sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1480602 [12/15] - in /sis/branches/Android: ./ ide-project/ ide-project/NetBeans/ ide-project/NetBeans/nbproject/ ide-project/eclipse/ sis-app/src/main/java/org/apache/sis/cli/ sis-build-helper/ sis-build-helper/src/main/java/org/apache/si...
Date Thu, 09 May 2013 12:24:20 GMT
Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Thu May  9 12:24:13 2013
@@ -14,13 +14,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+CanNotAddToExclusiveSet_2       = Aucun \u00e9l\u00e9ment ne peut \u00eatre ajout\u00e9 \u00e0 cet ensemble car les propri\u00e9t\u00e9s \u2018{0}\u2019 et \u2018{1}\u2019 sont mutuellement exclusives.
+CanNotConvertFromType_2         = Ne peut pas convertir du type \u2018{0}\u2019 vers le type \u2018{1}\u2019.
+CanNotConvertValue_2            = La valeur \u201c{0}\u201d ne peut pas \u00eatre convertie vers le type \u2018{1}\u2019.
 CanNotComputeDerivative         = La d\u00e9riv\u00e9 ne peut pas \u00eatre calcul\u00e9e.
+CanNotInstantiate_1             = Ne peut pas cr\u00e9er un objet de type \u2018{0}\u2019.
+CanNotSetPropertyValue_1        = Ne peut pas d\u00e9finir une valeur pour la propri\u00e9t\u00e9 \u201c{0}\u201d.
+ClassNotFinal_1                 = La classe \u2018{0}\u2019 n\u2019est pas finale.
 CloneNotSupported_1             = Un objet de type \u2018{0}\u2019 ne peut pas \u00eatre clon\u00e9.
 DeadThread_1                    = La t\u00e2che \u201c{0}\u201d est morte.
 DuplicatedValue_1               = La valeur \u201c{0}\u201d est dupliqu\u00e9e.
+DuplicatedValuesForProperty_1   = Plusieurs valeurs ont \u00e9t\u00e9 sp\u00e9cifi\u00e9es pour la propri\u00e9t\u00e9 \u201c{0}\u201d.
+DuplicatedValuesCount_1         = {0} valeurs dupliqu\u00e9es ont \u00e9t\u00e9 trouv\u00e9es.
 ElementAlreadyPresent_1         = L\u2019\u00e9lement \u201c{0}\u201d est d\u00e9j\u00e0 pr\u00e9sent.
 EmptyArgument_1                 = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre vide.
 EmptyDictionary                 = Le dictionnaire doit contenir au moins une entr\u00e9e.
+EmptyEnvelope2D                 = L\u2019enveloppe doit avoir au moins deux dimensions et ne pas \u00eatre vide.
 EmptyProperty_1                 = La propri\u00e9t\u00e9 nomm\u00e9e \u201c{0}\u201d ne doit pas \u00eatre vide.
 ExcessiveArgumentSize_3         = L\u2019argument \u2018{0}\u2019 ne peut pas contenir plus de {1} \u00e9l\u00e9ments. Un nombre de {2} est excessif.
 ForbiddenAttribute_2            = L\u2019attribut \u201c{0}\u201d n\u2019est pas autoris\u00e9 pour un objet de type \u2018{1}\u2019.
@@ -35,6 +44,8 @@ IllegalLanguageCode_1           = Le cod
 IllegalOrdinateRange_3          = La plage de valeurs de coordonn\u00e9es [{1} \u2026 {2}] n\u2019est pas valide pour l\u2019axe \u201c{0}\u201d.
 IllegalPropertyClass_2          = La propri\u00e9t\u00e9 \u2018{0}\u2019 ne peut pas \u00eatre associ\u00e9e \u00e0 une valeur de type \u2018{1}\u2019.
 IllegalRange_2                  = La plage [{0} \u2026 {1}] n\u2019est pas valide.
+IncompatiblePropertyValue_1     = La valeur de la propri\u00e9t\u00e9 \u201c{0}\u201d n\u2019est pas compatible.
+IncompatibleUnits_2             = Les unit\u00e9s \u201c{0}\u201d et \u201c{1}\u201d ne sont pas compatibles.
 InconsistentAttribute_2         = La valeur \u201c{1}\u201d de l\u2019attribut \u2018{0}\u2019 n\u2019est pas coh\u00e9rente avec celles des autres attributs.
 InconsistentTableColumns        = Les colonnes des tables ne sont pas coh\u00e9rentes.
 IdentifierAlreadyBound_1        = L\u2019identifiant \u201c{0}\u201d est d\u00e9j\u00e0 associ\u00e9 \u00e0 un autre objet.
@@ -47,25 +58,41 @@ MandatoryAttribute_2            = L\u201
 MismatchedCRS                   = Le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es doit \u00eatre le m\u00eame pour tous les objets.
 MismatchedDimension_2           = Les dimensions des objets ({0}D et {1}D) ne concordent pas.
 MismatchedDimension_3           = L\u2019argument \u2018{0}\u2019 a {2} dimension{2,choice,1#|2#s}, alors qu\u2019on en attendait {1}.
+MissingRequiredModule_1         = Cette op\u00e9ration requiert le module \u201c{0}\u201d.
+MissingValueForProperty_1       = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour la propri\u00e9t\u00e9 \u201c{0}\u201d.
+MissingValueInColumn_1          = Il manque une valeur dans la colonne \u201c{0}\u201d.
 NegativeArgument_2              = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre n\u00e9gatif. La valeur donn\u00e9e \u00e9tait {1}.
 NodeChildOfItself_1             = Le n\u0153ud \u201c{0}\u201d ne peut pas \u00eatre un enfant de lui-m\u00eame.
 NodeHasAnotherParent_1          = Le n\u0153ud \u201c{0}\u201d a d\u00e9j\u00e0 un autre parent.
 NodeHasNoParent_1               = Le n\u0153ud \u201c{0}\u201d n\u2019a pas de parent.
+NodeIsLeaf_1                    = Le n\u0153ud \u201c{0}\u201d est une feuille.
 NodeNotFound_1                  = Aucun n\u0153ud \u201c{0}\u201d n\u2019a \u00e9t\u00e9 trouv\u00e9.
 NonEquilibratedParenthesis_2    = Il manque une parenth\u00e8se \u2018{1}\u2019 dans \u201c{0}\u201d.
+NonInvertibleConversion         = La conversion n\u2019est pas inversible.
+NonInvertibleTransform          = La transformation n\u2019est pas inversible.
 NonAngularUnit_1                = \u201c{0}\u201d n\u2019est pas une unit\u00e9 d\u2019angles.
 NonLinearUnit_1                 = \u201c{0}\u201d n\u2019est pas une unit\u00e9 de longueurs.
 NonScaleUnit_1                  = \u201c{0}\u201d n\u2019est pas une unit\u00e9 d\u2019\u00e9chelles.
 NonTemporalUnit_1               = \u201c{0}\u201d n\u2019est pas une unit\u00e9 de temps.
 NotANumber_1                    = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre NaN (Not-a-Number).
 NotAPrimitiveWrapper_1          = La classe \u2018{0}\u2019 n\u2019est pas un adaptateur d\u2019un type primitif.
+NotComparableClass_1            = La classe \u2018{0}\u2019 n\u2019est pas comparable.
+NoSuchProperty_2                = Aucune propri\u00e9t\u00e9 nomm\u00e9e \u201c{0}\u201d n\u2019a \u00e9t\u00e9 trouv\u00e9e dans \u201c{1}\u201d.
+NoUnit                          = Aucune unit\u00e9 de mesure n\u2019a \u00e9t\u00e9 sp\u00e9cifi\u00e9e.
 NullArgument_1                  = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre nul.
+NullMapKey                      = La cl\u00e9 nulle n\u2019est pas autoris\u00e9e dans ce dictionnaire.
+NullMapValue                    = Les valeurs nulles ne sont pas autoris\u00e9es dans ce dictionnaire.
 OddArrayLength_1                = La longueur du tableau est {0}, alors qu\u2019on attendait une longueur paire.
 RecursiveCreateCallForKey_1     = Appel r\u00e9cursif lors de la cr\u00e9ation d\u2019un objet pour la cl\u00e9 \u201c{0}\u201d.
 RequireDecimalSeparator         = Un s\u00e9parateur d\u00e9cimal est requis.
+StalledThread_1                 = La t\u00e2che \u201c{0}\u201d semble bloqu\u00e9e.
+UndefinedOrderingForElements_2  = L\u2019ordre entre les \u00e9l\u00e9ments \u201c{0}\u201d et \u201c{1}\u201d n\u2019est pas d\u00e9fini.
 UnexpectedChange_1              = Changement inattendu dans \u2018{0}\u2019.
 UnexpectedEndOfString_1         = D\u2019autres caract\u00e8res \u00e9taient attendus \u00e0 la fin du texte \u201c{0}\u201d.
+UnknownType_1                   = Le type \u2018{0}\u2019 n\u2019est pas reconnu dans ce contexte.
+UnknownTypeForProperty_1        = Le type de la propri\u00e9t\u00e9 \u201c{0}\u201d est inconnu.
 UnmodifiableAffineTransform     = Cette transformation affine n\u2019est pas modifiable.
+UnmodifiableCellValue_2         = La cellule \u00e0 la colonne \u201c{1}\u201d de la ligne \u201c{0}\u201d n\u2019est pas modifiable.
 UnmodifiableGeometry            = Cette g\u00e9om\u00e9trie n\u2019est pas modifiable.
 UnmodifiableMetadata            = Cette m\u00e9ta-donn\u00e9e n\u2019est pas modifiable.
 UnmodifiableObject_1            = L\u2019objet \u2018{0}\u2019 n\u2019est pas modifiable.
@@ -74,6 +101,7 @@ UnparsableStringForClass_2      = Le tex
 UnparsableStringForClass_3      = Le texte \u201c{1}\u201d n\u2019est pas reconnu comme un objet de type \u2018{0}\u2019, \u00e0 cause des caract\u00e8res \u201c{2}\u201d.
 UnsupportedImplementation_1     = Les instances de \u2018{0}\u2019 ne peuvent pas \u00eatre g\u00e9r\u00e9es parce que les impl\u00e9mentations arbitraires ne sont pas encore support\u00e9es.
 UnsupportedOperation_1          = L\u2019op\u00e9ration \u2018{0}\u2019 n\u2019est pas support\u00e9e.
+UnsupportedType_1               = Le type \u2018{0}\u2019 n\u2019est pas support\u00e9.
 ValueAlreadyDefined_1           = Une valeur est d\u00e9j\u00e0 d\u00e9finie pour \u201c{0}\u201d.
 ValueNotGreaterThanZero_2       = La valeur \u2018{0}\u2019={1} n\u2019est pas valide. On attendait un nombre positif non-nul.
 ValueOutOfRange_4               = La valeur \u2018{0}\u2019={3} est invalide. Une valeur dans la plage [{1} \u2026 {2}] \u00e9tait attendue.

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=ISO-8859-1

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java [UTF-8] Thu May  9 12:24:13 2013
@@ -16,11 +16,10 @@
  */
 package org.apache.sis.util.resources;
 
+import java.net.URL;
 import java.io.BufferedInputStream;
 import java.io.DataInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStream;
 import java.text.MessageFormat;
 import java.util.Enumeration;
 import java.util.Locale;
@@ -35,12 +34,13 @@ import org.opengis.util.InternationalStr
 
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.Classes;
+import org.apache.sis.util.Localized;
 import org.apache.sis.util.Exceptions;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
 
 // Related to JDK7
-import org.apache.sis.internal.util.JDK7;
+import org.apache.sis.internal.jdk7.JDK7;
 
 
 /**
@@ -60,7 +60,7 @@ import org.apache.sis.internal.util.JDK7
  * @module
  */
 @ThreadSafe
-public class IndexedResourceBundle extends ResourceBundle {
+public class IndexedResourceBundle extends ResourceBundle implements Localized {
     /**
      * Maximum string length for text inserted into another text. This parameter is used by
      * {@link #summarize}. Resource strings are never cut to this length. However, text replacing
@@ -69,33 +69,23 @@ public class IndexedResourceBundle exten
     private static final int MAX_STRING_LENGTH = 200;
 
     /**
-     * The resource name of the binary file containing resources. It may be a file name or an
-     * entry in a JAR file. The path must be relative to the package containing the subclass
-     * of {@code IndexedResourceBundle}.
+     * The path of the binary file containing resources, or {@code null} if there is no resources
+     * of if the resources have already been loaded. The resources may be a file or an entry in a
+     * JAR file.
      */
-    private final String filename;
+    private URL resources;
 
     /**
      * The array of resources. Keys are an array index. For example, the value for key "14" is
      * {@code values[14]}. This array will be loaded only when first needed. We should not load
      * it at construction time, because some {@code ResourceBundle} objects will never ask for
-     * values. This is particularly the case for ancestor classes of {@code Resources_fr_CA},
+     * values. This is particularly the case for parent resources of {@code Resources_fr_CA},
      * {@code Resources_en}, {@code Resources_de}, etc., which will only be used if a key has
-     * not been found in the subclass.
+     * not been found in the child resources.
      *
      * @see #ensureLoaded(String)
      */
-    private String[] values;
-
-    /**
-     * The locale for formatting objects like number, date, etc. There are two possible Locales
-     * we could use: default locale or resource bundle locale. If the default locale uses the same
-     * language as this ResourceBundle's locale, then we will use the default locale. This allows
-     * dates and numbers to be formatted according to user conventions (e.g. French Canada) even
-     * if the ResourceBundle locale is different (e.g. standard French). However, if languages
-     * don't match, then we will use ResourceBundle locale for better coherence.
-     */
-    private transient Locale formatLocale;
+    private volatile String[] values;
 
     /**
      * The object to use for formatting messages. This object
@@ -113,11 +103,11 @@ public class IndexedResourceBundle exten
     /**
      * Constructs a new resource bundle loading data from the given UTF file.
      *
-     * @param filename The file or the JAR entry containing resources. The path must be relative
-     *        to the package of the {@code IndexedResourceBundle} subclass being constructed.
+     * @param resources The path of the binary file containing resources, or {@code null} if
+     *        there is no resources. The resources may be a file or an entry in a JAR file.
      */
-    protected IndexedResourceBundle(final String filename) {
-        this.filename = filename;
+    protected IndexedResourceBundle(final URL resources) {
+        this.resources = resources;
     }
 
     /**
@@ -143,24 +133,6 @@ public class IndexedResourceBundle exten
     }
 
     /**
-     * Returns the locale to use for formatters. It is often the same than {@link #getLocale()},
-     * except if the later has the same language than the default locale, in which case this
-     * method returns the default locale. For example if this {@code IndexResourceBundle} is
-     * for the French locale but the user is French Canadian, we will format the dates using
-     * Canada French conventions rather than France conventions.
-     */
-    private Locale getFormatLocale() {
-        if (formatLocale == null) {
-            formatLocale = Locale.getDefault();
-            final Locale rl = getLocale(); // Sometime null with IBM's JDK.
-            if (rl != null && !formatLocale.getLanguage().equalsIgnoreCase(rl.getLanguage())) {
-                formatLocale = rl;
-            }
-        }
-        return formatLocale;
-    }
-
-    /**
      * Returns a handler for the constants declared in the inner {@code Keys} class.
      * Subclasses defined in the {@code org.apache.sis.util.resources} package
      * override this method for efficiency. However the default implementation
@@ -271,78 +243,75 @@ public class IndexedResourceBundle exten
      * @throws MissingResourceException if this method failed to load resources.
      */
     private String[] ensureLoaded(final String key) throws MissingResourceException {
-        final String methodName = (key != null) ? "getObject" : "getKeys";
-        LogRecord record = null;
-        try {
-            String[] values;
-            synchronized (this) {
-                values = this.values;
-                if (values != null) {
-                    return values;
-                }
+        String[] values = this.values;
+        if (values == null) synchronized (this) {
+            values = this.values;
+            if (values == null) {
                 /*
-                 * Prepares a log record.  We will wait for successful loading before
-                 * posting this record.  If loading fails, the record will be changed
-                 * into an error record. Note that the message must be logged outside
-                 * the synchronized block, otherwise there is dead locks!
+                 * If there is no explicit resources for this instance, inherit the resources
+                 * from the parent. Note that this IndexedResourceBundle instance may still
+                 * differ from its parent in the way date and numbers are formatted.
                  */
-                record = new LogRecord(Level.FINER, "Loaded resources for {0} from bundle \"{1}\".");
-                /*
-                 * Loads resources from the UTF file.
-                 */
-                InputStream in;
-                String name = filename;
-                while ((in = getClass().getResourceAsStream(name)) == null) { // NOSONAR
-                    final int ext  = name.lastIndexOf('.');
-                    final int lang = name.lastIndexOf('_', ext-1);
-                    if (lang <= 0) {
-                        throw new FileNotFoundException(filename);
-                    }
-                    final int length = name.length();
-                    name = new StringBuilder(lang + (length-ext))
-                            .append(name, 0, lang).append(name, ext, length).toString();
-                }
-                final DataInputStream input = new DataInputStream(new BufferedInputStream(in));
-                try {
-                    this.values = values = new String[input.readInt()];
-                    for (int i=0; i<values.length; i++) {
-                        values[i] = input.readUTF();
-                        if (values[i].isEmpty()) {
-                            values[i] = null;
+                if (resources == null) {
+                    // If we get a NullPointerException or ClassCastException here,
+                    // it would be a bug in the way we create the chain of parents.
+                    values = ((IndexedResourceBundle) parent).ensureLoaded(key);
+                } else {
+                    /*
+                     * Prepares a log record.  We will wait for successful loading before
+                     * posting this record.  If loading fails, the record will be changed
+                     * into an error record. Note that the message must be logged outside
+                     * the synchronized block, otherwise there is dead locks!
+                     */
+                    final Locale    locale     = getLocale(); // Sometime null with IBM's JDK.
+                    final String    baseName   = getClass().getCanonicalName();
+                    final String    methodName = (key != null) ? "getObject" : "getKeys";
+                    final LogRecord record     = new LogRecord(Level.FINER, "Loaded resources for {0} from bundle \"{1}\".");
+                    /*
+                     * Loads resources from the UTF file.
+                     */
+                    try {
+                        DataInputStream input = new DataInputStream(new BufferedInputStream(resources.openStream()));
+                        values = new String[input.readInt()];
+                        for (int i=0; i<values.length; i++) {
+                            values[i] = input.readUTF();
+                            if (values[i].isEmpty()) {
+                                values[i] = null;
+                            }
                         }
+                        input.close();
+                    } catch (IOException exception) {
+                        record.setLevel  (Level.WARNING);
+                        record.setMessage(exception.getMessage()); // For administrator, use system locale.
+                        record.setThrown (exception);
+                        Logging.log(IndexedResourceBundle.class, methodName, record);
+                        final MissingResourceException error = new MissingResourceException(
+                                Exceptions.getLocalizedMessage(exception, locale), // For users, use requested locale.
+                                baseName, key);
+                        error.initCause(exception);
+                        throw error;
                     }
-                } finally {
-                    input.close();
-                }
-                /*
-                 * Now, logs the message. This message is not localized.  Note that
-                 * Locale.getDisplayName() may return different string on different
-                 * Java implementation, but it doesn't matter here since we use the
-                 * result only for logging purpose.
-                 */
-                String language = null;
-                final Locale rl = getLocale(); // Sometime null with IBM's JDK.
-                if (rl != null) {
-                    language = rl.getDisplayName(Locale.US);
-                }
-                if (language == null || language.isEmpty()) {
-                    language = "<default>";
+                    /*
+                     * Now, logs the message. This message is provided only in English.
+                     * Note that Locale.getDisplayName() may return different string on
+                     * different Java implementation, but it doesn't matter here since
+                     * we use the result only for logging purpose.
+                     */
+                    String language = null;
+                    if (locale != null) {
+                        language = locale.getDisplayName(Locale.US);
+                    }
+                    if (language == null || language.isEmpty()) {
+                        language = "<root>";
+                    }
+                    record.setParameters(new String[] {language, baseName});
+                    Logging.log(IndexedResourceBundle.class, methodName, record);
+                    resources = null; // Not needed anymore, let GC do its job.
                 }
-                record.setParameters(new String[] {language, getClass().getCanonicalName()});
+                this.values = values;
             }
-            Logging.log(IndexedResourceBundle.class, methodName, record);
-            return values;
-        } catch (IOException exception) {
-            record.setLevel  (Level.WARNING);
-            record.setMessage(exception.getMessage()); // For administrator, use system locale.
-            record.setThrown (exception);
-            Logging.log(IndexedResourceBundle.class, methodName, record);
-            final MissingResourceException error = new MissingResourceException(
-                    Exceptions.getLocalizedMessage(exception, getLocale()), // For users, use requested locale.
-                    getClass().getCanonicalName(), key);
-            error.initCause(exception);
-            throw error;
         }
+        return values;
     }
 
     /**
@@ -404,11 +373,11 @@ public class IndexedResourceBundle exten
             if (element instanceof CharSequence) {
                 CharSequence text = (CharSequence) element;
                 if (text instanceof InternationalString) {
-                    text = ((InternationalString) element).toString(getFormatLocale());
+                    text = ((InternationalString) element).toString(getLocale());
                 }
                 replacement = CharSequences.shortSentence(text, MAX_STRING_LENGTH);
             } else if (element instanceof Throwable) {
-                String message = Exceptions.getLocalizedMessage((Throwable) element, getFormatLocale());
+                String message = Exceptions.getLocalizedMessage((Throwable) element, getLocale());
                 if (message == null) {
                     message = Classes.getShortClassName(element);
                 }
@@ -429,7 +398,7 @@ public class IndexedResourceBundle exten
     }
 
     /**
-     * Gets a string for the given key and appends "…" to it.
+     * Gets a string for the given key and appends "…" to it.
      * This method is typically used for creating menu items.
      *
      * @param  key The key for the desired string.
@@ -437,7 +406,7 @@ public class IndexedResourceBundle exten
      * @throws MissingResourceException If no object for the given key can be found.
      */
     public final String getMenuLabel(final int key) throws MissingResourceException {
-        return getString(key) + '…';
+        return getString(key) + '…';
     }
 
     /**
@@ -496,7 +465,7 @@ public class IndexedResourceBundle exten
                 /*
                  * Constructs a new MessageFormat for formatting the arguments.
                  */
-                format = new MessageFormat(pattern, getFormatLocale());
+                format = new MessageFormat(pattern, getLocale());
                 lastKey = key;
             } else if (key != lastKey) {
                 /*

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java [UTF-8] Thu May  9 12:24:13 2013
@@ -19,10 +19,9 @@ package org.apache.sis.util.resources;
 import java.util.Arrays;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.CharSequences;
 
-import static org.apache.sis.util.Arrays.resize;
-
 
 /**
  * Base class of {@code Keys} inner classes declaring key constants.
@@ -92,7 +91,7 @@ class KeyConstants {
             } catch (Exception e) { // (ReflectiveOperationException) on JDK7
                 names = CharSequences.EMPTY_ARRAY;
             }
-            keys = resize(names, length);
+            keys = ArraysExt.resize(names, length);
         }
         return keys;
     }

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/KeyConstants.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java [UTF-8] Thu May  9 12:24:13 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.util.resources;
 
+import java.net.URL;
 import java.util.List;
 import java.util.Locale;
 import java.util.Collections;
@@ -105,25 +106,16 @@ final class Loader extends ResourceBundl
          * bundle only if the file is found.
          */
         final String classname = classe.getSimpleName();
-        String filename = toResourceName(toBundleName(classname, locale), EXTENSION);
-        if (classe.getResource(filename) == null) {
-            if (!Locale.ENGLISH.equals(locale)) {
-                return null;
-            }
-            // We have no explicit resources for English. We use the default one for that.
-            filename = toResourceName(classname, EXTENSION);
-            if (classe.getResource(filename) == null) {
-                return null;
-            }
-        }
+        final URL resources = classe.getResource(toResourceName(toBundleName(classname, locale), EXTENSION));
         /*
-         * If the file exists, instantiate now the resource bundle. Note that the constructor
-         * will not loads the data immediately, which is why we don't pass it the above URL.
+         * Instantiate now the resource bundle. The resources URL may be null, in which case the
+         * bundle will inherit the strings from the parent bundle. In every cases, the strings
+         * will be loaded only when first needed.
          *
          * Note: Do not call Constructor.setAccessible(true) - this is not allowed in Applet.
          */
         try {
-            return (ResourceBundle) classe.getDeclaredConstructor(String.class).newInstance(filename);
+            return (ResourceBundle) classe.getDeclaredConstructor(URL.class).newInstance(resources);
         } catch (Exception e) { // The JDK7 branch uses multi-catches here.
             InstantiationException exception = new InstantiationException(Exceptions.getLocalizedMessage(e, locale));
             exception.initCause(e);

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Loader.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] Thu May  9 12:24:13 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.util.resources;
 
+import java.net.URL;
 import java.util.Locale;
 import java.util.MissingResourceException;
 import org.opengis.util.InternationalString;
@@ -59,6 +60,22 @@ public final class Messages extends Inde
         public static final int ChangedContainerCapacity_2 = 0;
 
         /**
+         * Property “{0}” has been discarded in favor of “{1}”, because those two properties are
+         * mutually exclusive.
+         */
+        public static final int DiscardedExclusiveProperty_2 = 4;
+
+        /**
+         * Text were discarded for some locales.
+         */
+        public static final int LocalesDiscarded = 2;
+
+        /**
+         * Property “{0}” is hidden by “{1}”.
+         */
+        public static final int PropertyHiddenBy_2 = 3;
+
+        /**
          * Unavailable content.
          */
         public static final int UnavailableContent = 1;
@@ -67,10 +84,11 @@ public final class Messages extends Inde
     /**
      * Constructs a new resource bundle loading data from the given UTF file.
      *
-     * @param filename The file or the JAR entry containing resources.
+     * @param resources The path of the binary file containing resources, or {@code null} if
+     *        there is no resources. The resources may be a file or an entry in a JAR file.
      */
-    Messages(final String filename) {
-        super(filename);
+    Messages(final URL resources) {
+        super(resources);
     }
 
     /**
@@ -179,7 +197,7 @@ public final class Messages extends Inde
      * The international string to be returned by {@link formatInternational}.
      */
     private static final class International extends ResourceInternationalString {
-        private static final long serialVersionUID = -229348959712294903L;
+        private static final long serialVersionUID = 4553487496835099424L;
 
         International(int key)                   {super(key);}
         International(int key, Object args)      {super(key, args);}

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] Thu May  9 12:24:13 2013
@@ -15,4 +15,7 @@
 # limitations under the License.
 #
 ChangedContainerCapacity_2      = Changed the container capacity from {0} to {1} elements.
+DiscardedExclusiveProperty_2    = Property \u201c{0}\u201d has been discarded in favor of \u201c{1}\u201d, because those two properties are mutually exclusive.
+PropertyHiddenBy_2              = Property \u201c{0}\u201d is hidden by \u201c{1}\u201d.
+LocalesDiscarded                = Text were discarded for some locales.
 UnavailableContent              = Unavailable content.

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=ISO-8859-1

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] Thu May  9 12:24:13 2013
@@ -15,4 +15,7 @@
 # limitations under the License.
 #
 ChangedContainerCapacity_2      = Changement de la capacit\u00e9 du conteneur de {0} vers {1} \u00e9l\u00e9ments.
+DiscardedExclusiveProperty_2    = La propri\u00e9t\u00e9 \u201c{0}\u201d a \u00e9t\u00e9 \u00e9cart\u00e9e en faveur de \u201c{1}\u201d, parce que ces deux propri\u00e9t\u00e9s sont mutuellement exclusives.
+PropertyHiddenBy_2              = La propri\u00e9t\u00e9 \u201c{0}\u201d est masqu\u00e9e par \u201c{1}\u201d.
+LocalesDiscarded                = Des textes ont \u00e9t\u00e9 ignor\u00e9s pour certaines langues.
 UnavailableContent              = Contenu non-disponible.

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=ISO-8859-1

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java [UTF-8] Thu May  9 12:24:13 2013
@@ -29,7 +29,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.iso.AbstractInternationalString;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**
@@ -47,7 +47,7 @@ abstract class ResourceInternationalStri
     /**
      * Serial number for inter-operability with different versions.
      */
-    private static final long serialVersionUID = 4744571031462678126L;
+    private static final long serialVersionUID = -3910920973710535738L;
 
     /**
      * The key for the resource to fetch. A negative value means that the resource takes no
@@ -106,23 +106,15 @@ abstract class ResourceInternationalStri
     /**
      * Returns a string in the specified locale.
      *
-     * @param  locale The locale to look for, or {@code null} for an unlocalized version.
-     * @return The string in the specified locale, or in a default locale.
+     * @param  locale The desired locale for the string to be returned.
+     * @return The string in the specified locale, or in a fallback locale.
      * @throws MissingResourceException is the key given to the constructor is invalid.
      */
     @Override
-    public String toString(Locale locale) throws MissingResourceException {
-        if (locale == null) {
-            // The English locale (NOT the system default) is often used
-            // as the real identifier in OGC IdentifiedObject naming. If
-            // a user wants a string in the system default locale, he
-            // should invokes the 'toString()' method instead.
-            locale = Locale.ENGLISH;
-        }
+    public String toString(final Locale locale) throws MissingResourceException {
         final IndexedResourceBundle resources = getBundle(locale);
-        return (key < 0)
-                ? resources.getString(~key)
-                : resources.getString(key, arguments);
+        return (key < 0) ? resources.getString(~key)
+                         : resources.getString(key, arguments);
     }
 
     /**

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/ResourceInternationalString.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Thu May  9 12:24:13 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.util.resources;
 
+import java.net.URL;
 import java.util.Locale;
 import java.util.MissingResourceException;
 import org.opengis.util.InternationalString;
@@ -104,11 +105,26 @@ public final class Vocabulary extends In
         public static final int DaylightTime = 24;
 
         /**
+         * Destination
+         */
+        public static final int Destination = 38;
+
+        /**
          * Directory
          */
         public static final int Directory = 36;
 
         /**
+         * Identifier
+         */
+        public static final int Identifier = 42;
+
+        /**
+         * Index
+         */
+        public static final int Index = 44;
+
+        /**
          * Java extensions
          */
         public static final int JavaExtensions = 26;
@@ -119,6 +135,11 @@ public final class Vocabulary extends In
         public static final int JavaHome = 30;
 
         /**
+         * Latitude
+         */
+        public static final int Latitude = 40;
+
+        /**
          * Libraries
          */
         public static final int Libraries = 35;
@@ -139,6 +160,11 @@ public final class Vocabulary extends In
         public static final int Localization = 19;
 
         /**
+         * Longitude
+         */
+        public static final int Longitude = 41;
+
+        /**
          * Maximum value
          */
         public static final int MaximumValue = 5;
@@ -159,7 +185,7 @@ public final class Vocabulary extends In
         public static final int Name = 0;
 
         /**
-         * Number of ‘NaN’
+         * Number of ‘NaN’
          */
         public static final int NumberOfNaN = 3;
 
@@ -169,6 +195,11 @@ public final class Vocabulary extends In
         public static final int NumberOfValues = 2;
 
         /**
+         * {0} ({1} of {2})
+         */
+        public static final int Of_3 = 43;
+
+        /**
          * Offset
          */
         public static final int Offset = 22;
@@ -204,6 +235,11 @@ public final class Vocabulary extends In
         public static final int Scale = 23;
 
         /**
+         * Source
+         */
+        public static final int Source = 39;
+
+        /**
          * Standard deviation
          */
         public static final int StandardDeviation = 8;
@@ -247,10 +283,11 @@ public final class Vocabulary extends In
     /**
      * Constructs a new resource bundle loading data from the given UTF file.
      *
-     * @param filename The file or the JAR entry containing resources.
+     * @param resources The path of the binary file containing resources, or {@code null} if
+     *        there is no resources. The resources may be a file or an entry in a JAR file.
      */
-    Vocabulary(final String filename) {
-        super(filename);
+    Vocabulary(final URL resources) {
+        super(resources);
     }
 
     /**
@@ -287,7 +324,7 @@ public final class Vocabulary extends In
      * The international string to be returned by {@link formatInternational}.
      */
     private static final class International extends ResourceInternationalString {
-        private static final long serialVersionUID = 8360132666298806838L;
+        private static final long serialVersionUID = -5423999784169092823L;
 
         International(int key)                   {super(key);}
         International(int key, Object args)      {super(key, args);}
@@ -308,4 +345,34 @@ public final class Vocabulary extends In
     public static InternationalString formatInternational(final int key) {
         return new International(key);
     }
+
+    /**
+     * Gets an international string for the given key. This method does not check for the key
+     * validity. If the key is invalid, then a {@link MissingResourceException} may be thrown
+     * when a {@link InternationalString#toString(Locale)} method is invoked.
+     *
+     * {@note This method is redundant with the one expecting <code>Object...</code>, but avoid
+     *        the creation of a temporary array. There is no risk of confusion since the two
+     *        methods delegate their work to the same <code>format</code> method anyway.}
+     *
+     * @param  key The key for the desired string.
+     * @param  arg Values to substitute to "{0}".
+     * @return An international string for the given key.
+     */
+    public static InternationalString formatInternational(final int key, final Object arg) {
+        return new International(key, arg);
+    }
+
+    /**
+     * Gets an international string for the given key. This method does not check for the key
+     * validity. If the key is invalid, then a {@link MissingResourceException} may be thrown
+     * when a {@link InternationalString#toString(Locale)} method is invoked.
+     *
+     * @param  key  The key for the desired string.
+     * @param  args Values to substitute to "{0}", "{1}", <i>etc</i>.
+     * @return An international string for the given key.
+     */
+    public static InternationalString formatInternational(final int key, final Object... args) {
+        return new International(key, args);
+    }
 }

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] Thu May  9 12:24:13 2013
@@ -24,9 +24,14 @@ Code_1             = {0} code
 CurrentDateTime    = Current date and time
 CurrentDirectory   = Current directory
 DaylightTime       = Daylight time
+Destination        = Destination
 Directory          = Directory
+Identifier         = Identifier
+Index              = Index
 JavaExtensions     = Java extensions
 JavaHome           = Java home directory
+Latitude           = Latitude
+Longitude          = Longitude
 Libraries          = Libraries
 LocalConfiguration = Local configuration
 Locale             = Locale
@@ -37,6 +42,7 @@ MinimumValue       = Minimum value
 Name               = Name
 NumberOfValues     = Number of values
 NumberOfNaN        = Number of \u2018NaN\u2019
+Of_3               = {0} ({1} of {2})
 Offset             = Offset
 OperatingSystem    = Operating system
 Others             = Others
@@ -44,6 +50,7 @@ Paths              = Paths
 Root               = Root
 RootMeanSquare     = Root Mean Square
 Scale              = Scale
+Source             = Source
 StandardDeviation  = Standard deviation
 TemporaryFiles     = Temporary files
 Timezone           = Timezone

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=ISO-8859-1

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] Thu May  9 12:24:13 2013
@@ -24,9 +24,14 @@ Code_1             = Code {0}
 CurrentDateTime    = Date et heure courantes
 CurrentDirectory   = R\u00e9pertoire courant
 DaylightTime       = Heure normale
+Destination        = Destination
 Directory          = R\u00e9pertoire
+Identifier         = Identifiant
+Index              = Index
 JavaExtensions     = Extensions du Java
 JavaHome           = R\u00e9pertoire du Java
+Latitude           = Latitude
+Longitude          = Longitude
 Libraries          = Biblioth\u00e8ques
 LocalConfiguration = Configuration locale
 Locale             = Locale
@@ -37,6 +42,7 @@ MinimumValue       = Valeur minimale
 Name               = Nom
 NumberOfValues     = Nombre de valeurs
 NumberOfNaN        = Nombre de \u2018NaN\u2019
+Of_3               = {0} ({1} de {2})
 Offset             = D\u00e9calage
 OperatingSystem    = Syst\u00e8me d'exploitation
 Others             = Autres
@@ -44,6 +50,7 @@ Paths              = Chemins
 Root               = Racine
 RootMeanSquare     = Moyenne quadratique
 Scale              = \u00c9chelle
+Source             = Source
 StandardDeviation  = \u00c9cart type
 TemporaryFiles     = Fichiers temporaires
 Timezone           = Fuseau horaire

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=ISO-8859-1

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java [UTF-8] Thu May  9 12:24:13 2013
@@ -64,7 +64,7 @@ import org.opengis.metadata.citation.Cit
  * @module
  *
  * @see IdentifierSpace
- * @see org.apache.sis.metadata.iso.MetadataEntity
+ * @see org.apache.sis.metadata.iso.ISOMetadata
  * @see ReferenceResolver#newIdentifiedObject(MarshalContext, Class, Identifier[])
  */
 public interface IdentifiedObject {
@@ -99,7 +99,8 @@ public interface IdentifiedObject {
     Collection<? extends Identifier> getIdentifiers();
 
     /**
-     * A map view of {@linkplain #getIdentifiers() identifiers}.
+     * A map view of the {@linkplain #getIdentifiers() identifiers} collection
+     * as (<var>authority</var>, <var>code</var>) entries.
      * Each {@linkplain java.util.Map.Entry map entry} is associated
      * to an element from the above identifier collection in which the
      * {@linkplain java.util.Map.Entry#getKey() key} is the

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java [UTF-8] Thu May  9 12:24:13 2013
@@ -28,7 +28,7 @@ import org.opengis.metadata.citation.Cit
  * identifier authority} and the {@linkplain java.util.Map.Entry#getValue() value} is the
  * {@linkplain Identifier#getCode() identifier code}.
  *
- * <p>Some XML identifiers are difficult to handle as {@link Identifier} objects. Those identifiers are
+ * <p>Some XML identifiers are difficult to handle as {@link Identifier} objects. Those identifiers are
  * rather handled using specialized classes like {@link XLink}. This {@code IdentifierMap} interface
  * mirrors the standard {@link Map#get(Object) get} and {@link Map#put(Object, Object) put} methods
  * with specialized methods, in order to fetch and store identifiers as objects of the specialized
@@ -64,10 +64,8 @@ public interface IdentifierMap extends M
      * @param  value The identifier to be associated with the given namespace.
      * @return The previous identifier associated with {@code authority}, or {@code null}
      *         if there was no mapping of the specialized type for {@code authority}.
-     * @throws IdentifierAlreadyBoundException If this map expects unique identifiers for the
-     *         given authority, and the given value is already associated to another object.
      * @throws UnsupportedOperationException If the identifier map is unmodifiable.
      */
     <T> T putSpecialized(IdentifierSpace<T> authority, T value)
-            throws IdentifierAlreadyBoundException, UnsupportedOperationException;
+            throws UnsupportedOperationException;
 }

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java [UTF-8] Thu May  9 12:24:13 2013
@@ -59,7 +59,11 @@ public interface IdentifierSpace<T> exte
      * Its type is {@code "xs:ID"} - i.e. it is a fragment identifier, unique within document scope only,
      * for internal cross-references. It is not useful by itself as a persistent unique identifier.
      *
-     * <p>The XML {@linkplain #getName() attribute name} is {@code "gml:id"}.</p>
+     * <p>The XML {@linkplain #getName() attribute name} is {@code "gml:id"}, but is also used
+     * for {@code "gco:id"} in metadata documents. However the {@code "gco:"} prefix is omitted
+     * in XML documents (i.e. the {@code gco:id} attribute is <cite>unqualified</cite>).</p>
+     *
+     * <p>The XML attribute name of the reference to such identified object is {@code "xlink:href"}.</p>
      *
      * @see javax.xml.bind.annotation.XmlID
      */
@@ -70,7 +74,11 @@ public interface IdentifierSpace<T> exte
      * that implement ISO 19115 in XML. May be used as a persistent unique identifier, but only
      * available within GMD context.
      *
-     * <p>The XML {@linkplain #getName() attribute name} is {@code "gco:uuid"}.</p>
+     * <p>The XML {@linkplain #getName() attribute name} is {@code "gco:uuid"}. However the
+     * {@code "gco:"} prefix is omitted in XML documents (i.e. the {@code gco:uuid} attribute
+     * is <cite>unqualified</cite>).</p>
+     *
+     * <p>The XML attribute name of the reference to such identified object is {@code "gco:uuidref"}.
      *
      * @see UUID
      */
@@ -91,7 +99,7 @@ public interface IdentifierSpace<T> exte
     /**
      * Any XML attributes defined by OGC in the
      * <a href="http://schemas.opengis.net/xlink/1.0.0/xlinks.xsd">xlink</a> schema.
-     * Note that the above {@link #HREF} identifier space is a special case of this
+     * Note that the above {@link #HREF} identifier space is a special case of this
      * {@code xlink} identifier space.
      *
      * @see XLink

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java [UTF-8] Thu May  9 12:24:13 2013
@@ -60,35 +60,34 @@ public abstract class MarshalContext {
      * Returns the locale to use for (un)marshalling, or {@code null} if no locale were explicitly
      * specified. The locale returned by this method can be used for choosing a language in an
      * {@link org.opengis.util.InternationalString}.
-     * This locale may vary in different fragments of the same XML document.
+     *
+     * <p>This locale may vary in different fragments of the same XML document.
      * In particular children of {@link org.opengis.metadata.Metadata} inherit the locale
-     * specified by the {@link org.opengis.metadata.Metadata#getLanguage()} attribute.
+     * specified by the {@link org.opengis.metadata.Metadata#getLanguage()} attribute.</p>
+     *
+     * {@section Handling of <code>Locale.ROOT</code>}
+     * {@link Locale#ROOT} is interpreted as a request for locale-neutral strings.
+     * The meaning of "locale-neutral" is implementation specific - this is usually
+     * very close to the English locale, but not necessarily. For examples dates are
+     * formatted according ISO standard instead than the rules of the English locale.
      *
-     * {@section Null locale}
-     * Null locales are typically interpreted as a request for locale-independent strings in SIS.
-     * The meaning of "locale-independent" is implementation specific -
-     * this is usually very close to the English locale, but not necessarily
-     * (e.g. dates formatted according ISO standard instead then English locale).
-     * If the locale is {@code null}, then callers shall select a default locale as documented
-     * in the {@link org.apache.sis.util.iso.DefaultInternationalString#toString(Locale)} javadoc.
-     * As a matter of rule:
-     *
-     * <ul>
-     *   <li>If the locale is given to an {@code InternationalString.toString(Locale)} method,
-     *       keep the {@code null} value since the international string is already expected to
-     *       returns a "unlocalized" string in such case.</li>
-     *   <li>Otherwise, if a {@code Locale} instance is really needed, use {@link Locale#US}
-     *       as an approximation of "unlocalized" string.</li>
-     * </ul>
+     * {@section Handling of <code>null</code> locale}
+     * A {@code null} value means that the locale is unspecified. Callers are encouraged
+     * to use the root locale as the default value, but some flexibility is allowed.
      *
      * @return The locale for the XML fragment being (un)marshalled, or {@code null} is unspecified.
+     *
+     * @see org.apache.sis.util.iso.DefaultInternationalString#toString(Locale)
      */
     public abstract Locale getLocale();
 
     /**
      * Returns the timezone to use for (un)marshalling, or {@code null} if none were explicitely
-     * specified. If {@code null}, then an implementation-default (typically UTC) timezone is
-     * assumed.
+     * specified.
+     *
+     * {@section Handling of <code>null</code> timezone}
+     * A {@code null} value means that the timezone is unspecified. Callers are encouraged
+     * to use the UTC timezone as the default value, but some flexibility is allowed.
      *
      * @return The timezone for the XML fragment being (un)marshalled, or {@code null} if unspecified.
      */

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java [UTF-8] Thu May  9 12:24:13 2013
@@ -18,14 +18,17 @@ package org.apache.sis.xml;
 
 import java.util.Map;
 import java.util.Deque;
-import java.util.LinkedList;
 import java.util.Collections;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.atomic.AtomicBoolean;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import net.jcip.annotations.ThreadSafe;
 import org.apache.sis.util.logging.Logging;
+import org.apache.sis.internal.util.DelayedExecutor;
+import org.apache.sis.internal.util.DelayedRunnable;
 import org.apache.sis.internal.jaxb.AdapterReplacement;
 
 
@@ -38,7 +41,7 @@ import org.apache.sis.internal.jaxb.Adap
  * {@preformat java
  *     Marshaller marshaller = pool.acquireMarshaller();
  *     marshaller.marchall(...);
- *     pool.release(marshaller);
+ *     pool.recycle(marshaller);
  * }
  *
  * {@section Configuring (un)marshallers}
@@ -51,21 +54,26 @@ import org.apache.sis.internal.jaxb.Adap
  * @module
  *
  * @see XML
- *
- * @todo Need a timeout for disposing marshallers that have been unused for a while.
  */
 @ThreadSafe
 public class MarshallerPool {
     /**
-     * Maximal amount of marshallers and unmarshallers to keep.
+     * Amount of nanoseconds to wait before to remove unused (un)marshallers.
+     * This is a very approximative value: actual timeout will not be shorter,
+     * but may be twice longer.
+     */
+    private static final long TIMEOUT = 15000000000L; // 15 seconds.
+
+    /**
+     * Kind of JAXB implementations.
      */
-    private static final int CAPACITY = 16;
+    private static final byte INTERNAL = 0, ENDORSED = 1, OTHER = 2;
 
     /**
-     * The key to be used in the map given to the constructors for specifying the root namespace.
+     * The key to be used in the map given to the constructors for specifying the default namespace.
      * An example of value for this key is {@code "http://www.isotc211.org/2005/gmd"}.
      */
-    public static final String ROOT_NAMESPACE_KEY = "org.apache.sis.xml.rootNamespace";
+    public static final String DEFAULT_NAMESPACE_KEY = "org.apache.sis.xml.defaultNamespace";
 
     /**
      * The JAXB context to use for creating marshaller and unmarshaller.
@@ -73,11 +81,11 @@ public class MarshallerPool {
     private final JAXBContext context;
 
     /**
-     * {@code true} if the JAXB implementation is the one bundled in JDK 6,
-     * or {@code false} if this is an external implementation like a JAR put
-     * in the endorsed directory.
+     * {@link #INTERNAL} if the JAXB implementation is the one bundled in the JDK,
+     * {@link #ENDORSED} if the TAXB implementation is the endorsed JAXB (Glassfish), or
+     * {@link #OTHER} if unknown.
      */
-    private final boolean internal;
+    private final byte implementation;
 
     /**
      * The mapper between namespaces and prefix.
@@ -85,16 +93,38 @@ public class MarshallerPool {
     private final Object mapper;
 
     /**
-     * The pool of marshaller. This pool is initially empty
-     * and will be filled with elements as needed.
+     * The pool of marshaller. This pool is initially empty and will be filled with elements as needed.
+     * Marshallers (if any) shall be fetched using the {@link Deque#poll()} method and, after use,
+     * given back to the pool using the {@link Deque#push(Object)} method.
+     *
+     * <p>This queue must be a thread-safe implementation, since it will not be invoked in
+     * synchronized block.</p>
+     *
+     * @see #acquireMarshaller()
+     * @see #recycle(Marshaller)
      */
-    private final Deque<Marshaller> marshallers = new LinkedList<Marshaller>();
+    private final Deque<Marshaller> marshallers;
 
     /**
-     * The pool of unmarshaller. This pool is initially empty
-     * and will be filled with elements as needed.
+     * The pool of unmarshaller. This pool is initially empty and will be filled with elements as needed.
+     * Unmarshallers (if any) shall be fetched using the {@link Deque#poll()} method and, after use,
+     * given back to the pool using the {@link Deque#push(Object)} method.
+     *
+     * <p>This queue must be a thread-safe implementation, since it will not be invoked in
+     * synchronized block.</p>
+     *
+     * @see #acquireUnmarshaller()
+     * @see #recycle(Unmarshaller)
      */
-    private final Deque<Unmarshaller> unmarshallers = new LinkedList<Unmarshaller>();
+    private final Deque<Unmarshaller> unmarshallers;
+
+    /**
+     * {@code true} if a task has been scheduled for removing expired (un)marshallers,
+     * or {@code false} if no removal task is currently scheduled.
+     *
+     * @see #scheduleRemoval()
+     */
+    private final AtomicBoolean isRemovalScheduled;
 
     /**
      * Creates a new factory for the given class to be bound, with a default empty namespace.
@@ -108,7 +138,7 @@ public class MarshallerPool {
 
     /**
      * Creates a new factory for the given class to be bound. The keys in the {@code properties} map
-     * shall be one or many of the constants defined in this class like {@link #ROOT_NAMESPACE_KEY}.
+     * shall be one or many of the constants defined in this class like {@link #DEFAULT_NAMESPACE_KEY}.
      *
      * @param  properties       The set of properties to be given to the pool.
      * @param  classesToBeBound The classes to be bound, for example {@code DefaultMetadata.class}.
@@ -120,11 +150,14 @@ public class MarshallerPool {
 
     /**
      * Creates a new factory for the given packages, with a default empty namespace.
-     * The separator character for the packages is the colon.
+     * The separator character for the packages is the colon. Example:
      *
-     * @param  packages         The packages in which JAXB will search for annotated classes to be bound,
-     *                          for example {@code "org.apache.sis.metadata.iso:org.apache.sis.metadata.iso.citation"}.
-     * @throws JAXBException    If the JAXB context can not be created.
+     * {@preformat text
+     *     "org.apache.sis.metadata.iso:org.apache.sis.metadata.iso.citation"
+     * }
+     *
+     * @param  packages      The colon-separated list of packages in which JAXB will search for annotated classes.
+     * @throws JAXBException If the JAXB context can not be created.
      */
     public MarshallerPool(final String packages) throws JAXBException {
         this(Collections.<String,String>emptyMap(), packages);
@@ -133,11 +166,10 @@ public class MarshallerPool {
     /**
      * Creates a new factory for the given packages. The separator character for the packages is the
      * colon. The keys in the {@code properties} map shall be one or many of the constants defined
-     * in this class like {@link #ROOT_NAMESPACE_KEY}.
+     * in this class like {@link #DEFAULT_NAMESPACE_KEY}.
      *
      * @param  properties    The set of properties to be given to the pool.
-     * @param  packages      The packages in which JAXB will search for annotated classes to be bound,
-     *                       for example {@code "org.apache.sis.metadata.iso:org.apache.sis.metadata.iso.citation"}.
+     * @param  packages      The colon-separated list of packages in which JAXB will search for annotated classes.
      * @throws JAXBException If the JAXB context can not be created.
      */
     public MarshallerPool(final Map<String,String> properties, final String packages) throws JAXBException {
@@ -154,138 +186,214 @@ public class MarshallerPool {
     @SuppressWarnings({"unchecked", "rawtypes"}) // Generic array creation
     private MarshallerPool(final Map<String,String> properties, final JAXBContext context) throws JAXBException {
         this.context = context;
-        String rootNamespace = properties.get(ROOT_NAMESPACE_KEY);
+        String rootNamespace = properties.get(DEFAULT_NAMESPACE_KEY);
         if (rootNamespace == null) {
             rootNamespace = "";
         }
         /*
          * Detects if we are using the endorsed JAXB implementation (i.e. the one provided in
-         * separated JAR files).  If not, we will assume that we are using the implementation
-         * bundled in JDK 6. We use the JAXB context package name as a criterion.
+         * separated JAR files) or the one bundled in JDK 6. We use the JAXB context package
+         * name as a criterion:
          *
          *   JAXB endorsed JAR uses    "com.sun.xml.bind"
          *   JAXB bundled in JDK uses  "com.sun.xml.internal.bind"
          */
-        internal = !context.getClass().getName().startsWith("com.sun.xml.bind");
-        String type = "org.apache.sis.xml.OGCNamespacePrefixMapper_Endorsed";
-        if (internal) {
-            type = type.substring(0, type.lastIndexOf('_'));
+        String classname = context.getClass().getName();
+        if (classname.startsWith("com.sun.xml.internal.bind.")) {
+            classname = "org.apache.sis.xml.OGCNamespacePrefixMapper";
+            implementation = INTERNAL;
+        } else if (classname.startsWith(Pooled.ENDORSED_PREFIX)) {
+            classname = "org.apache.sis.xml.OGCNamespacePrefixMapper_Endorsed";
+            implementation = ENDORSED;
+        } else {
+            classname = null;
+            implementation = OTHER;
         }
         /*
          * Instantiates the OGCNamespacePrefixMapper appropriate for the implementation
-         * we just detected.
+         * we just detected. Note that we may get NoClassDefFoundError instead than the
+         * usual ClassNotFoundException if the class was found but its parent class has
+         * not been found.
          */
-        try {
-            mapper = Class.forName(type).getConstructor(String.class).newInstance(rootNamespace);
+        if (classname == null) {
+            mapper = null;
+        } else try {
+            mapper = Class.forName(classname).getConstructor(String.class).newInstance(rootNamespace);
         } catch (Throwable exception) { // (ReflectiveOperationException | NoClassDefFoundError) on JDK7 branch.
-            // The NoClassDefFoundError is because of our trick using "geotk-provided".
-            throw new JAXBException("Unsupported JAXB implementation.", exception);
-        }
-    }
-
-    /**
-     * Returns the marshaller or unmarshaller to use from the given queue.
-     * If the queue is empty, returns {@code null}.
-     */
-    private static <T> T acquire(final Deque<T> queue) {
-        synchronized (queue) {
-            return queue.pollLast();
+            throw new JAXBException(exception);
         }
+        marshallers        = new LinkedBlockingDeque<Marshaller>();
+        unmarshallers      = new LinkedBlockingDeque<Unmarshaller>();
+        isRemovalScheduled = new AtomicBoolean();
     }
 
     /**
      * Marks the given marshaller or unmarshaller available for further reuse.
+     * This method:
+     *
+     * <ul>
+     *   <li>{@link Pooled#reset() Resets} the (un)marshaller to its initial state.</li>
+     *   <li>{@linkplain Deque#push(Object) Pushes} the (un)marshaller in the given queue.</li>
+     *   <li>Registers a delayed task for disposing expired (un)marshallers after the timeout.</li>
+     * </ul>
      */
-    private static <T> void release(final Deque<T> queue, final T marshaller) {
+    private <T> void recycle(final Deque<T> queue, final T marshaller) {
         try {
             ((Pooled) marshaller).reset();
         } catch (JAXBException exception) {
-            // Not expected to happen because the we are supposed
+            // Not expected to happen because we are supposed
             // to reset the properties to their initial values.
-            Logging.unexpectedException(MarshallerPool.class, "release", exception);
+            Logging.unexpectedException(MarshallerPool.class, "recycle", exception);
             return;
         }
-        synchronized (queue) {
-            queue.addLast(marshaller);
-            while (queue.size() > CAPACITY) {
-                // Remove the least recently used marshallers.
-                queue.removeFirst();
+        queue.push(marshaller);
+        scheduleRemoval();
+    }
+
+    /**
+     * Schedule a new task for removing expired (un)marshallers if no such task is currently
+     * registered. If a task is already registered, then this method does nothing. Note that
+     * this task will actually wait for a longer time than the {@link #TIMEOUT} value before
+     * to execute, in order to increase the chances to process many (un)marshallers at once.
+     */
+    private void scheduleRemoval() {
+        if (isRemovalScheduled.compareAndSet(false, true)) {
+            DelayedExecutor.schedule(new DelayedRunnable(System.nanoTime() + 2*TIMEOUT) {
+                @Override public void run() {
+                    removeExpired();
+                }
+            });
+        }
+    }
+
+    /**
+     * Invoked from the task scheduled by {@link #scheduleRemoval()} for removing expired
+     * (un)marshallers. If some (un)marshallers remain after execution of this task, then
+     * this method will reschedule a new task for checking again later.
+     */
+    final void removeExpired() {
+        isRemovalScheduled.set(false);
+        final long now = System.nanoTime();
+        if (!removeExpired(marshallers, now) | // Really |, not ||
+            !removeExpired(unmarshallers, now))
+        {
+            scheduleRemoval();
+        }
+    }
+
+    /**
+     * Removes expired (un)marshallers from the given queue.
+     *
+     * @param  <T>   Either {@code Marshaller} or {@code Unmarshaller} type.
+     * @param  queue The queue from which to remove expired (un)marshallers.
+     * @param  now   Current value of {@link System#nanoTime()}.
+     * @return {@code true} if the queue became empty as a result of this method call.
+     */
+    private static <T> boolean removeExpired(final Deque<T> queue, final long now) {
+        T next;
+        while ((next = queue.peekLast()) != null) {
+            /*
+             * The above line fetched the oldest (un)marshaller without removing it.
+             * If the timeout is not yet elapsed, do not remove that (un)marshaller.
+             * Since marshallers are enqueued in chronological order, the next ones
+             * should be yet more recent, so it is not worth to continue the search.
+             */
+            if (now - ((Pooled) next).resetTime < TIMEOUT) {
+                return false;
+            }
+            /*
+             * Now remove the (un)marshaller and check again the timeout. This second
+             * check is because the oldest (un)marshaller may have changed concurrently
+             * (depending on the queue implementation, which depends on the target JDK).
+             * If such case, restore the (un)marshaller on the queue.
+             */
+            next = queue.pollLast();
+            if (now - ((Pooled) next).resetTime < TIMEOUT) {
+                queue.addLast(next);
+                return false;
             }
         }
+        return true;
     }
 
     /**
      * Returns a JAXB marshaller from the pool. If there is no marshaller currently available
-     * in the pool, then this method will {@linkplain #createMarshaller create} a new one.
+     * in the pool, then this method will {@linkplain #createMarshaller() create} a new one.
      *
      * <p>This method shall be used as below:</p>
      *
      * {@preformat java
      *     Marshaller marshaller = pool.acquireMarshaller();
      *     marshaller.marchall(...);
-     *     pool.release(marshaller);
+     *     pool.recycle(marshaller);
      * }
      *
-     * Note that this is not strictly required to release the marshaller in a {@code finally}
-     * block. Actually it is safer to let the garbage collector disposes the marshaller if an
-     * error occurred while marshalling the object.
+     * Note that {@link #recycle(Marshaller)} shall not be invoked in case of exception,
+     * since the marshaller may be in an invalid state.
      *
      * @return A marshaller configured for formatting OGC/ISO XML.
      * @throws JAXBException If an error occurred while creating and configuring a marshaller.
      */
     public Marshaller acquireMarshaller() throws JAXBException {
-        Marshaller marshaller = acquire(marshallers);
+        Marshaller marshaller = marshallers.poll();
         if (marshaller == null) {
-            marshaller = new PooledMarshaller(createMarshaller(), internal);
+            marshaller = new PooledMarshaller(createMarshaller(), implementation == INTERNAL);
         }
         return marshaller;
     }
 
     /**
      * Returns a JAXB unmarshaller from the pool. If there is no unmarshaller currently available
-     * in the pool, then this method will {@linkplain #createUnmarshaller create} a new one.
+     * in the pool, then this method will {@linkplain #createUnmarshaller() create} a new one.
      *
      * <p>This method shall be used as below:</p>
      *
      * {@preformat java
      *     Unmarshaller unmarshaller = pool.acquireUnmarshaller();
      *     Unmarshaller.unmarchall(...);
-     *     pool.release(unmarshaller);
+     *     pool.recycle(unmarshaller);
      * }
      *
-     * Note that this is not strictly required to release the unmarshaller in a {@code finally}
-     * block. Actually it is safer to let the garbage collector disposes the unmarshaller if an
-     * error occurred while unmarshalling the object.
+     * Note that {@link #recycle(Unmarshaller)} shall not be invoked in case of exception,
+     * since the unmarshaller may be in an invalid state.
      *
      * @return A unmarshaller configured for parsing OGC/ISO XML.
      * @throws JAXBException If an error occurred while creating and configuring the unmarshaller.
      */
     public Unmarshaller acquireUnmarshaller() throws JAXBException {
-        Unmarshaller unmarshaller = acquire(unmarshallers);
+        Unmarshaller unmarshaller = unmarshallers.poll();
         if (unmarshaller == null) {
-            unmarshaller = new PooledUnmarshaller(createUnmarshaller(), internal);
+            unmarshaller = new PooledUnmarshaller(createUnmarshaller(), implementation == INTERNAL);
         }
         return unmarshaller;
     }
 
     /**
-     * Declares a marshaller as available for reuse. The caller should not use
-     * anymore the marshaller after this method call.
+     * Declares a marshaller as available for reuse.
+     * The caller should not use anymore the given marshaller after this method call.
+     *
+     * <p>Do not invoke this method if the marshaller threw an exception, since the
+     * marshaller may be in an invalid state. In particular, this method should not
+     * be invoked in a {@code finally} block.</p>
      *
      * @param marshaller The marshaller to return to the pool.
      */
-    public void release(final Marshaller marshaller) {
-        release(marshallers, marshaller);
+    public void recycle(final Marshaller marshaller) {
+        recycle(marshallers, marshaller);
     }
 
     /**
-     * Declares a unmarshaller as available for reuse. The caller should not use
-     * anymore the unmarshaller after this method call.
+     * Declares a unmarshaller as available for reuse.
+     * The caller should not use anymore the given unmarshaller after this method call.
+     *
+     * <p>Do not invoke this method if the marshaller threw an exception, since the
+     * marshaller may be in an invalid state. In particular, this method should not
+     * be invoked in a {@code finally} block.</p>
      *
      * @param unmarshaller The unmarshaller to return to the pool.
      */
-    public void release(final Unmarshaller unmarshaller) {
-        release(unmarshallers, unmarshaller);
+    public void recycle(final Unmarshaller unmarshaller) {
+        recycle(unmarshallers, unmarshaller);
     }
 
     /**
@@ -297,13 +405,20 @@ public class MarshallerPool {
      * @throws JAXBException If an error occurred while creating and configuring the marshaller.
      */
     protected Marshaller createMarshaller() throws JAXBException {
-        final String mapperKey = internal ?
-            "com.sun.xml.internal.bind.namespacePrefixMapper" :
-            "com.sun.xml.bind.namespacePrefixMapper";
         final Marshaller marshaller = context.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
         marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
-        marshaller.setProperty(mapperKey, mapper);
+        switch (implementation) {
+            case INTERNAL: {
+                marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);
+                break;
+            }
+            case ENDORSED: {
+                marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);
+                break;
+            }
+            // Do nothing for the OTHER case.
+        }
         synchronized (AdapterReplacement.PROVIDER) {
             for (final AdapterReplacement adapter : AdapterReplacement.PROVIDER) {
                 adapter.register(marshaller);

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java [UTF-8] Thu May  9 12:24:13 2013
@@ -27,8 +27,9 @@ import org.apache.sis.util.ArgumentCheck
 /**
  * List some namespaces URLs used by JAXB when (un)marshalling.
  *
- * @author  Cédric Briançon (Geomatys)
+ * @author  Cédric Briançon (Geomatys)
  * @author  Quentin Boileau (Geomatys)
+ * @author  Guilhem Legal (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
  * @version 0.3
  * @module
@@ -42,6 +43,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gco"}.
      *
      * @category ISO
      */
@@ -49,6 +51,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gfc"}.
      *
      * @category ISO
      */
@@ -56,6 +59,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gmd"}.
      *
      * @category ISO
      */
@@ -63,6 +67,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gmi"}.
      *
      * @category ISO
      */
@@ -70,6 +75,23 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "srv"}.
+     *
+     * @category ISO
+     */
+    public static final String SRV = "http://www.isotc211.org/2005/srv";
+
+    /**
+     * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gts"}.
+     *
+     * @category ISO
+     */
+    public static final String GTS = "http://www.isotc211.org/2005/gts";
+
+    /**
+     * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gmx"}.
      *
      * @category ISO
      */
@@ -77,6 +99,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "gml"}.
      *
      * @category OGC
      */
@@ -84,6 +107,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "csw"}.
      *
      * @category OGC
      */
@@ -100,6 +124,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "xlink"}.
      *
      * @category W3C
      */
@@ -107,6 +132,7 @@ public final class Namespaces extends St
 
     /**
      * The <code>{@value}</code> URL.
+     * The usual prefix for this namespace is {@code "fra"}.
      *
      * @category Profiles
      */
@@ -176,7 +202,7 @@ public final class Namespaces extends St
         if (prefix != null) {
             return prefix;
         }
-        namespace = namespace.toLowerCase(Locale.US);
+        namespace = namespace.toLowerCase(Locale.ROOT);
         for (final String baseURL : GENERIC_URLS) {
             if (namespace.startsWith(baseURL)) {
                 final int startAt = baseURL.length();

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/Namespaces.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObject.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObject.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObject.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObject.java [UTF-8] Thu May  9 12:24:13 2013
@@ -29,7 +29,7 @@ package org.apache.sis.xml;
  *
  * <p>Nil objects appear most frequently in XML documents since if a mandatory ISO 19115 attribute
  * is absent, then the ISO 19139 standard requires us to said why it is so. The following example
- * shows a {@code CI_Citation} fragment with an ordinary {@code CI_Series} element on the left side,
+ * shows a {@code CI_Citation} fragment with an ordinary {@code CI_Series} element on the left side,
  * and an unknown {@code CI_Series} element on the right side:</p>
  *
  * <table class="sis"><tr>
@@ -74,7 +74,6 @@ package org.apache.sis.xml;
  * @module
  *
  * @see NilReason#createNilObject(Class)
- * @see ReferenceResolver#resolve(MarshalContext, Class, NilReason)
  * @see org.apache.sis.util.Numbers#valueOfNil(Class)
  */
 public interface NilObject {

Propchange: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObject.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Thu May  9 12:24:13 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Modified: sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
URL: http://svn.apache.org/viewvc/sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java?rev=1480602&r1=1480601&r2=1480602&view=diff
==============================================================================
--- sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java [iso-8859-1] (original)
+++ sis/branches/Android/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java [UTF-8] Thu May  9 12:24:13 2013
@@ -34,7 +34,7 @@ import org.apache.sis.internal.jaxb.Iden
 import org.apache.sis.internal.jaxb.IdentifierMapWithSpecialCases;
 
 // Related to JDK7
-import org.apache.sis.internal.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**
@@ -72,7 +72,7 @@ final class NilObjectHandler implements 
                 asList.add(identifier);
             }
         }
-        attribute = new IdentifierMapWithSpecialCases(asList, null);
+        attribute = new IdentifierMapWithSpecialCases(asList);
     }
 
     /**



Mime
View raw message