sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1420841 - in /sis/branches/JDK7: sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/ sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/ sis-utility/src/main/java/org/apache/sis/util/iso/ sis-utility/src/test/java/org/apa...
Date Wed, 12 Dec 2012 17:17:48 GMT
Author: desruisseaux
Date: Wed Dec 12 17:17:46 2012
New Revision: 1420841

URL: http://svn.apache.org/viewvc?rev=1420841&view=rev
Log:
Merged the CodeLists static methods with Types, in the hope to simplify a little bit the API.
This also make easier to emphase the similarity between methods like getDescription(CodeList,
...)
and getDescription(Class, ...).

Removed:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/CodeLists.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/iso/CodeListsTest.java
Modified:
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/Types.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/iso/TypesTest.java

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java?rev=1420841&r1=1420840&r2=1420841&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java
(original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java
Wed Dec 12 17:17:46 2012
@@ -18,7 +18,7 @@ package org.apache.sis.internal.jaxb.cod
 
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import org.opengis.metadata.Obligation;
-import org.apache.sis.util.iso.CodeLists;
+import org.apache.sis.util.iso.Types;
 
 
 /**
@@ -40,7 +40,7 @@ public final class MD_ObligationCode ext
      */
     @Override
     public Obligation unmarshal(String value) {
-        return CodeLists.valueOf(Obligation.class, value);
+        return Types.forCodeName(Obligation.class, value, true);
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java?rev=1420841&r1=1420840&r2=1420841&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
Wed Dec 12 17:17:46 2012
@@ -18,7 +18,7 @@ package org.apache.sis.internal.jaxb.gmd
 
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import org.opengis.util.CodeList;
-import org.apache.sis.util.iso.CodeLists;
+import org.apache.sis.util.iso.Types;
 import org.apache.sis.internal.jaxb.MarshalContext;
 
 
@@ -117,7 +117,7 @@ public abstract class CodeListAdapter<Va
         if (adapter == null) {
             return null;
         }
-        return CodeLists.valueOf(getCodeListClass(), adapter.proxy.identifier());
+        return Types.forCodeName(getCodeListClass(), adapter.proxy.identifier(), true);
     }
 
     /**
@@ -132,7 +132,7 @@ public abstract class CodeListAdapter<Va
         if (value == null) {
             return null;
         }
-        return wrap(isEnum() ? new CodeListProxy(CodeLists.getCodeName(value))
+        return wrap(isEnum() ? new CodeListProxy(Types.getCodeName(value))
                              : new CodeListProxy(MarshalContext.current(), value));
     }
 

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java?rev=1420841&r1=1420840&r2=1420841&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java
Wed Dec 12 17:17:46 2012
@@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlType
 import javax.xml.bind.annotation.XmlValue;
 import org.opengis.util.CodeList;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.util.iso.CodeLists;
+import org.apache.sis.util.iso.Types;
 import org.apache.sis.internal.jaxb.MarshalContext;
 
 
@@ -166,15 +166,15 @@ public final class CodeListProxy {
      * @param code    The code list to wrap.
      */
     CodeListProxy(final MarshalContext context, final CodeList<?> code) {
-        final String classID = CodeLists.getListName(code);
-        final String fieldID = CodeLists.getCodeName(code);
+        final String classID = Types.getListName(code);
+        final String fieldID = Types.getCodeName(code);
         codeList = schema(context, "gmxCodelists.xml", classID);
         /*
          * Get the localized name of the field identifier, if possible.
-         * This code partially duplicates CodeList.getCodeTitle(CodeList, Locale).
+         * This code partially duplicates Types.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.getCodeTitle(CodeList, Locale) method accordingly.
+         * the Types.getCodeTitle(CodeList, Locale) method accordingly.
          */
         final Locale locale = context.getLocale();
         if (locale != null) {
@@ -192,7 +192,7 @@ public final class CodeListProxy {
             // 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.getCodeTitle(code);
+            value = Types.getCodeTitle(code);
         }
         codeListValue = fieldID;
     }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java?rev=1420841&r1=1420840&r2=1420841&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
Wed Dec 12 17:17:46 2012
@@ -22,7 +22,7 @@ import org.apache.sis.util.Characters.Fi
 
 
 /**
- * The filters used by {@link CodeLists#valueOf(Class, String)}.
+ * The filters used by {@link Types#forCodeName(Class, String, boolean)}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java?rev=1420841&r1=1420840&r2=1420841&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java Wed Dec
12 17:17:46 2012
@@ -25,7 +25,9 @@ import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import java.io.IOException;
 import java.io.InputStream;
-
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
 import org.opengis.annotation.UML;
 import org.opengis.util.CodeList;
 import org.opengis.util.NameFactory;
@@ -33,6 +35,7 @@ import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.Identifier;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.BackingStoreException;
@@ -40,12 +43,18 @@ import org.apache.sis.internal.util.Defa
 
 
 /**
- * Static methods working on GeoAPI types.
- * The methods in this class can be used for:
+ * Static methods working on GeoAPI types and {@link CodeList} values.
+ * This class provides:
  *
  * <ul>
- *   <li>Creating {@link InternationalString} instances from {@link CharSequence} instances.</li>
- *   <li>Mapping ISO identifiers to the GeoAPI types (interfaces or {@linkplain CodeList
code lists}).</li>
+ *   <li>{@link #toInternationalString(CharSequence)} and {@link #toGenericName(Object,
NameFactory)}
+ *       for creating name-related objects from various objects.</li>
+ *   <li>{@link #getStandardName(Class)}, {@link #getListName(CodeList)} and {@link
#getCodeName(CodeList)}
+ *       for fetching ISO names if possible, or Java names as a fallback.</li>
+ *   <li>{@link #getCodeTitle(CodeList, Locale)}, {@link #getDescription(CodeList,
Locale)} and
+ *       {@link #getDescription(Class, Locale)} for fetching human-readable descriptions.</li>
+ *   <li>{@link #forStandardName(String)} and {@link #forCodeName(Class, String, boolean)}
for
+ *       fetching an instance from a name (converse of above {@code get} methods).</li>
  * </ul>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
@@ -57,7 +66,7 @@ public final class Types extends Static 
     /**
      * The class loader to use for fetching GeoAPI resources.
      */
-    static final ClassLoader CLASSLOADER = UML.class.getClassLoader();
+    private static final ClassLoader CLASSLOADER = UML.class.getClassLoader();
 
     /**
      * The types for ISO 19115 UML identifiers. The keys are UML identifiers. Values
@@ -85,6 +94,8 @@ public final class Types extends Static 
      *
      * @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}.
+     *
+     * @see #forStandardName(String)
      */
     public static String getStandardName(final Class<?> type) {
         if (type != null) {
@@ -100,53 +111,166 @@ public final class Types extends Static 
     }
 
     /**
-     * Returns the GeoAPI interface for the given ISO name, or {@code null} if none.
-     * The identifier argument shall be the value documented in the {@link UML#identifier()}
-     * annotation associated with the GeoAPI interface.
+     * Returns the ISO classname (if available) or the Java classname (as a fallback)
+     * of the given code. This method uses the {@link UML} annotation if it exists, or
+     * fallback on the {@linkplain Class#getSimpleName() simple class name} otherwise.
      * Examples:
      *
      * <ul>
-     *   <li>{@code forStandardName("CI_Citation")}      returns <code>{@linkplain
org.opengis.metadata.citation.Citation}.class</code></li>
-     *   <li>{@code forStandardName("CS_AxisDirection")} returns <code>{@linkplain
org.opengis.referencing.cs.AxisDirection}.class</code></li>
+     *   <li>{@code getListName(AxisDirection.NORTH)} returns {@code "CS_AxisDirection"}.</li>
+     *   <li>{@code getListName(CharacterSet.UTF_8)} returns {@code "MD_CharacterSetCode"}.</li>
+     *   <li>{@code getListName(ImagingCondition.BLURRED_IMAGE)} returns {@code "MD_ImagingConditionCode"}.</li>
      * </ul>
      *
-     * Only identifiers for the stable part of GeoAPI are recognized. This method does not
handle
-     * the identifiers for the {@code geoapi-pending} module.
+     * @param  code The code for which to get the class name, or {@code null}.
+     * @return The ISO (preferred) or Java (fallback) class name, or {@code null} if the
given code is null.
+     */
+    public static String getListName(final CodeList<?> code) {
+        if (code == null) {
+            return null;
+        }
+        final Class<?> type = code.getClass();
+        final String id = getStandardName(type);
+        return (id != null) ? id : type.getSimpleName();
+    }
+
+    /**
+     * Returns the ISO name (if available) or the Java name (as a fallback) of the given
code.
+     * If the code has no {@link UML} identifier, then the programmatic name is used as a
fallback.
+     * Examples:
      *
-     * @param  identifier The ISO {@linkplain UML} identifier, or {@code null}.
-     * @return The GeoAPI interface, or {@code null} if the given identifier is {@code null}
or unknown.
+     * <ul>
+     *   <li>{@code getCodeName(AxisDirection.NORTH)} returns {@code "north"}.</li>
+     *   <li>{@code getCodeName(CharacterSet.UTF_8)} returns {@code "utf8"}.</li>
+     *   <li>{@code getCodeName(ImagingCondition.BLURRED_IMAGE)} returns {@code "blurredImage"}.</li>
+     * </ul>
+     *
+     * @param  code The code for which to get the name, or {@code null}.
+     * @return The UML identifiers or programmatic name for the given code,
+     *         or {@code null} if the given code is null.
+     *
+     * @see #getCodeTitle(CodeList)
+     * @see #getDescription(CodeList, Locale)
+     * @see #forCodeName(Class, String, boolean)
      */
-    public static synchronized Class<?> forStandardName(final String identifier) {
-        if (identifier == null) {
+    public static String getCodeName(final CodeList<?> code) {
+        if (code == null) {
             return null;
         }
-        if (typeForNames == null) {
-            final Class<UML> c = UML.class;
-            final InputStream in = c.getResourceAsStream("class-index.properties");
-            if (in == null) {
-                throw new MissingResourceException("class-index.properties", c.getName(),
identifier);
-            }
-            final Properties props = new Properties();
-            try {
-                props.load(in);
-                in.close();
-            } catch (IOException | IllegalArgumentException e) {
-                throw new BackingStoreException(e);
+        final String id = code.identifier();
+        return (id != null && !id.isEmpty()) ? id : code.name();
+    }
+
+    /**
+     * 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 #getCodeTitle(CodeList, Locale)} instead.
+     *
+     * <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 getCodeTitle(AxisDirection.NORTH)} returns {@code "North"}.</li>
+     *   <li>{@code getCodeTitle(CharacterSet.UTF_8)} returns {@code "UTF-8"}.</li>
+     *   <li>{@code getCodeTitle(ImagingCondition.BLURRED_IMAGE)} returns {@code "Blurred
image"}.</li>
+     * </ul>
+     *
+     * @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.
+     *
+     * @see #getCodeName(CodeList)
+     * @see #getDescription(CodeList, Locale)
+     */
+    public static String getCodeTitle(final CodeList<?> code) {
+        if (code == null) {
+            return null;
+        }
+        String id = code.identifier();
+        final String name = code.name();
+        if (id == null) {
+            id = name;
+        }
+        for (final String candidate : code.names()) {
+            if (!candidate.equals(name) && candidate.length() >= id.length())
{
+                id = candidate;
             }
-            typeForNames = new HashMap<>(props);
         }
-        final Object value = typeForNames.get(identifier);
-        if (value == null || value instanceof Class<?>) {
-            return (Class<?>) value;
+        return CharSequences.camelCaseToSentence(id).toString();
+    }
+
+    /**
+     * Returns the localized title of the given code.
+     * 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 {@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 #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 title, or {@code null} if the given code is null.
+     *
+     * @see #getDescription(CodeList, Locale)
+     */
+    public static String getCodeTitle(final CodeList<?> code, Locale locale) {
+        if (code == null) {
+            return null;
         }
-        final Class<?> type;
+        if (locale == null) {
+            locale = Locale.US;
+        }
+        /*
+         * The code below is a duplicated - in a different way - of CodeListProxy(CodeList)
+         * constructor (org.apache.sis.internal.jaxb.code package). This duplication exists
+         * because CodeListProxy constructor stores more information in an opportunist way.
+         * If this method is updated, please update CodeListProxy(CodeList) accordingly.
+         */
+        final String key = getListName(code) + '.' + getCodeName(code);
         try {
-            type = Class.forName((String) value);
-        } catch (ClassNotFoundException e) {
-            throw new TypeNotPresentException((String) value, e);
+            return ResourceBundle.getBundle("org.opengis.metadata.CodeLists", locale, CLASSLOADER).getString(key);
+        } catch (MissingResourceException e) {
+            Logging.recoverableException(Types.class, "getCodeTitle", e);
+            return getCodeTitle(code);
         }
-        typeForNames.put(identifier, type);
-        return type;
+    }
+
+    /**
+     * 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 #getDescription(Class, Locale)
+     */
+    public static String getDescription(final CodeList<?> code, final Locale locale)
{
+        return (code != null) ? getDescription(getListName(code) + '.' + getCodeName(code),
locale) : null;
     }
 
     /**
@@ -169,7 +293,7 @@ public final class Types extends Static 
      * @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)
+     * @see #getDescription(CodeList, Locale)
      */
     public static String getDescription(final Class<?> type, final Locale locale) {
         return getDescription(getStandardName(type), locale);
@@ -182,7 +306,7 @@ public final class Types extends Static 
      * @param  locale  The locale in which to get the description.
      * @return The description, or {@code null} if none.
      */
-    static String getDescription(final String key, Locale locale) {
+    private static String getDescription(final String key, Locale locale) {
         if (key != null) {
             if (locale == null) {
                 locale = Locale.getDefault();
@@ -197,6 +321,125 @@ public final class Types extends Static 
     }
 
     /**
+     * Returns all known values for the given type of code list.
+     * Note that the size of the returned array may growth between different invocations
of this method,
+     * since users can add their own codes to an existing list.
+     *
+     * @param <T> The compile-time type given as the {@code codeType} parameter.
+     * @param codeType The type of code list.
+     * @return The list of values for the given code list, or an empty array if none.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends CodeList<?>> T[] getCodeValues(final Class<T>
codeType) {
+        Object values;
+        try {
+            values = codeType.getMethod("values", (Class<?>[]) null).invoke(null, (Object[])
null);
+        } catch (InvocationTargetException e) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            }
+            if (cause instanceof Error) {
+                throw (Error) cause;
+            }
+            throw new UndeclaredThrowableException(cause);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            values = Array.newInstance(codeType, 0);
+        }
+        return (T[]) values;
+    }
+
+    /**
+     * Returns the GeoAPI interface for the given ISO name, or {@code null} if none.
+     * The identifier argument shall be the value documented in the {@link UML#identifier()}
+     * annotation associated with the GeoAPI interface.
+     * Examples:
+     *
+     * <ul>
+     *   <li>{@code forStandardName("CI_Citation")}      returns <code>{@linkplain
org.opengis.metadata.citation.Citation}.class</code></li>
+     *   <li>{@code forStandardName("CS_AxisDirection")} returns <code>{@linkplain
org.opengis.referencing.cs.AxisDirection}.class</code></li>
+     * </ul>
+     *
+     * Only identifiers for the stable part of GeoAPI are recognized. This method does not
handle
+     * the identifiers for the {@code geoapi-pending} module.
+     *
+     * @param  identifier The ISO {@linkplain UML} identifier, or {@code null}.
+     * @return The GeoAPI interface, or {@code null} if the given identifier is {@code null}
or unknown.
+     */
+    public static synchronized Class<?> forStandardName(final String identifier) {
+        if (identifier == null) {
+            return null;
+        }
+        if (typeForNames == null) {
+            final Class<UML> c = UML.class;
+            final InputStream in = c.getResourceAsStream("class-index.properties");
+            if (in == null) {
+                throw new MissingResourceException("class-index.properties", c.getName(),
identifier);
+            }
+            final Properties props = new Properties();
+            try {
+                props.load(in);
+                in.close();
+            } catch (IOException | IllegalArgumentException e) {
+                throw new BackingStoreException(e);
+            }
+            typeForNames = new HashMap<>(props);
+        }
+        final Object value = typeForNames.get(identifier);
+        if (value == null || value instanceof Class<?>) {
+            return (Class<?>) value;
+        }
+        final Class<?> type;
+        try {
+            type = Class.forName((String) value);
+        } catch (ClassNotFoundException e) {
+            throw new TypeNotPresentException((String) value, e);
+        }
+        typeForNames.put(identifier, type);
+        return type;
+    }
+
+    /**
+     * Returns the code of the given type that matches the given name, or optionally returns
a new
+     * one if none match it. This method performs the same work than the GeoAPI {@code valueOf(…)}
+     * method, except that this method is more tolerant on string comparisons when looking
for an
+     * existing code:
+     *
+     * <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>
+     *
+     * If no match is found, then a new code is created only if the {@code canCreate} argument
is
+     * {@code true}. Otherwise this method returns {@code null}.
+     *
+     * @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}.
+     *
+     * @see CodeList#valueOf(Class, String)
+     */
+    public static <T extends CodeList<T>> T forCodeName(final Class<T>
codeType, String name, final boolean canCreate) {
+        name = CharSequences.trimWhitespaces(name);
+        if (name == null || name.isEmpty()) {
+            return null;
+        }
+        final String typeName = codeType.getName();
+        try {
+            // Forces initialization of the given class in order
+            // to register its list of static final constants.
+            Class.forName(typeName, true, codeType.getClassLoader());
+        } catch (ClassNotFoundException e) {
+            throw new TypeNotPresentException(typeName, e); // Should never happen.
+        }
+        return CodeList.valueOf(codeType, new CodeListFilter(name, canCreate));
+    }
+
+    /**
      * 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/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=1420841&r1=1420840&r2=1420841&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
Wed Dec 12 17:17:46 2012
@@ -59,7 +59,6 @@ import org.junit.runners.Suite;
 
     // GeoAPI most basic types.
     org.apache.sis.util.iso.TypesTest.class,
-    org.apache.sis.util.iso.CodeListsTest.class,
     org.apache.sis.util.iso.SimpleInternationalStringTest.class,
     org.apache.sis.util.iso.DefaultInternationalStringTest.class,
     org.apache.sis.internal.util.LocalizedParseExceptionTest.class,

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java?rev=1420841&r1=1420840&r2=1420841&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java Wed
Dec 12 17:17:46 2012
@@ -16,8 +16,13 @@
  */
 package org.apache.sis.util.iso;
 
+import java.util.Set;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Locale;
 import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.citation.OnLineFunction;
+import org.opengis.metadata.content.ImagingCondition;
 import org.opengis.metadata.identification.CharacterSet;
 import org.opengis.referencing.datum.Datum;
 import org.opengis.referencing.cs.AxisDirection;
@@ -59,6 +64,18 @@ public final strictfp class TypesTest ex
     }
 
     /**
+     * Tests the {@link Types#forCodeName(Class, String, boolean)} method.
+     */
+    @Test
+    public void testForCodeName() {
+        assertSame(ImagingCondition.SEMI_DARKNESS, Types.forCodeName(ImagingCondition.class,
"SEMI_DARKNESS", false));
+        assertSame(ImagingCondition.SEMI_DARKNESS, Types.forCodeName(ImagingCondition.class,
"SEMIDARKNESS",  false));
+        assertSame(ImagingCondition.SEMI_DARKNESS, Types.forCodeName(ImagingCondition.class,
"semi darkness", false));
+        assertSame(ImagingCondition.SEMI_DARKNESS, Types.forCodeName(ImagingCondition.class,
"semi-darkness", false));
+        assertNull(Types.forCodeName(ImagingCondition.class, "darkness", false));
+    }
+
+    /**
      * Tests the {@link Types#getDescription(Class, Locale)} method.
      */
     @Test
@@ -68,4 +85,66 @@ public final strictfp class TypesTest ex
         assertEquals("Jeu de caractères.",
                 Types.getDescription(CharacterSet.class, Locale.FRENCH));
     }
+
+    /**
+     * Tests the {@link Types#getDescription(CodeList, Locale)} method.
+     */
+    @Test
+    public void testGetCodeDescription() {
+        assertEquals("ISO/IEC 8859-1, Information technology - 8-bit single byte coded graphic
character sets - Part 1 : Latin alphabet No.1.",
+                Types.getDescription(CharacterSet.ISO_8859_1, Locale.ENGLISH));
+        assertEquals("ISO/IEC 8859-1, alphabet latin 1.",
+                Types.getDescription(CharacterSet.ISO_8859_1, Locale.FRENCH));
+    }
+
+    /**
+     * Tests the examples given in {@link Types#getListName(CodeList)} javadoc.
+     */
+    @Test
+    public void testGetListName() {
+        assertEquals("CS_AxisDirection",        Types.getListName(AxisDirection   .NORTH));
+        assertEquals("MD_CharacterSetCode",     Types.getListName(CharacterSet    .UTF_8));
+        assertEquals("MD_ImagingConditionCode", Types.getListName(ImagingCondition.BLURRED_IMAGE));
+    }
+
+    /**
+     * Tests the examples given in {@link Types#getCodeName(CodeList)} javadoc.
+     */
+    @Test
+    public void testGetCodeName() {
+        assertEquals("north",        Types.getCodeName(AxisDirection   .NORTH));
+        assertEquals("utf8",         Types.getCodeName(CharacterSet    .UTF_8));
+        assertEquals("blurredImage", Types.getCodeName(ImagingCondition.BLURRED_IMAGE));
+    }
+
+    /**
+     * Tests the examples given in {@link Types#getCodeTitle(CodeList)} javadoc.
+     */
+    @Test
+    public void testGetCodeTitle() {
+        assertEquals("North",         Types.getCodeTitle(AxisDirection   .NORTH));
+        assertEquals("UTF-8",         Types.getCodeTitle(CharacterSet    .UTF_8));
+        assertEquals("Blurred image", Types.getCodeTitle(ImagingCondition.BLURRED_IMAGE));
+    }
+
+    /**
+     * Tests {@link Types#getCodeTitle(CodeList, Locale)}.
+     */
+    @Test
+    public void testGetLocalizedCodeTitle() {
+        assertEquals("Download",       Types.getCodeTitle(OnLineFunction.DOWNLOAD, Locale.ENGLISH));
+        assertEquals("Téléchargement", Types.getCodeTitle(OnLineFunction.DOWNLOAD,
Locale.FRENCH));
+    }
+
+    /**
+     * Tests the {@link Types#getCodeValues(Class)} method.
+     */
+    @Test
+    public void testGetCodeValues() {
+        final Set<OnLineFunction> expected = new HashSet<>(Arrays.asList(
+                OnLineFunction.INFORMATION, OnLineFunction.SEARCH, OnLineFunction.ORDER,
+                OnLineFunction.DOWNLOAD, OnLineFunction.OFFLINE_ACCESS));
+        final OnLineFunction[] actual = Types.getCodeValues(OnLineFunction.class);
+        assertTrue(expected.containsAll(Arrays.asList(actual)));
+    }
 }



Mime
View raw message