sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1631200 - in /sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis: internal/metadata/OtherLocales.java metadata/iso/DefaultMetadata.java
Date Sun, 12 Oct 2014 16:14:32 GMT
Author: desruisseaux
Date: Sun Oct 12 16:14:32 2014
New Revision: 1631200

URL: http://svn.apache.org/r1631200
Log:
Factored out the handling of "defaultLocale+otherLocale" special property in a separated OtherLocales
class.
This is currently used only by DefaultMetadata, but we will need to leverage that OtherLocales
class in the
DefaultDataIdentification class too when we will implement ISO 19115:2014-3 XML marshalling.

Added:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java

Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java?rev=1631200&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
(added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
[UTF-8] Sun Oct 12 16:14:32 2014
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.metadata;
+
+import java.util.Locale;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.AbstractCollection;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.collection.Containers;
+
+
+/**
+ * Helper methods for handling the ISO 19115 {@code defaultLocale} and {@code otherLocale}
legacy properties.
+ * The ISO standard defines them as two separated properties while GeoAPI handles them in
a single collection
+ * for integration with JDK standard API like {@link Locale#lookup(List, Collection)}.
+ *
+ * <p>The first element of the {@code languages} collection is taken as the {@code
defaultLocale}, and all
+ * remaining ones are taken as {@code otherLocale} elements. Instances of this {@code OtherLocales}
class
+ * are for those remaining elements and are created by the {@link #filter(Collection)} method.</p>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public final class OtherLocales extends AbstractCollection<Locale> {
+    /**
+     * The default locale followed by all other locales.
+     */
+    private final Collection<Locale> languages;
+
+    /**
+     * Private constructor for {@link #filter(Collection)} only.
+     */
+    private OtherLocales(final Collection<Locale> languages) {
+        this.languages = languages;
+    }
+
+    /**
+     * Returns a collection for all elements except the first one from the given collection.
+     *
+     * <p><b>Null values and XML marshalling:</b>
+     * The {@code languages} argument may be {@code null} at XML marshalling time. In such
case, this method returns
+     * {@code null} instead than an empty set in order to instruct JAXB to not marshal the
{@code otherLocale} element
+     * (an empty set would cause JAXB to marshal an empty element). Since the {@code languages}
argument given to this
+     * method should never be null except at XML marshalling time, this rule should not be
a violation of public API.</p>
+     *
+     * <p>The converse of this {@code filter} method is {@link #merge(Locale, Collection)}.</p>
+     *
+     * @param  languages The collection containing the default locale followed by the other
ones.
+     * @return A collection containing all {@code languages} elements except the first one.
+     */
+    public static Collection<Locale> filter(final Collection<Locale> languages)
{
+        return (languages != null) ? new OtherLocales(languages) : null;
+    }
+
+    /**
+     * Returns the number of elements in this collection.
+     *
+     * @return Number of other locales.
+     */
+    @Override
+    public int size() {
+        int size = languages.size();
+        if (size != 0) size--;
+        return size;
+    }
+
+    /**
+     * Returns an iterator over all elements in this collection except the first one.
+     *
+     * @return Iterator over all other locales.
+     */
+    @Override
+    public Iterator<Locale> iterator() {
+        final Iterator<Locale> it = languages.iterator();
+        if (it.hasNext()) it.next(); // Skip the first element.
+        return it;
+    }
+
+    /**
+     * Adds a new element to the collection of "other locales". If we had no "default locale"
prior this method call,
+     * then this method will choose one before to add the given locale. This is needed since
the other locales begin
+     * only after the first element, so a first element needs to exist.
+     *
+     * <p>The above rule could be a risk of confusion for the users, since it could
cause the apparition of a default
+     * locale which has never been specified. However this risk exists only when invoking
the deprecated methods, or
+     * when unmarshalling a XML document having a {@code otherLocale} property without {@code
defaultLocale} property,
+     * which is probably invalid.</p>
+     *
+     * @param  locale The element to add.
+     * @return {@code true} if the "other locales" collection has been modified as a result
of this method call.
+     */
+    @Override
+    public boolean add(final Locale locale) {
+        ArgumentChecks.ensureNonNull("locale", locale);
+        if (languages.isEmpty()) {
+            Locale defaultLocale = Locale.getDefault();
+            if (defaultLocale.equals(locale)) {
+                defaultLocale = Locale.ROOT;  // Same default than merge(Locale, Collection).
+            }
+            languages.add(defaultLocale);
+        }
+        return languages.add(locale);
+    }
+
+    /**
+     * Returns a collection containing the given {@code defaultLocale} followed by the {@code
otherLocales}.
+     *
+     * @param  defaultLocale The first element in the collection to be returned, or {@code
null} if unspecified.
+     * @param  otherLocales  All remaining elements in the collection to be returned, or
{@code null} if none.
+     * @return A collection containing the default locale followed by all other ones.
+     */
+    public static Collection<Locale> merge(Locale defaultLocale, final Collection<?
extends Locale> otherLocales) {
+        final Collection<Locale> merged;
+        if (Containers.isNullOrEmpty(otherLocales)) {
+            merged = LegacyPropertyAdapter.asCollection(defaultLocale);
+        } else {
+            merged = new ArrayList<>(otherLocales.size() + 1);
+            if (defaultLocale == null) {
+                defaultLocale = Locale.getDefault();
+                if (otherLocales.contains(defaultLocale)) {
+                    defaultLocale = Locale.ROOT;  // Same default than add(Locale).
+                }
+            }
+            merged.add(defaultLocale);
+            merged.addAll(otherLocales);
+        }
+        return merged;
+    }
+
+    /**
+     * Returns the first element of the given collection, or {@code null} if none.
+     * This method does not emit warning if more than one element is found.
+     * Consequently, this method should be used only when multi-occurrence is not ambiguous.
+     *
+     * <p><b>Note:</b> while defined in {@code OtherLocales} because the
primary use for this method is to
+     * get the default locale, this method is also opportunistically used for other legacy
properties.</p>
+     *
+     * @param  <T>    The type of elements in the collection.
+     * @param  values The collection from which to get the first element, or {@code null}.
+     * @return The first element found in the given collection, or {@code null}.
+     */
+    public static <T> T getFirst(final Collection<T> values) {
+        if (values != null) {
+            final Iterator<T> it = values.iterator();
+            if (it.hasNext()) {
+                return it.next();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Sets the first element in the given collection to the given value.
+     * Special cases:
+     *
+     * <ul>
+     *   <li>If the given collection is null, a new collection will be returned.</li>
+     *   <li>If the given new value  is null, then the first element in the collection
is removed.</li>
+     *   <li>Otherwise if the given collection is empty, the given value will be added
to it.</li>
+     * </ul>
+     *
+     * <p><b>Note:</b> while defined in {@code OtherLocales} because the
primary use for this method is to
+     * get the default locale, this method is also opportunistically used for other legacy
properties.</p>
+     *
+     * @param  <T>      The type of elements in the collection.
+     * @param  values   The collection where to add the new value, or {@code null}.
+     * @param  newValue The new value to set, or {@code null} for instead removing the first
element.
+     * @return The collection (may or may not be the given {@code values} collection).
+     */
+    public static <T> Collection<T> setFirst(Collection<T> values, final
T newValue) {
+        if (values == null) {
+            return LegacyPropertyAdapter.asCollection(newValue);
+        }
+        if (newValue == null) {
+            final Iterator<T> it = values.iterator();
+            if (it.hasNext()) {
+                it.remove();
+            }
+        } else if (values.isEmpty()) {
+            values.add(newValue);
+        } else {
+            if (!(values instanceof List<?>)) {
+                values = new ArrayList<>(values);
+            }
+            ((List<T>) values).set(0, newValue);
+        }
+        return values;
+    }
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java?rev=1631200&r1=1631199&r2=1631200&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
[UTF-8] Sun Oct 12 16:14:32 2014
@@ -21,8 +21,6 @@ import java.util.Locale;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.AbstractCollection;
 import java.util.Iterator;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -56,7 +54,6 @@ import org.opengis.metadata.quality.Data
 import org.opengis.metadata.spatial.SpatialRepresentation;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.util.InternationalString;
-import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.citation.DefaultCitationDate;
@@ -64,6 +61,7 @@ import org.apache.sis.metadata.iso.citat
 import org.apache.sis.metadata.iso.identification.AbstractIdentification;
 import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
+import org.apache.sis.internal.metadata.OtherLocales;
 import org.apache.sis.internal.jaxb.code.PT_Locale;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.xml.Namespaces;
@@ -444,27 +442,12 @@ public class DefaultMetadata extends ISO
     @Deprecated
     @XmlElement(name = "language")
     public final Locale getLanguage() {
-        return first(languages);
+        return OtherLocales.getFirst(languages);
         // No warning if the collection contains more than one locale, because
         // this is allowed by the "getLanguage() + getLocales()" contract.
     }
 
     /**
-     * Returns the first element of the given collection, or {@code null} if none.
-     * This method does not emit warning if more than one element is found.
-     * Consequently, this method should be used only when multi-occurrence is not ambiguous.
-     */
-    private static <T> T first(final Collection<T> values) {
-        if (values != null) {
-            final Iterator<T> it = values.iterator();
-            if (it.hasNext()) {
-                return it.next();
-            }
-        }
-        return null;
-    }
-
-    /**
      * Sets the language used for documenting metadata.
      * This method modifies the collection returned by {@link #getLanguages()} as below:
      *
@@ -480,31 +463,7 @@ public class DefaultMetadata extends ISO
     @Deprecated
     public final void setLanguage(final Locale newValue) {
         checkWritePermission();
-        setLanguages(setFirst(languages, newValue));
-    }
-
-    /**
-     * Sets the first element in the given collection to the given value.
-     * If the given collection is empty, the given value will be added to it.
-     */
-    private static <T> Collection<T> setFirst(Collection<T> values, final
T newValue) {
-        if (values == null) {
-            return LegacyPropertyAdapter.asCollection(newValue);
-        }
-        if (newValue == null) {
-            final Iterator<T> it = values.iterator();
-            if (it.hasNext()) {
-                it.remove();
-            }
-        } else if (values.isEmpty()) {
-            values.add(newValue);
-        } else {
-            if (!(values instanceof List<?>)) {
-                values = new ArrayList<>(values);
-            }
-            ((List<T>) values).set(0, newValue);
-        }
-        return values;
+        setLanguages(OtherLocales.setFirst(languages, newValue));
     }
 
     /**
@@ -519,32 +478,7 @@ public class DefaultMetadata extends ISO
     @XmlElement(name = "locale")
     @XmlJavaTypeAdapter(PT_Locale.class)
     public final Collection<Locale> getLocales() {
-        final Collection<Locale> languages = getLanguages();
-        if (languages == null) { // May happen at XML marshalling time.
-            return Collections.emptySet();
-        }
-        return new AbstractCollection<Locale>() {
-            @Override
-            public int size() {
-                return Math.max(0, languages.size() - 1);
-            }
-
-            @Override
-            public Iterator<Locale> iterator() {
-                final Iterator<Locale> it = languages.iterator();
-                if (it.hasNext()) it.next(); // Skip the first element.
-                return it;
-            }
-
-            @Override
-            public boolean add(final Locale newValue) {
-                if (languages.isEmpty()) {
-                    languages.add(newValue);
-                    // Add twice, since the first entry is assigned to the "language" legacy
property.
-                }
-                return languages.add(newValue);
-            }
-        };
+        return OtherLocales.filter(getLanguages());
     }
 
     /**
@@ -557,20 +491,7 @@ public class DefaultMetadata extends ISO
     @Deprecated
     public final void setLocales(final Collection<? extends Locale> newValues) {
         checkWritePermission();
-        Locale language = getLanguage();
-        final Collection<Locale> merged;
-        if (Containers.isNullOrEmpty(newValues)) {
-            merged = LegacyPropertyAdapter.asCollection(language);
-        } else {
-            merged = new ArrayList<>(newValues.size() + 1);
-            if (language == null) {
-                language = newValues.iterator().next();
-                // Add twice, since the first entry is assigned to the "language" legacy
property.
-            }
-            merged.add(language);
-            merged.addAll(newValues);
-        }
-        setLanguages(merged);
+        setLanguages(OtherLocales.merge(getLanguage(), newValues));
     }
 
     /**
@@ -1215,7 +1136,7 @@ public class DefaultMetadata extends ISO
         final URI uri = new URI(newValue);
         checkWritePermission();
         Collection<Identification> identificationInfo = this.identificationInfo;
-        AbstractIdentification firstId = AbstractIdentification.castOrCopy(first(identificationInfo));
+        AbstractIdentification firstId = AbstractIdentification.castOrCopy(OtherLocales.getFirst(identificationInfo));
         if (firstId == null) {
             firstId = new DefaultDataIdentification();
         }
@@ -1224,15 +1145,15 @@ public class DefaultMetadata extends ISO
             citation = new DefaultCitation();
         }
         Collection<OnlineResource> onlineResources = citation.getOnlineResources();
-        DefaultOnlineResource firstOnline = DefaultOnlineResource.castOrCopy(first(onlineResources));
+        DefaultOnlineResource firstOnline = DefaultOnlineResource.castOrCopy(OtherLocales.getFirst(onlineResources));
         if (firstOnline == null) {
             firstOnline = new DefaultOnlineResource();
         }
         firstOnline.setLinkage(uri);
-        onlineResources = setFirst(onlineResources, firstOnline);
+        onlineResources = OtherLocales.setFirst(onlineResources, firstOnline);
         citation.setOnlineResources(onlineResources);
         firstId.setCitation(citation);
-        identificationInfo = setFirst(identificationInfo, firstId);
+        identificationInfo = OtherLocales.setFirst(identificationInfo, firstId);
         setIdentificationInfo(identificationInfo);
     }
 
@@ -1507,7 +1428,7 @@ public class DefaultMetadata extends ISO
      * This method sets the locale to be used for XML marshalling to the metadata language.
      */
     private void beforeMarshal(final Marshaller marshaller) {
-        Context.push(first(languages));
+        Context.push(OtherLocales.getFirst(languages));
     }
 
     /**



Mime
View raw message