sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1417767 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/internal/jaxb/code/ main/java/org/apache/sis/util/ main/java/org/apache/sis/util/type/ main/java/org/apache/sis/xml/ test/java/org/apache/sis/test/suite/ test/java/o...
Date Thu, 06 Dec 2012 08:17:33 GMT
Author: desruisseaux
Date: Thu Dec  6 08:17:29 2012
New Revision: 1417767

URL: http://svn.apache.org/viewvc?rev=1417767&view=rev
Log:
Moved Locales.getLanguageCode(Locale) to ValueConverter, completed by addition of getCountryCode(...).
Renamed CodeLists.getDescription(...) as CodeLists.getCodeTitle(...) and added a "real" getDescription
method.
Improved javadoc.

Added:
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java
  (with props)
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/code/CodeListProxy.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Locales.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeListFilter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeLists.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/Types.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/ValueConverter.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/TypesTest.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/code/CodeListProxy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/code/CodeListProxy.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/code/CodeListProxy.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/code/CodeListProxy.java
Thu Dec  6 08:17:29 2012
@@ -23,7 +23,6 @@ import javax.xml.bind.annotation.XmlAttr
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 import org.opengis.util.CodeList;
-import org.apache.sis.util.Locales;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.type.CodeLists;
 import org.apache.sis.internal.jaxb.MarshalContext;
@@ -98,9 +97,9 @@ public final class CodeListProxy {
      * The optional {@code codeSpace} attribute in the XML element. The default value is
      * {@code null}. If a value is provided in this field, then {@link #value} should be
      * set as well.
-     * <p>
-     * This attribute is set to the 3 letters language code of the {@link #value} attribute,
-     * as returned by {@link Locale#getISO3Language()}.
+     *
+     * <p>This attribute is set to the 3-letters language code of the {@link #value}
attribute,
+     * as returned by {@link Locale#getISO3Language()}.</p>
      */
     @XmlAttribute
     public String codeSpace;
@@ -140,13 +139,15 @@ public final class CodeListProxy {
      * @param catalog       The file which defines the code list (for example {@code "ML_gmxCodelists.xml"}),
without its path.
      * @param codeList      The {@code codeList} attribute, to be concatenated after the
catalog name and the {@code "#"} symbol.
      * @param codeListValue The {@code codeListValue} attribute, to be declared in the attribute.
-     * @param value         The value in English language (because this constructor does
not set the {@link #codeSpace} attribute).
+     * @param codeSpace     The 3-letters language code of the {@code value} attribute, or
{@code null} if none.
+     * @param value         The value in the language specified by the {@code codeSpace}
attribute, or {@code null} if none.
      */
     public CodeListProxy(final MarshalContext context, final String catalog,
-            final String codeList, final String codeListValue, final String value)
+            final String codeList, final String codeListValue, final String codeSpace, final
String value)
     {
         this.codeList      = schema(context, catalog, codeList);
         this.codeListValue = codeListValue;
+        this.codeSpace     = codeSpace;
         this.value         = value;
     }
 
@@ -163,10 +164,10 @@ public final class CodeListProxy {
         codeList = schema(context, "gmxCodelists.xml", classID);
         /*
          * Get the localized name of the field identifier, if possible.
-         * This code partially duplicates CodeList.getDescription(CodeList, Locale).
+         * This code partially duplicates CodeList.getCodeTitle(CodeList, Locale).
          * This duplication exists because this constructor stores more information in
          * an opportunist way. If this constructor is updated, please consider updating
-         * the CodeList.getDescription(CodeList, Locale) method accordingly.
+         * the CodeList.getCodeTitle(CodeList, Locale) method accordingly.
          */
         final Locale locale = context.getLocale();
         if (locale != null) {
@@ -178,12 +179,12 @@ public final class CodeListProxy {
             }
         }
         if (value != null) {
-            codeSpace = Locales.getLanguageCode(locale);
+            codeSpace = MarshalContext.converter(context).toLanguageCode(context, locale);
         } else {
             // Fallback when no value is defined for the code list. Build a value from the
             // most descriptive name (excluding the field name), which is usually the UML
             // name except for CharacterSet in which case it is a string like "UTF-8".
-            value = CodeLists.getDescription(code);
+            value = CodeLists.getCodeTitle(code);
         }
         codeListValue = fieldID;
     }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java Thu
Dec  6 08:17:29 2012
@@ -1530,6 +1530,57 @@ cmp:    while (ia < lga) {
     }
 
     /**
+     * Returns {@code true} if the given texts are equal, ignoring case and any character
which
+     * is not a {@linkplain Character#isLetterOrDigit(int) letter or digit}. In particular,
+     * spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.
+     * This method is sometime used for comparing identifiers in a lenient way.
+     *
+     * @param  s1 The first string to compare, or {@code null}.
+     * @param  s2 The second string to compare, or {@code null}.
+     * @return {@code true} if the two given texts are equal, comparing only letters and
digits
+     *         in a case-insensitive way, or if both arguments are {@code null}.
+     */
+    public static boolean equalsLettersAndDigits(final CharSequence s1, final CharSequence
s2) {
+        if (s1 == s2) {
+            return true;
+        }
+        if (s1 == null || s2 == null) {
+            return false;
+        }
+        final int lg1 = s1.length();
+        final int lg2 = s2.length();
+        int i2 = 0, n;
+        for (int i1=0; i1<lg1; i1+=n) {
+            int c1 = codePointAt(s1, i1);
+            n = charCount(c1);
+            if (isLetterOrDigit(c1)) {
+                // Fetch the next significant character from the second string.
+                int c2;
+                do {
+                    if (i2 >= lg2) {
+                        return false; // The first string has more significant characters
than expected.
+                    }
+                    c2 = codePointAt(s2, i2);
+                    i2 += charCount(c2);
+                } while (!isLetterOrDigit(c2));
+
+                // Compare the characters in the same way than String.equalsIgnoreCase(String).
+                if (c1 != c2 && !equalsIgnoreCase(c1, c2)) {
+                    return false;
+                }
+            }
+        }
+        while (i2 < lg2) {
+            final int s = codePointAt(s2, i2);
+            if (isLetterOrDigit(s)) {
+                return false; // The first string has less significant characters than expected.
+            }
+            i2 += charCount(s);
+        }
+        return true;
+    }
+
+    /**
      * Returns {@code true} if the two given texts are equal. This method delegates to
      * {@link String#contentEquals(CharSequence)} if possible. This method never invoke
      * {@link CharSequence#toString()} in order to avoid a potentially large copy of data.

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Locales.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Locales.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Locales.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Locales.java Thu Dec 
6 08:17:29 2012
@@ -22,7 +22,6 @@ import java.util.Arrays;
 import java.util.Locale;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
-import java.util.MissingResourceException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
@@ -199,24 +198,6 @@ public final class Locales extends Stati
     }
 
     /**
-     * Returns the {@linkplain Locale#getISO3Language() 3-letters ISO language code} if available,
-     * or the {@linkplain Locale#getLanguage() 2-letters code} otherwise.
-     *
-     * @param  locale The locale for which we want the language.
-     * @return The language code, 3 letters if possible or 2 letters otherwise.
-     *
-     * @see Locale#getISO3Language()
-     */
-    public static String getLanguageCode(final Locale locale) {
-        try {
-            return locale.getISO3Language();
-        } catch (MissingResourceException e) {
-            Logging.recoverableException(Locales.class, "getLanguage", e);
-            return locale.getLanguage();
-        }
-    }
-
-    /**
      * Parses the given locale. The string is the language code either as the 2 letters or
the
      * 3 letters ISO code. It can optionally be followed by the {@code '_'} character and
the
      * country code (again either as 2 or 3 letters), optionally followed by {@code '_'}
and

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeListFilter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeListFilter.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeListFilter.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeListFilter.java
Thu Dec  6 08:17:29 2012
@@ -17,6 +17,7 @@
 package org.apache.sis.util.type;
 
 import org.opengis.util.CodeList;
+import org.apache.sis.util.CharSequences;
 
 
 /**
@@ -60,68 +61,10 @@ final class CodeListFilter implements Co
     @Override
     public boolean accept(final CodeList<?> code) {
         for (final String name : code.names()) {
-            if (matches(name, codename)) {
+            if (CharSequences.equalsLettersAndDigits(name, codename)) {
                 return true;
             }
         }
         return false;
     }
-
-    /**
-     * Returns {@code true} if the given strings are equal, ignoring case, whitespaces and
the
-     * {@code '_'} character.
-     *
-     * @param  candidate The first string to compare.
-     * @param  search The second string to compare.
-     * @return {@code true} if the two strings are equal.
-     */
-    private static boolean matches(final String candidate, final String search) {
-        final int length = candidate.length();
-        final int searchLength = search.length();
-        int searchIndex=0, n;
-        for (int i=0; i<length; i+=n) {
-            int c = candidate.codePointAt(i);
-            n = Character.charCount(c);
-            if (isSignificant(c)) {
-                // Fetch the next significant character from the expected string.
-                int s;
-                do {
-                    if (searchIndex >= searchLength) {
-                        return false; // The name has more significant characters than expected.
-                    }
-                    s = search.codePointAt(searchIndex);
-                    searchIndex += Character.charCount(s);
-                } while (!isSignificant(s));
-
-                // Compare the characters in the same way than String.equalsIgnoreCase(String).
-                if (c != s) {
-                    c = Character.toUpperCase(c);
-                    s = Character.toUpperCase(s);
-                    if (c != s) {
-                        c = Character.toLowerCase(c);
-                        s = Character.toLowerCase(s);
-                        if (c != s) {
-                            return false;
-                        }
-                    }
-                }
-            }
-        }
-        while (searchIndex < searchLength) {
-            final int s = search.charAt(searchIndex);
-            if (isSignificant(s)) {
-                return false; // The name has less significant characters than expected.
-            }
-            searchIndex += Character.charCount(s);
-        }
-        return true;
-    }
-
-    /**
-     * Returns {@code true} if the given character should be taken in account when comparing
two
-     * strings. Current implementation ignores whitespace and the {@code '_'} character.
-     */
-    private static boolean isSignificant(final int c) {
-        return !Character.isWhitespace(c) && !Character.isIdentifierIgnorable(c)
&& c != '_';
-    }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeLists.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeLists.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeLists.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/CodeLists.java Thu
Dec  6 08:17:29 2012
@@ -30,11 +30,18 @@ import org.apache.sis.util.logging.Loggi
 
 
 /**
- * Utility methods working on {@link CodeList}.
- * This class defines a SIS {@link #valueOf(Class, String)} method which can be used instead
- * of the GeoAPI {@code CodeList.valueOf(Class, String)} when more tolerant search is wanted.
- * The main difference between the two methods is that the GeoAPI method is strict while
the
- * SIS method ignores cases, whitespaces and the {@code '_'} character.
+ * Static methods working on {@link CodeList}.
+ * This class provides:
+ *
+ * <ul>
+ *   <li>{@link #getListName(CodeList)} and {@link #getCodeName(CodeList)}
+ *       for fetching ISO name if possible, or Java name as a fallback.</li>
+ *   <li>{@link #getCodeTitle(CodeList, Locale)} for fetching human-readable names.</li>
+ *   <li>A SIS {@link #valueOf(Class, String)} method which can be used instead of
the GeoAPI
+ *       {@link CodeList#valueOf(Class, String)} when more tolerant search is wanted.
+ *       The main difference between the two methods is that the GeoAPI method is strict
+ *       while the SIS method ignores cases, whitespaces and the {@code '_'} character.</li>
+ * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)
@@ -96,26 +103,26 @@ public final class CodeLists extends Sta
     }
 
     /**
-     * Returns a unlocalized description of the given code.
-     * This method builds a description using heuristics rules, which should give reasonable
+     * Returns a unlocalized title for the given code.
+     * This method builds a title using heuristics rules, which should give reasonable
      * results without the need of resource bundles. For better results, consider using
-     * {@link #getDescription(CodeList, Locale)} instead.
+     * {@link #getCodeTitle(CodeList, Locale)} instead.
      *
-     * <p>The current heuristic implementation is to iterate over {@linkplain CodeList#names()
all
-     * code names}, select the longest one excluding the {@linkplain CodeList#name() field
name}
-     * if possible, then {@linkplain CharSequences#camelCaseToSentence(CharSequence) make
a sentence}
+     * <p>The current heuristic implementation iterates over {@linkplain CodeList#names()
all
+     * code names}, selects the longest one excluding the {@linkplain CodeList#name() field
name}
+     * if possible, then {@linkplain CharSequences#camelCaseToSentence(CharSequence) makes
a sentence}
      * from that name. Examples:</p>
      *
      * <ul>
-     *   <li><code>getDescription({@linkplain org.opengis.referencing.cs.AxisDirection#NORTH})</code>
returns {@code "North"}.</li>
-     *   <li><code>getDescription({@linkplain org.opengis.metadata.identification.CharacterSet#UTF_8})</code>
returns {@code "UTF-8"}.</li>
-     *   <li><code>getDescription({@linkplain org.opengis.metadata.content.ImagingCondition#BLURRED_IMAGE})</code>
returns {@code "Blurred image"}.</li>
+     *   <li><code>getCodeTitle({@linkplain org.opengis.referencing.cs.AxisDirection#NORTH})</code>
returns {@code "North"}.</li>
+     *   <li><code>getCodeTitle({@linkplain org.opengis.metadata.identification.CharacterSet#UTF_8})</code>
returns {@code "UTF-8"}.</li>
+     *   <li><code>getCodeTitle({@linkplain org.opengis.metadata.content.ImagingCondition#BLURRED_IMAGE})</code>
returns {@code "Blurred image"}.</li>
      * </ul>
      *
-     * @param  code The code from which to get a description, or {@code null}.
-     * @return A unlocalized description for the given code, or {@code null} if the given
code is null.
+     * @param  code The code from which to get a title, or {@code null}.
+     * @return A unlocalized title for the given code, or {@code null} if the given code
is null.
      */
-    public static String getDescription(final CodeList<?> code) {
+    public static String getCodeTitle(final CodeList<?> code) {
         if (code == null) {
             return null;
         }
@@ -133,7 +140,7 @@ public final class CodeLists extends Sta
     }
 
     /**
-     * Returns the localized name of the given code.
+     * Returns the localized title of the given code.
      * Special cases:
      *
      * <ul>
@@ -141,15 +148,19 @@ public final class CodeLists extends Sta
      *   <li>If {@code locale} is {@code null}, then this method uses {@link Locale#US}
      *       as a close approximation of "unlocalized" strings since OGC standards are
      *       defined in English.</li>
+     *   <li>If there is no resources for the given code in the given language, then
this method
+     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
      *   <li>If there is no localized resources for the given code, then this method
fallback
-     *       on {@link #getDescription(CodeList)}.</li>
+     *       on {@link #getCodeTitle(CodeList)}.</li>
      * </ul>
      *
      * @param  code   The code for which to get the localized name, or {@code null}.
      * @param  locale The local, or {@code null} if none.
-     * @return The localized sentence, or {@code null} if the given code is null.
+     * @return The localized title, or {@code null} if the given code is null.
+     *
+     * @see #getDescription(CodeList, Locale)
      */
-    public static String getDescription(final CodeList<?> code, Locale locale) {
+    public static String getCodeTitle(final CodeList<?> code, Locale locale) {
         if (code == null) {
             return null;
         }
@@ -166,9 +177,49 @@ public final class CodeLists extends Sta
         try {
             return ResourceBundle.getBundle("org.opengis.metadata.CodeLists", locale).getString(key);
         } catch (MissingResourceException e) {
-            Logging.recoverableException(CodeLists.class, "localize", e);
-            return getDescription(code);
+            Logging.recoverableException(CodeLists.class, "getCodeTitle", e);
+            return getCodeTitle(code);
+        }
+    }
+
+    /**
+     * Returns the localized description of the given code, or {@code null} if none.
+     * Special cases:
+     *
+     * <ul>
+     *   <li>If {@code code} is {@code null}, then this method returns {@code null}.</li>
+     *   <li>If {@code locale} is {@code null}, then this method uses the
+     *       {@linkplain Locale#getDefault() default locale} - there is no such thing
+     *       like "unlocalized" description.</li>
+     *   <li>If there is no resources for the given code in the given language, then
this method
+     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
+     *   <li>If there is no localized resources for the given code, then this method
returns
+     *       {@code null} - there is no fallback.</li>
+     * </ul>
+     *
+     * For a description of the code list as a whole instead than a particular code,
+     * see {@link Types#getDescription(Class, Locale)}.
+     *
+     * @param  code   The code for which to get the localized description, or {@code null}.
+     * @param  locale The desired local, or {@code null} for the default locale.
+     * @return The localized description, or {@code null} if the given code is null.
+     *
+     * @see #getCodeTitle(CodeList, Locale)
+     * @see Types#getDescription(Class, Locale)
+     */
+    public static String getDescription(final CodeList<?> code, Locale locale) {
+        if (code != null) {
+            if (locale == null) {
+                locale = Locale.getDefault();
+            }
+            final String key = getListName(code) + '.' + getCodeName(code);
+            try {
+                return ResourceBundle.getBundle("org.opengis.metadata.Descriptions", locale).getString(key);
+            } catch (MissingResourceException e) {
+                Logging.recoverableException(CodeLists.class, "getDescription", e);
+            }
         }
+        return null;
     }
 
     /**
@@ -202,12 +253,18 @@ public final class CodeLists extends Sta
 
     /**
      * Returns the code of the given type that matches the given name, or returns a new one
if none
-     * match it. This method performs the same work than the GeoAPI method, except that it
is more
-     * tolerant on string comparisons (see the <a href="#skip-navbar_top">class javadoc</a>).
+     * match it. This method performs the same work than the GeoAPI method, except that this
method
+     * is more tolerant on string comparisons when looking for an existing code:
      *
-     * @param <T> The compile-time type given as the {@code codeType} parameter.
-     * @param codeType The type of code list.
-     * @param name The name of the code to obtain, or {@code null}.
+     * <ul>
+     *   <li>Name comparisons are case-insensitive.</li>
+     *   <li>Only {@linkplain Character#isLetterOrDigit(int) letter and digit} characters
are compared.
+     *       Spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.</li>
+     * </ul>
+     *
+     * @param <T>       The compile-time type given as the {@code codeType} parameter.
+     * @param codeType  The type of code list.
+     * @param name      The name of the code to obtain, or {@code null}.
      * @return A code matching the given name, or {@code null} if the name is null.
      *
      * @see CodeList#valueOf(Class, String)
@@ -221,10 +278,10 @@ public final class CodeLists extends Sta
      * {@link #valueOf(Class, String)} method. If no existing code matches, then this method
      * creates a new code if {@code canCreate} is {@code true}, or returns {@code null} otherwise.
      *
-     * @param <T> The compile-time type given as the {@code codeType} parameter.
-     * @param codeType The type of code list.
-     * @param name The name of the code to obtain, or {@code null}.
-     * @param canCreate {@code true} if this method is allowed to create new code.
+     * @param <T>        The compile-time type given as the {@code codeType} parameter.
+     * @param codeType   The type of code list.
+     * @param name       The name of the code to obtain, or {@code null}.
+     * @param canCreate  {@code true} if this method is allowed to create new code.
      * @return A code matching the given name, or {@code null} if the name is null
      *         or if no matching code is found and {@code canCreate} is {@code false}.
      *

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/Types.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/Types.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/Types.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/type/Types.java Thu Dec
 6 08:17:29 2012
@@ -18,7 +18,9 @@ package org.apache.sis.util.type;
 
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Properties;
+import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,11 +29,12 @@ import org.opengis.annotation.UML;
 import org.opengis.util.CodeList;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.collection.BackingStoreException;
 
 
 /**
- * Convenience methods working on GeoAPI types.
+ * Static methods working on GeoAPI types.
  * The methods in this class can be used for:
  *
  * <ul>
@@ -69,8 +72,8 @@ public final class Types extends Static 
      *   <li><code>getStandardName({@linkplain org.opengis.referencing.cs.AxisDirection}.class)</code>
returns {@code "CS_AxisDirection"}.</li>
      * </ul>
      *
-     * @param  type The GeoAPI interface from which to get the ISO name, or {@code null}.
-     * @return The ISO name for the given interface, or {@code null} if none or if the given
type is {@code null}.
+     * @param  type The GeoAPI interface or code list from which to get the ISO name, or
{@code null}.
+     * @return The ISO name for the given type, or {@code null} if none or if the type is
{@code null}.
      */
     public static String getStandardName(final Class<?> type) {
         if (type != null) {
@@ -136,6 +139,45 @@ public final class Types extends Static 
     }
 
     /**
+     * Returns a localized description for the given class, or {@code null} if none.
+     * This method can be used for GeoAPI interfaces or {@link CodeList}.
+     * Special cases:
+     *
+     * <ul>
+     *   <li>If {@code code} is {@code null}, then this method returns {@code null}.</li>
+     *   <li>If {@code locale} is {@code null}, then this method uses the
+     *       {@linkplain Locale#getDefault() default locale} - there is no such thing
+     *       like "unlocalized" description.</li>
+     *   <li>If there is no resources for the given type in the given language, then
this method
+     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
+     *   <li>If there is no localized resources for the given type, then this method
returns
+     *       {@code null} - there is no fallback.</li>
+     * </ul>
+     *
+     * @param  type The GeoAPI interface or code list from which to get the description,
or {@code null}.
+     * @param  locale The desired local, or {@code null} for the default locale.
+     * @return The ISO name for the given type, or {@code null} if none or if the type is
{@code null}.
+     *
+     * @see CodeLists#getDescription(CodeList, Locale)
+     */
+    public static String getDescription(final Class<?> type, Locale locale) {
+        if (type != null) {
+            final String name = getStandardName(type);
+            if (name != null) {
+                if (locale == null) {
+                    locale = Locale.getDefault();
+                }
+                try {
+                    return ResourceBundle.getBundle("org.opengis.metadata.Descriptions",
locale).getString(name);
+                } catch (MissingResourceException e) {
+                    Logging.recoverableException(Types.class, "getDescription", e);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Returns the given characters sequence as an international string. If the given sequence
is
      * null or an instance of {@link InternationalString}, this this method returns it unchanged.
      * Otherwise, this method copies the {@link InternationalString#toString()} value in
a new

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/ValueConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/ValueConverter.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/ValueConverter.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/ValueConverter.java Thu
Dec  6 08:17:29 2012
@@ -20,6 +20,7 @@ import java.net.URI;
 import java.net.URL;
 import java.net.URISyntaxException;
 import java.net.MalformedURLException;
+import java.util.MissingResourceException;
 import java.util.Locale;
 import java.util.UUID;
 import javax.measure.unit.Unit;
@@ -110,6 +111,96 @@ public class ValueConverter {
     }
 
     /**
+     * Converts the given locale to a language code. For strict ISO 19139 compliance, the
language
+     * code shall be a 3-letters ISO code as returned by {@link Locale#getISO3Language()}.
+     * However those codes may not be available for every locales.
+     *
+     * <p>The default implementation performs the following step:</p>
+     * <ul>
+     *   <li>Try {@code value.getISO3Language()}:<ul>
+     *     <li>On success, return that value if non-empty, or {@code null} otherwise.</li>
+     *     <li>If an exception has been thrown, then:<ul>
+     *       <li>If {@link #exceptionOccured exceptionOccured(…)} return {@code
true}, then
+     *           returns {@code value.getLanguage()} if non-empty or {@code null} otherwise.</li>
+     *       <li>If {@code exceptionOccured(…)} returned {@code false} (which
is the default
+     *           behavior), then let the exception propagate.</li>
+     *     </ul></li>
+     *   </ul></li>
+     * </ul>
+     *
+     * @param  context Context (GML version, locale, <i>etc.</i>) of the (un)marshalling
process.
+     * @param  value The locale to convert to a language code, or {@code null}.
+     * @return The language code, or {@code null} if the given value was null or does not
contains
+     *         a language code.
+     * @throws MissingResourceException If there is no ISO 3-letters language code for the
given locale.
+     *
+     * @see Locale#getISO3Language()
+     * @see Locale#getLanguage()
+     */
+    public String toLanguageCode(final MarshalContext context, final Locale value) throws
MissingResourceException {
+        if (value != null) {
+            String code;
+            try {
+                code = value.getISO3Language();
+            } catch (MissingResourceException e) {
+                if (!exceptionOccured(context, value, Locale.class, String.class, e)) {
+                    throw e;
+                }
+                code = value.getLanguage();
+            }
+            if (!code.isEmpty()) {
+                return code;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Converts the given locale to a country code. For strict ISO 19139 compliance, the
country
+     * code shall be a 3-letters ISO code as returned by {@link Locale#getISO3Country()}.
+     * However those codes may not be available for every locales.
+     *
+     * <p>The default implementation performs the following step:</p>
+     * <ul>
+     *   <li>Try {@code value.getISO3Country()}:<ul>
+     *     <li>On success, return that value if non-empty, or {@code null} otherwise.</li>
+     *     <li>If an exception has been thrown, then:<ul>
+     *       <li>If {@link #exceptionOccured exceptionOccured(…)} return {@code
true}, then
+     *           returns {@code value.getCountry()} if non-empty or {@code null} otherwise.</li>
+     *       <li>If {@code exceptionOccured(…)} returned {@code false} (which
is the default
+     *           behavior), then let the exception propagate.</li>
+     *     </ul></li>
+     *   </ul></li>
+     * </ul>
+     *
+     * @param  context Context (GML version, locale, <i>etc.</i>) of the (un)marshalling
process.
+     * @param  value The locale to convert to a country code, or {@code null}.
+     * @return The country code, or {@code null} if the given value was null or does not
contains
+     *         a country code.
+     * @throws MissingResourceException If there is no ISO 3-letters country code for the
given locale.
+     *
+     * @see Locale#getISO3Country()
+     * @see Locale#getCountry()
+     */
+    public String toCountryCode(final MarshalContext context, final Locale value) throws
MissingResourceException {
+        if (value != null) {
+            String code;
+            try {
+                code = value.getISO3Country();
+            } catch (MissingResourceException e) {
+                if (!exceptionOccured(context, value, Locale.class, String.class, e)) {
+                    throw e;
+                }
+                code = value.getCountry();
+            }
+            if (!code.isEmpty()) {
+                return code;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Converts the given string to a locale. The string is the language code either as the
2
      * letters or the 3 letters ISO code. It can optionally be followed by the {@code '_'}
      * character and the country code (again either as 2 or 3 letters), optionally followed

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
Thu Dec  6 08:17:29 2012
@@ -58,6 +58,7 @@ import org.junit.runners.Suite;
 
   // GeoAPI most basic types.
   org.apache.sis.util.type.TypesTest.class,
+  org.apache.sis.util.type.CodeListsTest.class,
   org.apache.sis.util.type.SimpleInternationalStringTest.class,
   org.apache.sis.util.type.DefaultInternationalStringTest.class,
   org.apache.sis.internal.util.LocalizedParseExceptionTest.class,

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
Thu Dec  6 08:17:29 2012
@@ -341,6 +341,16 @@ public final strictfp class CharSequence
     }
 
     /**
+     * Tests the {@link CharSequences#equalsLettersAndDigits(CharSequence, CharSequence)}
method.
+     */
+    @Test
+    public void testEqualsLettersAndDigits() {
+        assertTrue (equalsLettersAndDigits(" UTF-8 ", "utf8"));
+        assertTrue (equalsLettersAndDigits("UTF-8", " utf 8"));
+        assertFalse(equalsLettersAndDigits("UTF-8", " utf 16"));
+    }
+
+    /**
      * Tests the {@link CharSequences#equals(CharSequence, CharSequence)} method.
      */
     @Test

Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java?rev=1417767&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java
(added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java
Thu Dec  6 08:17:29 2012
@@ -0,0 +1,117 @@
+/*
+ * 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.util.type;
+
+import java.util.Set;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import org.opengis.metadata.citation.OnLineFunction;
+import org.opengis.metadata.content.ImagingCondition;
+import org.opengis.metadata.identification.CharacterSet;
+import org.opengis.referencing.cs.AxisDirection;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests the {@link CodeLists} class.
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+@DependsOn(TypesTest.class)
+public final strictfp class CodeListsTest extends TestCase {
+    /**
+     * Tests the examples given in {@link CodeLists#getListName(CodeList)} javadoc.
+     */
+    @Test
+    public void testGetListName() {
+        assertEquals("CS_AxisDirection",        CodeLists.getListName(AxisDirection   .NORTH));
+        assertEquals("MD_CharacterSetCode",     CodeLists.getListName(CharacterSet    .UTF_8));
+        assertEquals("MD_ImagingConditionCode", CodeLists.getListName(ImagingCondition.BLURRED_IMAGE));
+    }
+
+    /**
+     * Tests the examples given in {@link CodeLists#getCodeName(CodeList)} javadoc.
+     */
+    @Test
+    public void testGetCodeName() {
+        assertEquals("north",        CodeLists.getCodeName(AxisDirection   .NORTH));
+        assertEquals("utf8",         CodeLists.getCodeName(CharacterSet    .UTF_8));
+        assertEquals("blurredImage", CodeLists.getCodeName(ImagingCondition.BLURRED_IMAGE));
+    }
+
+    /**
+     * Tests the examples given in {@link CodeLists#getCodeTitle(CodeList)} javadoc.
+     */
+    @Test
+    public void testGetCodeTitle() {
+        assertEquals("North",         CodeLists.getCodeTitle(AxisDirection   .NORTH));
+        assertEquals("UTF-8",         CodeLists.getCodeTitle(CharacterSet    .UTF_8));
+        assertEquals("Blurred image", CodeLists.getCodeTitle(ImagingCondition.BLURRED_IMAGE));
+    }
+
+    /**
+     * Tests {@link CodeLists#getCodeTitle(CodeList, Locale)}.
+     */
+    @Test
+    public void testGetLocalizedCodeTitle() {
+        assertEquals("Download",       CodeLists.getCodeTitle(OnLineFunction.DOWNLOAD, Locale.ENGLISH));
+        assertEquals("Téléchargement", CodeLists.getCodeTitle(OnLineFunction.DOWNLOAD,
Locale.FRENCH));
+    }
+
+    /**
+     * Tests the {@link CodeLists#getDescription(CodeList, Locale)} method.
+     */
+    @Test
+    public void testGetDescription() {
+        assertEquals("ISO/IEC 8859-1, Information technology - 8-bit single byte coded graphic
character sets - Part 1 : Latin alphabet No.1.",
+                CodeLists.getDescription(CharacterSet.ISO_8859_1, Locale.ENGLISH));
+        assertEquals("ISO/IEC 8859-1, alphabet latin 1.",
+                CodeLists.getDescription(CharacterSet.ISO_8859_1, Locale.FRENCH));
+    }
+
+    /**
+     * Tests the {@link CodeLists#values(Class)} method.
+     */
+    @Test
+    public void testValues() {
+        final Set<OnLineFunction> expected = new HashSet<>(Arrays.asList(
+                OnLineFunction.INFORMATION, OnLineFunction.SEARCH, OnLineFunction.ORDER,
+                OnLineFunction.DOWNLOAD, OnLineFunction.OFFLINE_ACCESS));
+        final OnLineFunction[] actual = CodeLists.values(OnLineFunction.class);
+        assertTrue(expected.containsAll(Arrays.asList(actual)));
+    }
+
+    /**
+     * Tests the {@link CodeLists#valueOf(Class, String, boolean)} method.
+     */
+    @Test
+    public void testValueOf() {
+        assertSame(ImagingCondition.SEMI_DARKNESS, CodeLists.valueOf(ImagingCondition.class,
"SEMI_DARKNESS", false));
+        assertSame(ImagingCondition.SEMI_DARKNESS, CodeLists.valueOf(ImagingCondition.class,
"SEMIDARKNESS",  false));
+        assertSame(ImagingCondition.SEMI_DARKNESS, CodeLists.valueOf(ImagingCondition.class,
"semi darkness", false));
+        assertSame(ImagingCondition.SEMI_DARKNESS, CodeLists.valueOf(ImagingCondition.class,
"semi-darkness", false));
+        assertNull(CodeLists.valueOf(ImagingCondition.class, "darkness", false));
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/CodeListsTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/TypesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/TypesTest.java?rev=1417767&r1=1417766&r2=1417767&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/TypesTest.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/type/TypesTest.java Thu
Dec  6 08:17:29 2012
@@ -16,7 +16,9 @@
  */
 package org.apache.sis.util.type;
 
+import java.util.Locale;
 import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.identification.CharacterSet;
 import org.opengis.referencing.datum.Datum;
 import org.opengis.referencing.cs.AxisDirection;
 import org.apache.sis.test.TestCase;
@@ -55,4 +57,15 @@ public final strictfp class TypesTest ex
         assertEquals(AxisDirection.class, Types.forStandardName("CS_AxisDirection"));
         assertNull  (                     Types.forStandardName("MD_Dummy"));
     }
+
+    /**
+     * Tests the {@link Types#getDescription(Class, Locale)} method.
+     */
+    @Test
+    public void testGetDescription() {
+        assertEquals("Name of the character coding standard used in the resource.",
+                Types.getDescription(CharacterSet.class, Locale.ENGLISH));
+        assertEquals("Jeu de caractères.",
+                Types.getDescription(CharacterSet.class, Locale.FRENCH));
+    }
 }



Mime
View raw message