Java tutorial
/* * This software is governed by the CeCILL-B license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/or redistribute the software under the terms of the CeCILL-B * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-B license and that you accept its terms. */ package fr.gouv.culture.thesaurus.service.rdf; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.commons.collections.map.MultiValueMap; import org.apache.commons.lang.LocaleUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import fr.gouv.culture.thesaurus.util.LangUtils; import fr.gouv.culture.thesaurus.util.xml.XmlDate; public class RdfResource { /** The class' logger. */ protected final static Logger log = Logger.getLogger(RdfResource.class); /** The entry identifier as a URI. */ protected final String uri; /** * Ensemble des proprits de l'entre ainsi que leurs valeurs. Les * proprits sont identifies par leur URI. */ private final Map<String, LocalizedStrings> properties = new HashMap<String, LocalizedStrings>(); /** * Ensemble des associations de l'entre vers d'autres ressources. * <code>MultiMap<String, String></code>, la cl reprsentant l'URI de * la proprit et les valeurs l'URI des ressources lies. */ private final MultiValueMap associations = new MultiValueMap(); /** * Creates a new RDF Resource. * * @param uri * the resource identifier as a URI. */ public RdfResource(String uri) { if ((uri == null) || (uri.length() == 0)) { throw new IllegalArgumentException("uri"); } this.uri = uri; } /** * Returns the entry identifier as a URI. * * @return the entry identifier. */ public String getUri() { return this.uri; } /** * Returns an entry property value. * * @param key * the property URI. * @param locale * the language tagging the property value or <code>null</code> * to get the value without any language tag. * @return the first value of the property tagged with the specified * language or <code>null</code> if none is present. */ public LocalizedString getProperty(String key) { Iterator<LocalizedString> values = this.internalGetProperties(key).iterator(); return (values.hasNext()) ? values.next() : null; } /** * Returns an entry property value. * * @param key * the property URI. * @param locale * the language tagging the property value or <code>null</code> * to get the value without any language tag. * @return the first value of the property tagged with the specified * language or <code>null</code> if none is present. */ public LocalizedString getProperty(String key, String locale) { Iterator<LocalizedString> values = this.internalGetProperties(key, locale).iterator(); return (values.hasNext()) ? values.next() : null; } /** * Renvoie la premire date de la ressource pour la proprit. * * @param key * URI de la proprit * @return Premire valeur de type {@link Date}, ou <code>null</code> si * aucune valeur n'existe pour la proprit, ou si les valeurs ne * sont pas des dates valides */ public Date getDateProperty(String key) { final LocalizedString property = getProperty(key); return property == null ? null : this.parseXmlDate(property.getValue()); } /** * Returns an entry property value in the specified locale, if possible. If * there is no value in the specified locale, considers the neutral * language. * * @param property * the property URI. * @param locale * the language tagging the property value or <code>null</code> * to get the value without any language tag. * @return the first value of the property tagged with the specified * language or <code>null</code> if none is present. */ public LocalizedString getPreferredProperty(String property, Locale preferredLocale) { @SuppressWarnings("unchecked") List<Locale> locales = LocaleUtils.localeLookupList(preferredLocale); for (Locale locale : locales) { String localeStr = LangUtils.localeString(locale); LocalizedString value = this.getProperty(property, localeStr); if (value != null) { return value; } } if (preferredLocale != null) { return this.getProperty(property, null); } return null; } /** * Returns the first value for the specified property (preferably in the * specified locale). If no value can be found for the locale, switches to * the neutral language. Then, if no value can be found, returns the entry * URI. This method is usually used to identify an entry. * * @param property * the property URI * @param preferredLocale * the preferred locale * @return the property's value for the entry. */ public LocalizedString getIdentifyingProperty(String property, Locale preferredLocale) { LocalizedString label = getPreferredProperty(property, preferredLocale); if (label == null) { label = new LocalizedString(getUri(), null); } return label; } /** * Returns all the values of the specified entry property. * * @param key * the property URI. * @param locale * the language tagging the property values or <code>null</code> * to get the values without any language tag. * @return the values of the property tagged with the specified language or * an empty list if none is present. */ public Collection<LocalizedString> getProperties(String key, String locale) { return Collections.unmodifiableCollection(internalGetProperties(key, locale)); } /** * Returns all the values of the specified entry property. * * @param key * the URI. * @return the values of the property tagged with the specified language or * an empty list if none is present. */ public Collection<LocalizedString> getProperties(String key) { return Collections.unmodifiableCollection(this.internalGetProperties(key)); } /** * Retourne toutes les valeurs de type {@link Date} de la ressource pour la * proprit spcifie. Toute valeur incorrecte est ignore. * * @param key * URI de la proprit * @return Les valeurs de type {@link Date} de la proprit (ne peut tre * <code>null</code>) */ public Collection<Date> getDateProperties(String key) { final Collection<LocalizedString> values = getProperties(key); final Collection<Date> dates = new ArrayList<Date>(values.size()); for (final LocalizedString value : values) { final Date parsedDate = parseXmlDate(value.getValue()); if (parsedDate != null) { dates.add(parsedDate); } } return Collections.unmodifiableCollection(dates); } /** * Adds a new value to the property identified by <code>key</code>. The * language will be neutral. * * @param key * the property URI. * @param value * a property value. * @see #addProperty(String,String,String) */ public void addProperty(String key, String value) { this.addProperty(key, value, null); } /** * Adds a new value to the property identified by <code>key</code> for the * specified language. * * @param key * the property URI. * @param value * a property value. * @param lang * the ISO language code (2 characters) for which the value is * defined. */ public void addProperty(String key, String value, String lang) { this.internalAddProperty(key, value, lang, false); } /** * Sets the value to the property identified by <code>key</code>, removing * previous property values, if any. The language will be neutral. * * @param key * the property URI. * @param value * a property value. * @see #setProperty(String,String,String) */ public void setProperty(String key, String value) { this.setProperty(key, value, null); } /** * Sets the value to the property identified by <code>key</code> for the * specified language, removing previous property values, if any. * * @param key * the property URI. * @param value * a property value. * @param lang * the ISO language code (2 characters) for which the value is * defined. */ public void setProperty(String key, String value, String lang) { this.internalAddProperty(key, value, lang, true); } /** * Renvoie l'ensemble des ressources lies l'entre pour la proprit * donne. * * @param property * URI de la proprit * @return Ensemble des URI des ressources lies l'entre via la proprit * (jamais <code>null</code> mais peut tre vide) */ @SuppressWarnings("unchecked") public Collection<String> getAssociations(final String property) { Collection<String> resources = associations.getCollection(property); if (resources == null) { resources = Collections.emptyList(); } else { resources = Collections.unmodifiableCollection(resources); } return resources; } /** * Ajoute une nouvelle association. * * @param property * URI de la proprit * @param resourceUri * URI de la ressource lier avec l'entre */ public void addAssociation(final String property, final String resourceUri) { associations.put(property, resourceUri); } /** {@inheritDoc} */ @Override public boolean equals(Object o) { return ((o instanceof Entry) && (this.uri.equals(((Entry) o).uri))); } /** {@inheritDoc} */ @Override public int hashCode() { return this.uri.hashCode(); } /** {@inheritDoc} */ @Override public String toString() { return this.uri + ' ' + properties; } /** * Interprte une valeur de type date (XML). * * @param xmlDate * Date en XML * @return Valeur de la date, ou <code>null</code> si la date n'est pas dans * un format valide */ private Date parseXmlDate(String xmlDate) { Date d; try { d = XmlDate.toDate(xmlDate); } catch (Exception e) { d = null; log.warn("Failed to parse XML date (\"" + xmlDate + "\") for entry \"" + this.getUri() + '"'); } return d; } /** * Ajoute une proprit l'entre du thsaurus. Si la valeur est * <code>null</code>, l'action est ignore. * * @param key * URI de la proprit * @param value * Valeur de la proprit * @param lang * Langue associe la valeur (<code>null</code> pour la langue * neutre) * @param reset * <code>true</code> pour supprimer les anciennes valeurs de la * proprit, <code>false</code> sinon */ private void internalAddProperty(String key, String value, String lang, boolean reset) { if (StringUtils.isEmpty(key)) { throw new IllegalArgumentException("key"); } LocalizedStrings propertyValues = properties.get(key); if (propertyValues == null) { propertyValues = new LocalizedStrings(); properties.put(key, propertyValues); } else if (reset) { propertyValues.clear(); } if (value != null) { propertyValues.add(value, lang); } } /** * Renvoie les valeurs de la proprit, quelle que soit la langue des * valeurs. L'ordre des valeurs est arbitraire. * * @param key * URI de la proprit * @return Ensemble des valeurs de la proprit dans toutes les langues * (jamais <code>null</code>) */ private Collection<LocalizedString> internalGetProperties(String key) { if (StringUtils.isEmpty(key)) { throw new IllegalArgumentException("key"); } final Collection<LocalizedString> localizedValues; final LocalizedStrings values = properties.get(key); if (values == null) { localizedValues = Collections.emptySet(); } else { localizedValues = values.getValues(); } return localizedValues; } /** * Renvoie les valeurs de la proprit dans la langue spcifie. La langue * fournie est strictement respecte : si aucune valeur n'a t trouve dans * la langue, la fonction renvoie une liste vide. Si la langue spcifie est * <code>null</code>, seules les valeurs dans la langue neutre sont * renvoyes. * * @param key * URI de la proprit * @param locale * Langue des valeurs rcuprer (ou <code>null</code> pour * prendre uniquement les valeurs neutres) * @return Ensemble des valeurs de la proprit dans la langue spcifie * (jamais <code>null</code>) */ private Collection<LocalizedString> internalGetProperties(String key, String locale) { if (StringUtils.isEmpty(key)) { throw new IllegalArgumentException("key"); } final Collection<LocalizedString> localizedValues; final LocalizedStrings values = properties.get(key); if (values == null) { localizedValues = Collections.emptySet(); } else { localizedValues = values.getValues(locale); } return localizedValues; } }