sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1495368 - in /sis/branches/JDK7/core/sis-utility/src: main/java/org/apache/sis/internal/jaxb/ main/java/org/apache/sis/util/logging/ main/java/org/apache/sis/xml/ test/java/org/apache/sis/util/logging/ test/java/org/apache/sis/xml/
Date Fri, 21 Jun 2013 10:21:26 GMT
Author: desruisseaux
Date: Fri Jun 21 10:21:25 2013
New Revision: 1495368

URL: http://svn.apache.org/r1495368
Log:
Added a XML.WARNING_LISTENER property key in order to watch what may be going wrong during
(un)marshalling.
Also re-ordered the property order for using consistenly the same order everywhere.

Modified:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/logging/WarningListenersTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/ReferenceResolverMock.java

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
[UTF-8] Fri Jun 21 10:21:25 2013
@@ -19,7 +19,10 @@ package org.apache.sis.internal.jaxb;
 import java.util.Map;
 import java.util.Locale;
 import java.util.TimeZone;
+import java.util.logging.LogRecord;
 import org.apache.sis.util.Version;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.logging.WarningListener;
 import org.apache.sis.xml.MarshalContext;
 import org.apache.sis.xml.ValueConverter;
 import org.apache.sis.xml.ReferenceResolver;
@@ -70,20 +73,20 @@ public final class Context extends Marsh
     private static final ThreadLocal<Context> CURRENT = new ThreadLocal<>();
 
     /**
-     * The value converter currently in use, or {@code null} for {@link ValueConverter#DEFAULT}.
+     * Various boolean attributes determines by the above static constants.
      */
-    private ValueConverter converter;
+    private int bitMasks;
 
     /**
-     * The reference resolver currently in use, or {@code null} for {@link ReferenceResolver#DEFAULT}.
+     * The locale to use for marshalling, or {@code null} if no locale were explicitly specified.
      */
-    private ReferenceResolver resolver;
+    private Locale locale;
 
     /**
-     * The GML version to be marshalled or unmarshalled, or {@code null} if unspecified.
-     * If null, than the latest version is assumed.
+     * The timezone, or {@code null} if unspecified.
+     * In the later case, an implementation-default (typically UTC) timezone is used.
      */
-    private Version versionGML;
+    private TimeZone timezone;
 
     /**
      * The base URL of ISO 19139 (or other standards) schemas. The valid values
@@ -92,20 +95,25 @@ public final class Context extends Marsh
     private Map<String,String> schemas;
 
     /**
-     * The locale to use for marshalling, or {@code null} if no locale were explicitly specified.
+     * The GML version to be marshalled or unmarshalled, or {@code null} if unspecified.
+     * If null, than the latest version is assumed.
      */
-    private Locale locale;
+    private Version versionGML;
 
     /**
-     * The timezone, or {@code null} if unspecified.
-     * In the later case, an implementation-default (typically UTC) timezone is used.
+     * The reference resolver currently in use, or {@code null} for {@link ReferenceResolver#DEFAULT}.
      */
-    private TimeZone timezone;
+    private ReferenceResolver resolver;
 
     /**
-     * Various boolean attributes determines by the above static constants.
+     * The value converter currently in use, or {@code null} for {@link ValueConverter#DEFAULT}.
      */
-    private int bitMasks;
+    private ValueConverter converter;
+
+    /**
+     * The object to inform about warnings, or {@code null} if none.
+     */
+    private WarningListener<?> warningListener;
 
     /**
      * The context which was previously used. This form a linked list allowing
@@ -127,26 +135,29 @@ public final class Context extends Marsh
      *     }
      * }
      *
-     * @param  converter  The converter in use.
-     * @param  resolver   The resolver in use.
-     * @param  versionGML The GML version, or {@code null}.
-     * @param  schemas    The schemas root URL, or {@code null} if none.
-     * @param  locale     The locale, or {@code null} if unspecified.
-     * @param  timezone   The timezone, or {@code null} if unspecified.
-     * @param  bitMasks   A combination of {@link #MARSHALLING}, {@link #SUBSTITUTE_LANGUAGE},
-     *                    {@link #SUBSTITUTE_COUNTRY} or other bit masks.
-     */
-    public Context(final ValueConverter converter, final ReferenceResolver resolver,
-            final Version versionGML, final Map<String,String> schemas,
-            final Locale locale, final TimeZone timezone, final int bitMasks)
+     * @param  bitMasks        A combination of {@link #MARSHALLING}, {@code #SUBSTITUTE_*}
or other bit masks.
+     * @param  locale          The locale, or {@code null} if unspecified.
+     * @param  timezone        The timezone, or {@code null} if unspecified.
+     * @param  schemas         The schemas root URL, or {@code null} if none.
+     * @param  versionGML      The GML version, or {@code null}.
+     * @param  resolver        The resolver in use.
+     * @param  converter       The converter in use.
+     * @param  warningListener The object to inform about warnings.
+     */
+    public Context(final int                bitMasks,
+                   final Locale             locale,   final TimeZone       timezone,
+                   final Map<String,String> schemas,  final Version        versionGML,
+                   final ReferenceResolver  resolver, final ValueConverter converter,
+                   final WarningListener<?> warningListener)
     {
-        this.converter  = converter;
-        this.resolver   = resolver;
-        this.versionGML = versionGML;
-        this.schemas    = schemas; // No clone, because this class is internal.
-        this.locale     = locale;
-        this.timezone   = timezone;
-        this.bitMasks   = bitMasks;
+        this.bitMasks        = bitMasks;
+        this.locale          = locale;
+        this.timezone        = timezone;
+        this.schemas         = schemas; // No clone, because this class is internal.
+        this.versionGML      = versionGML;
+        this.resolver        = resolver;
+        this.converter       = converter;
+        this.warningListener = warningListener;
         previous = current();
         CURRENT.set(this);
     }
@@ -160,32 +171,20 @@ public final class Context extends Marsh
      */
     private Context(final Context previous) {
         if (previous != null) {
-            converter  = previous.converter;
-            resolver   = previous.resolver;
-            versionGML = previous.versionGML;
-            schemas    = previous.schemas;
-            locale     = previous.locale;
-            timezone   = previous.timezone;
-            bitMasks   = previous.bitMasks;
+            bitMasks         = previous.bitMasks;
+            locale           = previous.locale;
+            timezone         = previous.timezone;
+            schemas          = previous.schemas;
+            versionGML       = previous.versionGML;
+            resolver         = previous.resolver;
+            converter        = previous.converter;
+            warningListener  = previous.warningListener;
         }
         this.previous = previous;
         CURRENT.set(this);
     }
 
     /**
-     * Returns the schema version of the XML document being (un)marshalled.
-     * See the super-class javadoc for the list of prefix that we shall support.
-     */
-    @Override
-    public final Version getVersion(final String prefix) {
-        if (prefix.equals("gml")) {
-            return versionGML;
-        }
-        // Future SIS versions may add more cases here.
-        return null;
-    }
-
-    /**
      * Returns the locale to use for marshalling, or {@code null} if no locale were explicitly
      * specified.
      */
@@ -203,6 +202,19 @@ public final class Context extends Marsh
         return timezone;
     }
 
+    /**
+     * Returns the schema version of the XML document being (un)marshalled.
+     * See the super-class javadoc for the list of prefix that we shall support.
+     */
+    @Override
+    public final Version getVersion(final String prefix) {
+        if (prefix.equals("gml")) {
+            return versionGML;
+        }
+        // Future SIS versions may add more cases here.
+        return null;
+    }
+
     /*
      * ---- END OF PUBLIC API --------------------------------------------------------------
      *
@@ -250,44 +262,6 @@ public final class Context extends Marsh
     }
 
     /**
-     * Returns the value converter in use for the current marshalling or unmarshalling process.
-     * If no converter were explicitely set, then this method returns {@link ValueConverter#DEFAULT}.
-     *
-     * {@note This method is static for the convenience of performing the check for null
context.}
-     *
-     * @param  context The current context, or {@code null} if none.
-     * @return The current value converter (never null).
-     */
-    public static ValueConverter converter(final Context context) {
-        if (context != null) {
-            final ValueConverter converter = context.converter;
-            if (converter != null) {
-                return converter;
-            }
-        }
-        return ValueConverter.DEFAULT;
-    }
-
-    /**
-     * Returns the reference resolver in use for the current marshalling or unmarshalling
process.
-     * If no resolver were explicitely set, then this method returns {@link ReferenceResolver#DEFAULT}.
-     *
-     * {@note This method is static for the convenience of performing the check for null
context.}
-     *
-     * @param  context The current context, or {@code null} if none.
-     * @return The current reference resolver (never null).
-     */
-    public static ReferenceResolver resolver(final Context context) {
-        if (context != null) {
-            final ReferenceResolver resolver = context.resolver;
-            if (resolver != null) {
-                return resolver;
-            }
-        }
-        return ReferenceResolver.DEFAULT;
-    }
-
-    /**
      * Returns the base URL of ISO 19139 (or other standards) schemas.
      * The valid values are documented in the {@link org.apache.sis.xml.XML#SCHEMAS} property.
      *
@@ -336,6 +310,65 @@ public final class Context extends Marsh
     }
 
     /**
+     * Returns the reference resolver in use for the current marshalling or unmarshalling
process.
+     * If no resolver were explicitely set, then this method returns {@link ReferenceResolver#DEFAULT}.
+     *
+     * {@note This method is static for the convenience of performing the check for null
context.}
+     *
+     * @param  context The current context, or {@code null} if none.
+     * @return The current reference resolver (never null).
+     */
+    public static ReferenceResolver resolver(final Context context) {
+        if (context != null) {
+            final ReferenceResolver resolver = context.resolver;
+            if (resolver != null) {
+                return resolver;
+            }
+        }
+        return ReferenceResolver.DEFAULT;
+    }
+
+    /**
+     * Returns the value converter in use for the current marshalling or unmarshalling process.
+     * If no converter were explicitely set, then this method returns {@link ValueConverter#DEFAULT}.
+     *
+     * {@note This method is static for the convenience of performing the check for null
context.}
+     *
+     * @param  context The current context, or {@code null} if none.
+     * @return The current value converter (never null).
+     */
+    public static ValueConverter converter(final Context context) {
+        if (context != null) {
+            final ValueConverter converter = context.converter;
+            if (converter != null) {
+                return converter;
+            }
+        }
+        return ValueConverter.DEFAULT;
+    }
+
+    /**
+     * Sends the given warning to the warning listener if there is one, or log the warning
otherwise.
+     * The {@link LogRecord#getLoggerName()} <strong>must</strong> be set to
the proper logger name,
+     * because this method relies on that information for fetching the logger.
+     *
+     * @param context The current context, or {@code null} if none.
+     * @param source  The object that emit a warning. Can not be null.
+     * @param warning The warning.
+     */
+    @SuppressWarnings("unchecked")
+    public static void warningOccured(final Context context, final Object source, final LogRecord
warning) {
+        if (context != null) {
+            final WarningListener<?> warningListener = context.warningListener;
+            if (warningListener != null && warningListener.getSourceClass().isInstance(source))
{
+                ((WarningListener) warningListener).warningOccured(source, warning);
+                return;
+            }
+        }
+        Logging.getLogger(warning.getLoggerName()).log(warning);
+    }
+
+    /**
      * Sets the locale to the given value. The old locales are remembered and will
      * be restored by the next call to {@link #pull()}. This method can be invoked
      * when marshalling object that need to marshall their children in a different

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
[UTF-8] Fri Jun 21 10:21:25 2013
@@ -34,7 +34,7 @@ import java.util.logging.LogRecord;
  * The difference between using this listener or configuring the logging {@link java.util.logging.Handler}
is
  * that listeners allow to handle the warnings on a per-{@code DataStore} (or any other emitter)
instance.
  *
- * @param <S> The type of the source of warnings.
+ * @param <S> The base type of objects that emit warnings (the <cite>source</cite>).
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
@@ -46,6 +46,15 @@ import java.util.logging.LogRecord;
  */
 public interface WarningListener<S> extends EventListener {
     /**
+     * Returns the type of objects that emit warnings of interest for this listener.
+     * This is typically, but not necessarily, the class having the name returned by
+     * {@link LogRecord#getSourceClassName()}, or one of its parent classes.
+     *
+     * @return The base type of objects that emit warnings (the <cite>source</cite>).
+     */
+    Class<S> getSourceClass();
+
+    /**
      * Reports the occurrence of a non-fatal error. The emitter process (often a
      * {@link org.apache.sis.storage.DataStore} in the midst of a reading process)
      * will continue following the call to this method.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/MarshalContext.java
[UTF-8] Fri Jun 21 10:21:25 2013
@@ -19,6 +19,7 @@ package org.apache.sis.xml;
 import java.util.Locale;
 import java.util.TimeZone;
 import org.apache.sis.util.Version;
+import org.opengis.util.InternationalString;
 
 
 /**
@@ -37,29 +38,8 @@ public abstract class MarshalContext {
     }
 
     /**
-     * Returns the schema version of the XML document being (un)marshalled.
-     * The {@code prefix} argument can be any of the following values (case-sensitive):
-     *
-     * <table class="sis">
-     *   <tr>
-     *     <th>Prefix</th>
-     *     <th>Standard</th>
-     *     <th>Typical values</th>
-     *   </tr>
-     *   <tr>
-     *     <td>gml</td> <td>Geographic Markup Language</td> <td>{@code
3.0}, {@code 3.2}</td>
-     *   </tr>
-     * </table>
-     *
-     * @param  prefix One of the above-cited prefix.
-     * @return The version for the given schema, or {@code null} if unknown.
-     */
-    public abstract Version getVersion(final String prefix);
-
-    /**
-     * 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}.
+     * 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
InternationalString}.
      *
      * <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
@@ -82,8 +62,7 @@ public abstract class MarshalContext {
     public abstract Locale getLocale();
 
     /**
-     * Returns the timezone to use for (un)marshalling, or {@code null} if none were explicitely
-     * specified.
+     * Returns the timezone to use for (un)marshalling, or {@code null} if none were explicitely
specified.
      *
      * {@section Handling of <code>null</code> timezone}
      * A {@code null} value means that the timezone is unspecified. Callers are encouraged
@@ -92,4 +71,24 @@ public abstract class MarshalContext {
      * @return The timezone for the XML fragment being (un)marshalled, or {@code null} if
unspecified.
      */
     public abstract TimeZone getTimeZone();
+
+    /**
+     * Returns the schema version of the XML document being (un)marshalled.
+     * The {@code prefix} argument can be any of the following values (case-sensitive):
+     *
+     * <table class="sis">
+     *   <tr>
+     *     <th>Prefix</th>
+     *     <th>Standard</th>
+     *     <th>Typical values</th>
+     *   </tr>
+     *   <tr>
+     *     <td>gml</td> <td>Geographic Markup Language</td> <td>{@code
3.0}, {@code 3.2}</td>
+     *   </tr>
+     * </table>
+     *
+     * @param  prefix One of the above-cited prefix.
+     * @return The version for the given schema, or {@code null} if unknown.
+     */
+    public abstract Version getVersion(final String prefix);
 }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java [UTF-8]
(original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java [UTF-8]
Fri Jun 21 10:21:25 2013
@@ -29,8 +29,10 @@ import javax.xml.bind.PropertyException;
 import javax.xml.bind.ValidationEventHandler;
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import org.apache.sis.util.Version;
+import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.logging.WarningListener;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.jaxb.Context;
 
@@ -87,22 +89,23 @@ abstract class Pooled {
     private final Map<Object,Object> initialProperties;
 
     /**
-     * The object converters to use during (un)marshalling.
-     * Can be set by the {@link XML#CONVERTER} property.
+     * Bit masks for various boolean attributes. This include whatever the language codes
+     * or the country codes should be substituted by a simpler character string elements.
+     * Those bits are determined by the {@link XML#STRING_SUBSTITUTES} property.
      */
-    private ValueConverter converter;
+    private int bitMasks;
 
     /**
-     * The reference resolver to use during unmarshalling.
-     * Can be set by the {@link XML#RESOLVER} property.
+     * An optional locale for {@link org.opengis.util.InternationalString} and
+     * {@link org.opengis.util.CodeList}. Can be set by the {@link XML#LOCALE} property.
      */
-    private ReferenceResolver resolver;
+    private Locale locale;
 
     /**
-     * The GML version to be marshalled or unmarshalled, or {@code null} if unspecified.
-     * If null, then the latest version is assumed.
+     * The timezone, or {@code null} if unspecified.
+     *  Can be set by the {@link XML#TIMEZONE} property.
      */
-    private Version gmlVersion;
+    private TimeZone timezone;
 
     /**
      * The base URL of ISO 19139 (or other standards) schemas. It shall be an unmodifiable
@@ -112,23 +115,27 @@ abstract class Pooled {
     private Map<String,String> schemas;
 
     /**
-     * An optional locale for {@link org.opengis.util.InternationalString} and
-     * {@link org.opengis.util.CodeList}. Can be set by the {@link XML#LOCALE} property.
+     * The GML version to be marshalled or unmarshalled, or {@code null} if unspecified.
+     * If null, then the latest version is assumed.
      */
-    private Locale locale;
+    private Version gmlVersion;
 
     /**
-     * The timezone, or {@code null} if unspecified.
-     *  Can be set by the {@link XML#TIMEZONE} property.
+     * The reference resolver to use during unmarshalling.
+     * Can be set by the {@link XML#RESOLVER} property.
      */
-    private TimeZone timezone;
+    private ReferenceResolver resolver;
 
     /**
-     * Bit masks for various boolean attributes. This include whatever the language codes
-     * or the country codes should be substituted by a simpler character string elements.
-     * Those bits are determined by the {@link XML#STRING_SUBSTITUTES} property.
+     * The object converters to use during (un)marshalling.
+     * Can be set by the {@link XML#CONVERTER} property.
      */
-    private int bitMasks;
+    private ValueConverter converter;
+
+    /**
+     * The object to inform about warnings, or {@code null} if none.
+     */
+    private WarningListener<?> warningListener;
 
     /**
      * The {@link System#nanoTime()} value of the last call to {@link #reset()}.
@@ -170,14 +177,15 @@ abstract class Pooled {
             reset(entry.getKey(), entry.getValue());
         }
         initialProperties.clear();
-        converter  = null;
-        resolver   = null;
-        gmlVersion = null;
-        schemas    = null;
-        locale     = null;
-        timezone   = null;
-        bitMasks   = initialBitMasks();
-        resetTime  = System.nanoTime();
+        bitMasks        = initialBitMasks();
+        locale          = null;
+        timezone        = null;
+        schemas         = null;
+        gmlVersion      = null;
+        resolver        = null;
+        converter       = null;
+        warningListener = null;
+        resetTime       = System.nanoTime();
     }
 
     /**
@@ -241,12 +249,12 @@ abstract class Pooled {
     public final void setProperty(String name, final Object value) throws PropertyException
{
         try {
             switch (name) {
-                case XML.CONVERTER: {
-                    converter = (ValueConverter) value;
+                case XML.LOCALE: {
+                    locale = (Locale) value;
                     return;
                 }
-                case XML.RESOLVER: {
-                    resolver = (ReferenceResolver) value;
+                case XML.TIMEZONE: {
+                    timezone = (TimeZone) value;
                     return;
                 }
                 case XML.SCHEMAS: {
@@ -273,19 +281,18 @@ abstract class Pooled {
                     gmlVersion = (value instanceof CharSequence) ? new Version(value.toString())
: (Version) value;
                     return;
                 }
-                case XML.LOCALE: {
-                    locale = (Locale) value;
+                case XML.RESOLVER: {
+                    resolver = (ReferenceResolver) value;
                     return;
                 }
-                case XML.TIMEZONE: {
-                    timezone = (TimeZone) value;
+                case XML.CONVERTER: {
+                    converter = (ValueConverter) value;
                     return;
                 }
                 case XML.STRING_SUBSTITUTES: {
                     int mask = initialBitMasks();
-                    final CharSequence[] substitutes = CharSequences.split((CharSequence)
value, ',');
-                    if (substitutes != null) {
-                        for (final CharSequence substitute : substitutes) {
+                    if (value != null) {
+                        for (final CharSequence substitute : (CharSequence[]) value) {
                             if (CharSequences.equalsIgnoreCase(substitute, "language")) {
                                 mask |= Context.SUBSTITUTE_LANGUAGE;
                             } else if (CharSequences.equalsIgnoreCase(substitute, "country"))
{
@@ -296,6 +303,10 @@ abstract class Pooled {
                     bitMasks = mask;
                     return;
                 }
+                case XML.WARNING_LISTENER: {
+                    warningListener = (WarningListener<?>) value;
+                    return;
+                }
             }
         } catch (ClassCastException e) {
             throw new PropertyException(Errors.format(
@@ -316,22 +327,19 @@ abstract class Pooled {
      */
     public final Object getProperty(final String name) throws PropertyException {
         switch (name) {
-            case XML.CONVERTER:   return converter;
-            case XML.RESOLVER:    return resolver;
-            case XML.SCHEMAS:     return schemas;
-            case XML.GML_VERSION: return gmlVersion;
-            case XML.LOCALE:      return locale;
-            case XML.TIMEZONE:    return timezone;
+            case XML.LOCALE:           return locale;
+            case XML.TIMEZONE:         return timezone;
+            case XML.SCHEMAS:          return schemas;
+            case XML.GML_VERSION:      return gmlVersion;
+            case XML.RESOLVER:         return resolver;
+            case XML.CONVERTER:        return converter;
+            case XML.WARNING_LISTENER: return warningListener;
             case XML.STRING_SUBSTITUTES: {
-                final StringBuilder buffer = new StringBuilder();
-                if ((bitMasks & Context.SUBSTITUTE_LANGUAGE) != 0) buffer.append("language,");
-                if ((bitMasks & Context.SUBSTITUTE_COUNTRY)  != 0) buffer.append("country,");
-                final int length = buffer.length();
-                if (length != 0) {
-                    buffer.setLength(length - 1); // Remove the last coma.
-                    return buffer.toString();
-                }
-                return null;
+                int n = 0;
+                final String[] substitutes = new String[2];
+                if ((bitMasks & Context.SUBSTITUTE_LANGUAGE) != 0) substitutes[n++] =
"language";
+                if ((bitMasks & Context.SUBSTITUTE_COUNTRY)  != 0) substitutes[n++] =
"country";
+                return ArraysExt.resize(substitutes, n);
             }
             default: {
                 return getStandardProperty(convertPropertyKey(name));
@@ -428,6 +436,6 @@ abstract class Pooled {
      * @see Context#finish();
      */
     final Context begin() {
-        return new Context(converter, resolver, gmlVersion, schemas, locale, timezone, bitMasks);
+        return new Context(bitMasks, locale, timezone, schemas, gmlVersion, resolver, converter,
warningListener);
     }
 }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java [UTF-8] Fri
Jun 21 10:21:25 2013
@@ -16,7 +16,10 @@
  */
 package org.apache.sis.xml;
 
+import java.util.Map;
 import java.util.Locale;
+import java.util.TimeZone;
+import java.util.logging.LogRecord; // For javadoc
 import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -26,6 +29,8 @@ import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.JAXBException;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.Version;
+import org.apache.sis.util.logging.WarningListener;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.jaxb.TypeRegistration;
@@ -36,15 +41,18 @@ import org.apache.sis.internal.jaxb.Type
  * This class defines also some property keys that can be given to the {@link Marshaller}
  * and {@link Unmarshaller} instances created by {@link PooledMarshaller}:
  *
- * <ul>
- *   <li>{@link #LOCALE} for specifying the locale to use for international strings
and code lists.</li>
- *   <li>{@link #TIMEZONE} for specifying the timezone to use for dates and times.</li>
- *   <li>{@link #SCHEMAS} for specifying the root URL of metadata schemas to use.</li>
- *   <li>{@link #DEFAULT_NAMESPACE} for specifying the default namespace of the XML
document to write.</li>
- *   <li>{@link #RESOLVER} for replacing {@code xlink} or {@code uuidref} attributes
by the actual object to use.</li>
- *   <li>{@link #CONVERTER} for controlling the conversion of URL, UUID, Units or similar
objects.</li>
- *   <li>{@link #STRING_SUBSTITUTES} for specifying which code lists to replace by
simpler {@code <gco:CharacterString>} elements.</li>
- * </ul>
+ * <table class="sis">
+ *   <tr><th>Key</th>                         <th>Value type</th>
               <th>Purpose</th></tr>
+ *   <tr><td>{@link #LOCALE}</td>             <td>{@link Locale}</td>
           <td>for specifying the locale to use for international strings and code lists.</td></tr>
+ *   <tr><td>{@link #TIMEZONE}</td>           <td>{@link TimeZone}</td>
         <td>for specifying the timezone to use for dates and times.</td></tr>
+ *   <tr><td>{@link #SCHEMAS}</td>            <td>{@link Map}</td>
              <td>for specifying the root URL of metadata schemas to use.</td></tr>
+ *   <tr><td>{@link #DEFAULT_NAMESPACE}</td>  <td>{@link String}</td>
           <td>for specifying the default namespace of the XML document to write.</td></tr>
+ *   <tr><td>{@link #GML_VERSION}</td>        <td>{@link Version}</td>
          <td>for specifying the GML version to the document be (un)marshalled.</td></tr>
+ *   <tr><td>{@link #RESOLVER}</td>           <td>{@link ReferenceResolver}</td>
<td>for replacing {@code xlink} or {@code uuidref} attributes by the actual object to
use.</td></tr>
+ *   <tr><td>{@link #CONVERTER}</td>          <td>{@link ValueConverter}</td>
   <td>for controlling the conversion of URL, UUID, Units or similar objects.</td></tr>
+ *   <tr><td>{@link #STRING_SUBSTITUTES}</td> <td>{@code String[]}</td>
         <td>for specifying which code lists to replace by simpler {@code <gco:CharacterString>}
elements.</td></tr>
+ *   <tr><td>{@link #WARNING_LISTENER}</td>   <td>{@link WarningListener}</td>
  <td>for being notified about non-fatal warnings.</td></tr>
+ * </table>
  *
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
@@ -88,13 +96,13 @@ public final class XML extends Static {
      *
      * {@section Default behavior}
      * If this property is never set, then (un)marshalling will use the
-     * {@linkplain java.util.TimeZone#getDefault() default timezone}.
+     * {@linkplain TimeZone#getDefault() default timezone}.
      */
     public static final String TIMEZONE = "org.apache.sis.xml.timezone";
 
     /**
      * Specifies the root URL of schemas. The value for this property shall
-     * be an instance of {@link java.util.Map Map&lt;String,String&gt;}.
+     * be an instance of {@link Map Map&lt;String,String&gt;}.
      * This property controls the URL to be used when marshalling the following elements:
      *
      * <ul>
@@ -133,12 +141,13 @@ public final class XML extends Static {
     public static final String DEFAULT_NAMESPACE = "org.apache.sis.xml.defaultNamespace";
 
     /**
-     * Specifies the GML version to be marshalled or unmarshalled. The GML version may affect
the
-     * set of XML elements to be marshalled. Newer versions typically have more elements,
but not
-     * always. For example in {@code gml:VerticalDatum}, the {@code gml:verticalDatumType}
property
+     * Specifies the GML version of the document to be marshalled or unmarshalled.
+     * The GML version may affect the set of XML elements to be marshalled.
+     * Newer versions typically have more elements, but not always.
+     * For example in {@code gml:VerticalDatum}, the {@code gml:verticalDatumType} property
      * presents in GML 3.0 and 3.1 has been removed in GML 3.2.
      *
-     * <p>The value can be {@link String} or {@link org.apache.sis.util.Version} objects.
+     * <p>The value can be {@link String} or {@link Version} objects.
      * If no version is specified, then the most recent GML version is assumed.</p>
      */
     public static final String GML_VERSION = "org.apache.sis.gml.version";
@@ -219,9 +228,13 @@ public final class XML extends Static {
     public static final String CONVERTER = "org.apache.sis.xml.converter";
 
     /**
-     * Allows marshallers to substitute some code lists by the simpler {@code <gco:CharacterString>}
-     * element. The value for this property shall be a coma-separated list of any of the
following
-     * values: "{@code language}", "{@code country}".
+     * Allows marshallers to substitute some code lists by the simpler {@code <gco:CharacterString>}
element.
+     * The value for this property shall be a {@code String[]} array of any of the following
values:
+     *
+     * <ul>
+     *   <li>"{@code language}"</li>
+     *   <li>"{@code country}"</li>
+     * </ul>
      *
      * {@section Example}
      * INSPIRE compliant language code shall be formatted like below (formatting may vary):
@@ -247,6 +260,18 @@ public final class XML extends Static {
     public static final String STRING_SUBSTITUTES = "org.apache.sis.xml.stringSubstitutes";
 
     /**
+     * Specifies a listener to be notified when a non-fatal error occurred during the (un)marshalling.
+     * The value for this property shall be an instance of {@code WarningListener<Object>}.
+     *
+     * <p>By default, warnings that occur during the (un)marshalling process are logged.
However if a
+     * property is set for this key, then the {@link WarningListener#warningOccured(Object,
LogRecord)}
+     * method will be invoked and the warning will <em>not</em> be logged by
the (un)marshaller.</p>
+     *
+     * @see WarningListener
+     */
+    public static final String WARNING_LISTENER = "org.apache.sis.xml.warningListener";
+
+    /**
      * The pool of marshallers and unmarshallers used by this class.
      * The field name uses the uppercase convention because this field is almost constant:
      * this field is initially null, then created by {@link #getPool()} when first needed.

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/logging/WarningListenersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/logging/WarningListenersTest.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/logging/WarningListenersTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/logging/WarningListenersTest.java
[UTF-8] Fri Jun 21 10:21:25 2013
@@ -53,6 +53,14 @@ public final strictfp class WarningListe
     }
 
     /**
+     * Returns the type warning sources.
+     */
+    @Override
+    public Class<String> getSourceClass() {
+        return String.class;
+    }
+
+    /**
      * Invoked when a warning occurred. The implementation in this test verifies that the
{@code source} argument has
      * the expected values, then stores the log record in the {@link #warning} field for
inspection by the test method.
      */

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/ReferenceResolverMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/ReferenceResolverMock.java?rev=1495368&r1=1495367&r2=1495368&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/ReferenceResolverMock.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/ReferenceResolverMock.java
[UTF-8] Fri Jun 21 10:21:25 2013
@@ -54,8 +54,8 @@ public final strictfp class ReferenceRes
      * @return The (un)marshalling context.
      */
     public static Context begin(final boolean marshalling) {
-        return new Context(null, new ReferenceResolverMock(), null, null, null, null,
-                marshalling ? Context.MARSHALLING : 0);
+        return new Context(marshalling ? Context.MARSHALLING : 0, null, null, null, null,
+                new ReferenceResolverMock(), null, null);
     }
 
     /**



Mime
View raw message