sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1424365 - in /sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis: util/resources/ xml/
Date Thu, 20 Dec 2012 08:27:02 GMT
Author: desruisseaux
Date: Thu Dec 20 08:27:01 2012
New Revision: 1424365

URL: http://svn.apache.org/viewvc?rev=1424365&view=rev
Log:
Port of Pooled[Un]Marshaller.
They will be used by MarshallerPool (to be comitted later).

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java   (with props)
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java   (with props)
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java   (with props)
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/XML.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1424365&r1=1424364&r2=1424365&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java Thu Dec 20 08:27:01 2012
@@ -151,6 +151,11 @@ public final class Errors extends Indexe
         public static final int IllegalLanguageCode_1 = 12;
 
         /**
+         * Property ‘{0}’ can be associated to an instance of ‘{1}’.
+         */
+        public static final int IllegalPropertyClass_2 = 62;
+
+        /**
          * Range [{0} … {1}] is not valid.
          */
         public static final int IllegalRange_2 = 11;

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1424365&r1=1424364&r2=1424365&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties Thu Dec 20 08:27:01 2012
@@ -32,6 +32,7 @@ IllegalBitsPattern_1            = Illega
 IllegalClass_2                  = Class \u2018{0}\u2019 is illegal. It must be \u2018{1}\u2019 or a derived class.
 IllegalFormatPatternForClass_2  = The \u201c{0}\u201d pattern can not be applied to formating of objects of type \u2018{1}\u2019.
 IllegalLanguageCode_1           = The \u201c{0}\u201d language is not recognized.
+IllegalPropertyClass_2          = Property \u2018{0}\u2019 can be associated to an instance of \u2018{1}\u2019.
 IllegalRange_2                  = Range [{0} \u2026 {1}] is not valid.
 InconsistentAttribute_2         = Value \u201c{1}\u201d of attribute \u2018{0}\u2019 is inconsistent with other attributes.
 InconsistentTableColumns        = Inconsistent table columns.

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1424365&r1=1424364&r2=1424365&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties Thu Dec 20 08:27:01 2012
@@ -32,6 +32,7 @@ IllegalBitsPattern_1            = Patter
 IllegalClass_2                  = La classe \u2018{0}\u2019 est ill\u00e9gale. Il doit s\u2019agir d\u2019une classe \u2018{1}\u2019 ou d\u00e9riv\u00e9e.
 IllegalFormatPatternForClass_2  = Le mod\u00e8le \u201c{0}\u201d ne peut pas \u00eatre appliqu\u00e9 au formatage d\u2019objets de type \u2018{1}\u2019.
 IllegalLanguageCode_1           = Le code de langue \u201c{0}\u201d n\u2019est pas reconnu.
+IllegalPropertyClass_2          = La propri\u00e9t\u00e9 \u2018{0}\u2019 ne peut pas \u00eatre associ\u00e9e \u00e0 une valeur de type \u2018{1}\u2019.
 IllegalRange_2                  = La plage [{0} \u2026 {1}] n\u2019est pas valide.
 InconsistentAttribute_2         = La valeur \u201c{1}\u201d de l\u2019attribut \u2018{0}\u2019 n\u2019est pas coh\u00e9rente avec celles des autres attributs.
 InconsistentTableColumns        = Les colonnes des tables ne sont pas coh\u00e9rentes.

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java?rev=1424365&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java (added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java Thu Dec 20 08:27:01 2012
@@ -0,0 +1,424 @@
+/*
+ * 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.xml;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.ConcurrentModificationException;
+import java.util.Locale;
+import java.util.TimeZone;
+import javax.xml.validation.Schema;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.JAXBException;
+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.CharSequences;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.jaxb.MarshalContext;
+
+import static org.apache.sis.util.collection.Collections.unmodifiableOrCopy;
+
+
+/**
+ * Base class of {@link PooledMarshaller} and {@link PooledUnmarshaller}.
+ * This class provides basic service for saving the initial values of (un)marshaller properties,
+ * in order to reset them to their initial values after usage. This is required in order to allow
+ * (un)marshaller reuse. In addition this base class translates properties key from JDK 6 names to
+ * "endorsed JAR" names if needed.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+abstract class Pooled {
+    /**
+     * The keys of entries that can be stored in the {@link #schemas} map.
+     * Those keys are documented in {@link XML#SCHEMAS}.
+     */
+    private static final String[] SCHEMA_KEYS = {"gmd"};
+
+    /**
+     * The prefix of property names which are provided in external (endorsed) implementation of JAXB.
+     * This is slightly different than the prefix used by the implementation bundled with the JDK 6,
+     * which is {@code "com.sun.xml.internal.bind"}.
+     *
+     * @see #convertPropertyKey(String)
+     */
+    private static final String ENDORSED_PREFIX = "com.sun.xml.bind.";
+
+    /**
+     * {@code true} if the JAXB implementation is the one bundled in JDK 6, or {@code false}
+     * if this is the external implementation provided as a JAR file in the endorsed directory.
+     * If {@code true}, then an additional {@code "internal"} package name needs to be inserted
+     * in the property keys.
+     *
+     * @see #convertPropertyKey(String)
+     */
+    private final boolean internal;
+
+    /**
+     * The initial state of the (un)marshaller. Will be filled only as needed,
+     * often with null values (which must be supported by the map implementation).
+     *
+     * <ul>
+     *   <li>For each entry having a key of type {@link Class}, the value is the argument
+     *       to be given to a {@code marshaller.setFoo(value)} method.</li>
+     *   <li>For each entry having a key of type {@link String}, the value is the argument
+     *       to be given to the {@code marshaller.setProperty(key, value)} method.</li>
+     * </ul>
+     */
+    private final Map<Object,Object> initialProperties;
+
+    /**
+     * The object converters to use during (un)marshalling.
+     * Can be set by the {@link XML#CONVERTER} property.
+     */
+    private ValueConverter converter;
+
+    /**
+     * The reference resolver to use during unmarshalling.
+     * Can be set by the {@link XML#RESOLVER} property.
+     */
+    private ReferenceResolver resolver;
+
+    /**
+     * The GML version to be marshalled or unmarshalled, or {@code null} if unspecified.
+     * If null, then the latest version is assumed.
+     */
+    private Version gmlVersion;
+
+    /**
+     * The base URL of ISO 19139 (or other standards) schemas. It shall be an unmodifiable
+     * instance because {@link #getProperty(String)} returns a direct reference to the user.
+     * The valid values are documented in the {@link XML#SCHEMAS} property.
+     */
+    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.
+     */
+    private Locale locale;
+
+    /**
+     * The timezone, or {@code null} if unspecified.
+     *  Can be set by the {@link XML#TIMEZONE} property.
+     */
+    private TimeZone timezone;
+
+    /**
+     * 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 int bitMasks;
+
+    /**
+     * Default constructor.
+     *
+     * @param internal {@code true} if the JAXB implementation is the one bundled in JDK 6,
+     *        or {@code false} if this is the external implementation provided as a JAR file
+     *        in the endorsed directory.
+     */
+    Pooled(final boolean internal) {
+        this.internal = internal;
+        initialProperties = new LinkedHashMap<>();
+        bitMasks = initialBitMasks();
+    }
+
+    /**
+     * Returns the initial value of {@link MarshalContext#bitMasks}. Shall be 0 if this object is
+     * an unmarshaller, or {@link MarshalContext#MARSHALING} if it is an {@link Unmarshaller}.
+     */
+    private int initialBitMasks() {
+        return (this instanceof Marshaller) ? MarshalContext.MARSHALING : 0;
+    }
+
+    /**
+     * Resets the (un)marshaller to its initial state.
+     *
+     * @throws JAXBException If an error occurred while restoring a property.
+     */
+    public final void reset() throws JAXBException {
+        for (final Map.Entry<Object,Object> entry : initialProperties.entrySet()) {
+            reset(entry.getKey(), entry.getValue());
+        }
+        initialProperties.clear();
+        converter  = null;
+        resolver   = null;
+        gmlVersion = null;
+        schemas    = null;
+        locale     = null;
+        timezone   = null;
+        bitMasks   = initialBitMasks();
+    }
+
+    /**
+     * Resets the given marshaller property to its initial state. This method is invoked
+     * automatically by the {@link #reset()} method. The key is either a {@link String}
+     * or a {@link Class}. If this is a string, then the value shall be given to the
+     * {@code setProperty(key, value)} method. Otherwise the value shall be given to
+     * {@code setFoo(value)} method where {@code "Foo"} is determined from the key.
+     *
+     * @param  key   The property to reset.
+     * @param  value The initial value to give to the property.
+     * @throws JAXBException If an error occurred while restoring a property.
+     */
+    protected abstract void reset(final Object key, final Object value) throws JAXBException;
+
+    /**
+     * Returns {@code true} if the initial property is already saved for the given key.
+     * Note that a property set to {@code null} is still considered as defined.
+     */
+    final boolean isPropertySaved(final Class<?> key) {
+        return initialProperties.containsKey(key);
+    }
+
+    /**
+     * Saves the current value of a property. This method is invoked before a value is
+     * modified for the first time, in order to allow {@link #reset()} to restore the
+     * (un)marshaller to its initial state.
+     *
+     * @param type  The property to save.
+     * @param value The current value of the property.
+     */
+    final <E> void saveProperty(final Class<E> type, final E value) {
+        if (initialProperties.put(type, value) != null) {
+            // Should never happen, unless on concurrent changes in a backgroung thread.
+            throw new ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1,
+                    type.getInterfaces()[0].getSimpleName() + ".get" + type.getSimpleName()));
+        }
+    }
+
+    /**
+     * Converts a property key from the JAXB name to the underlying implementation name.
+     * This applies only to property keys in the {@code "com.sun.xml.bind"} namespace.
+     *
+     * @param  key The JAXB property key.
+     * @return The property key to use.
+     */
+    private String convertPropertyKey(String key) {
+        if (internal && key.startsWith(ENDORSED_PREFIX)) {
+            final StringBuilder buffer = new StringBuilder(key.length() + 10);
+            key = buffer.append("com.sun.xml.internal.bind.")
+                    .append(key, ENDORSED_PREFIX.length(), key.length()).toString();
+        }
+        return key;
+    }
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     * It saves the initial state if it was not already done, but subclasses will
+     * need to complete the work.
+     */
+    public final void setProperty(String name, final Object value) throws PropertyException {
+        try {
+            switch (name) {
+                case XML.CONVERTER: {
+                    converter = (ValueConverter) value;
+                    return;
+                }
+                case XML.RESOLVER: {
+                    resolver = (ReferenceResolver) value;
+                    return;
+                }
+                case XML.SCHEMAS: {
+                    final Map<?,?> map = (Map<?,?>) value;
+                    Map<String,String> copy = null;
+                    if (map != null) {
+                        copy = new HashMap<>(4);
+                        for (final String key : SCHEMA_KEYS) {
+                            final Object schema = map.get(key);
+                            if (schema != null) {
+                                if (!(schema instanceof String)) {
+                                    throw new PropertyException(Errors.format(Errors.Keys.IllegalPropertyClass_2,
+                                            name + "[\"" + key + "\"]", value.getClass()));
+                                }
+                                copy.put(key, (String) schema);
+                            }
+                        }
+                        copy = unmodifiableOrCopy(copy);
+                    }
+                    schemas = copy;
+                    return;
+                }
+                case XML.GML_VERSION: {
+                    gmlVersion = (value instanceof CharSequence) ? new Version(value.toString()) : (Version) value;
+                    return;
+                }
+                case XML.LOCALE: {
+                    locale = (Locale) value;
+                    return;
+                }
+                case XML.TIMEZONE: {
+                    timezone = (TimeZone) 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 (CharSequences.equalsIgnoreCase(substitute, "language")) {
+                                mask |= MarshalContext.SUBSTITUTE_LANGUAGE;
+                            } else if (CharSequences.equalsIgnoreCase(substitute, "country")) {
+                                mask |= MarshalContext.SUBSTITUTE_COUNTRY;
+                            }
+                        }
+                    }
+                    bitMasks = mask;
+                    return;
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new PropertyException(Errors.format(
+                    Errors.Keys.IllegalPropertyClass_2, name, value.getClass()), e);
+        }
+        name = convertPropertyKey(name);
+        if (!initialProperties.containsKey(name)) {
+            if (initialProperties.put(name, getStandardProperty(name)) != null) {
+                // Should never happen, unless on concurrent changes in a backgroung thread.
+                throw new ConcurrentModificationException(name);
+            }
+        }
+        setStandardProperty(name, value);
+    }
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     */
+    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.STRING_SUBSTITUTES: {
+                final StringBuilder buffer = new StringBuilder();
+                if ((bitMasks & MarshalContext.SUBSTITUTE_LANGUAGE) != 0) buffer.append("language,");
+                if ((bitMasks & MarshalContext.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;
+            }
+            default: {
+                return getStandardProperty(convertPropertyKey(name));
+            }
+        }
+    }
+
+    /**
+     * Sets the given property to the wrapped (un)marshaller. This method is invoked
+     * automatically when the property given to the {@link #setProperty(String, Object)}
+     * method was not one of the {@link XML} constants.
+     */
+    abstract void setStandardProperty(String name, Object value) throws PropertyException;
+
+    /**
+     * Gets the given property from the wrapped (un)marshaller. This method is invoked
+     * automatically when the property key given to the {@link #getProperty(String)}
+     * method was not one of the {@link XML} constants.
+     */
+    abstract Object getStandardProperty(String name) throws PropertyException;
+
+    /**
+     * Delegates to {@code setAdapter(adapter.getClass(), adapter)} as specified
+     * in {@code [Un]Marshaller} javadoc.
+     */
+    @SuppressWarnings({"unchecked","rawtypes"})
+    public final void setAdapter(final XmlAdapter adapter) {
+        setAdapter((Class) adapter.getClass(), adapter);
+    }
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     * It saves the initial state if it was not already done, but subclasses will
+     * need to complete the work.
+     */
+    @SuppressWarnings("rawtypes")
+    public <A extends XmlAdapter> void setAdapter(final Class<A> type, final A adapter) {
+        if (!isPropertySaved(type)) {
+            saveProperty(type, getAdapter(type));
+        }
+    }
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     */
+    @SuppressWarnings("rawtypes")
+    public abstract <A extends XmlAdapter> A getAdapter(final Class<A> type);
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     * It saves the initial state if it was not already done, but subclasses will
+     * need to complete the work.
+     */
+    public void setSchema(final Schema schema) {
+        if (!isPropertySaved(Schema.class)) {
+            saveProperty(Schema.class, getSchema());
+        }
+    }
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     */
+    public abstract Schema getSchema();
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     * It saves the initial state if it was not already done, but subclasses will
+     * need to complete the work.
+     */
+    public void setEventHandler(final ValidationEventHandler handler) throws JAXBException {
+        if (!initialProperties.containsKey(ValidationEventHandler.class)) {
+            saveProperty(ValidationEventHandler.class, getEventHandler());
+        }
+    }
+
+    /**
+     * A method which is common to both {@code Marshaller} and {@code Unmarshaller}.
+     */
+    public abstract ValidationEventHandler getEventHandler() throws JAXBException;
+
+    /**
+     * Must be invoked by subclasses before a {@code try} block performing a (un)marshalling
+     * operation. Must be followed by a call to {@code finish()} in a {@code finally} block.
+     *
+     * {@preformat java
+     *     MarshalContext context = begin();
+     *     try {
+     *         ...
+     *     } finally {
+     *         context.finish();
+     *     }
+     * }
+     *
+     * @see MarshalContext#finish();
+     */
+    final MarshalContext begin() {
+        return new MarshalContext(converter, resolver, gmlVersion, schemas, locale, timezone, bitMasks);
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java?rev=1424365&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java (added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java Thu Dec 20 08:27:01 2012
@@ -0,0 +1,334 @@
+/*
+ * 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.xml;
+
+import java.io.File;
+import java.io.Writer;
+import java.io.OutputStream;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.PropertyException;
+import javax.xml.bind.ValidationEventHandler;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.attachment.AttachmentMarshaller;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.validation.Schema;
+import org.xml.sax.ContentHandler;
+import org.w3c.dom.Node;
+import org.apache.sis.util.Decorator;
+import org.apache.sis.internal.jaxb.MarshalContext;
+
+
+/**
+ * Wraps a {@link Marshaller} in order to have some control on the modifications applied on it.
+ * This wrapper serves two purpose:
+ *
+ * <ul>
+ *   <li>Save properties before modification, in order to restore them to their original values
+ *       when the marshaller is recycled.</li>
+ *   <li>Constructs a SIS {@link MarshalContext} object on marshalling, in order to give
+ *       additional information to the SIS object being marshalled.</li>
+ * </ul>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+@Decorator(Marshaller.class)
+final class PooledMarshaller extends Pooled implements Marshaller {
+    /**
+     * The wrapper marshaller which does the real work.
+     */
+    private final Marshaller marshaller;
+
+    /**
+     * Creates a pooled marshaller wrapping the given one.
+     *
+     * @param marshaller The marshaller to use for the actual work.
+     * @param internal {@code true} if the JAXB implementation is the one bundled in JDK 6,
+     *        or {@code false} if this is the external implementation provided as a JAR file
+     *        in the endorsed directory.
+     */
+    PooledMarshaller(final Marshaller marshaller, final boolean internal) {
+        super(internal);
+        this.marshaller = marshaller;
+    }
+
+    /**
+     * Resets the given marshaller property to its initial state.
+     * This method is invoked automatically by {@link #reset()}.
+     *
+     * @param  key   The property to reset.
+     * @param  value The saved initial value to give to the property.
+     * @throws JAXBException If an error occurred while restoring a property.
+     */
+    @Override
+    @SuppressWarnings({"unchecked","rawtypes"})
+    protected void reset(final Object key, Object value) throws JAXBException {
+        if (key instanceof String) {
+            final String k = (String) key;
+            if (value == null && (k.endsWith(".xmlHeaders") || k.equals(JAXB_SCHEMA_LOCATION))) {
+                value = ""; // Null value doesn't seem to be accepted.
+            }
+            marshaller.setProperty(k, value);
+        } else if (key == AttachmentMarshaller.class) {
+            marshaller.setAttachmentMarshaller((AttachmentMarshaller) value);
+        } else if (key == Schema.class) {
+            marshaller.setSchema((Schema) value);
+        } else if (key == Listener.class) {
+            marshaller.setListener((Listener) value);
+        } else if (key == ValidationEventHandler.class) {
+            marshaller.setEventHandler((ValidationEventHandler) value);
+        } else {
+            marshaller.setAdapter((Class) key, (XmlAdapter) value);
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final Result output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final OutputStream output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final File output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final Writer output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final ContentHandler output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final Node output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final XMLStreamWriter output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public void marshal(final Object object, final XMLEventWriter output) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            marshaller.marshal(object, output);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the marshalling to the wrapped marshaller.
+     */
+    @Override
+    public Node getNode(final Object object) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return marshaller.getNode(object);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. This method is invoked by the parent
+     * class if the given name was not one of the {@link XML} constants.
+     */
+    @Override
+    void setStandardProperty(final String name, final Object value) throws PropertyException {
+        marshaller.setProperty(name, value);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. This method is invoked by the parent
+     * class if the given name was not one of the {@link XML} constants.
+     */
+    @Override
+    Object getStandardProperty(final String name) throws PropertyException {
+        return marshaller.getProperty(name);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public <A extends XmlAdapter> void setAdapter(final Class<A> type, final A adapter) {
+        super.setAdapter(type, adapter);
+        marshaller.setAdapter(type, adapter);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller.
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public <A extends XmlAdapter> A getAdapter(final Class<A> type) {
+        return marshaller.getAdapter(type);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setSchema(final Schema schema) {
+        super.setSchema(schema);
+        marshaller.setSchema(schema);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller.
+     */
+    @Override
+    public Schema getSchema() {
+        return marshaller.getSchema();
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setEventHandler(final ValidationEventHandler handler) throws JAXBException {
+        super.setEventHandler(handler);
+        marshaller.setEventHandler(handler);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller.
+     */
+    @Override
+    public ValidationEventHandler getEventHandler() throws JAXBException {
+        return marshaller.getEventHandler();
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setAttachmentMarshaller(final AttachmentMarshaller am) {
+        if (!isPropertySaved(AttachmentMarshaller.class)) {
+            saveProperty(AttachmentMarshaller.class, marshaller.getAttachmentMarshaller());
+        }
+        marshaller.setAttachmentMarshaller(am);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller.
+     */
+    @Override
+    public AttachmentMarshaller getAttachmentMarshaller() {
+        return marshaller.getAttachmentMarshaller();
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setListener(final Listener listener) {
+        if (!isPropertySaved(Listener.class)) {
+            saveProperty(Listener.class, marshaller.getListener());
+        }
+        marshaller.setListener(listener);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller.
+     */
+    @Override
+    public Listener getListener() {
+        return marshaller.getListener();
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledMarshaller.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java?rev=1424365&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java (added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java Thu Dec 20 08:27:01 2012
@@ -0,0 +1,421 @@
+/*
+ * 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.xml;
+
+import java.net.URL;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.PropertyException;
+import javax.xml.bind.UnmarshallerHandler;
+import javax.xml.bind.ValidationEventHandler;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.attachment.AttachmentUnmarshaller;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.Source;
+import javax.xml.validation.Schema;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.apache.sis.util.Decorator;
+import org.apache.sis.internal.jaxb.MarshalContext;
+
+
+/**
+ * Wraps a {@link Unmarshaller} in order to have some control on the modifications applied on it.
+ * This wrapper serves two purpose:
+ *
+ * <ul>
+ *   <li>Save properties before modification, in order to restore them to their original values
+ *       when the unmarshaller is recycled.</li>
+ *   <li>Constructs a SIS {@link MarshalContext} object on unmarshalling, in order to give
+ *       additional information to the SIS object being unmarshalled.</li>
+ * </ul>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+@Decorator(Unmarshaller.class)
+final class PooledUnmarshaller extends Pooled implements Unmarshaller {
+    /**
+     * The wrapper marshaller which does the real work.
+     */
+    private final Unmarshaller unmarshaller;
+
+    /**
+     * Creates a pooled unmarshaller wrapping the given one.
+     *
+     * @param unmarshaller The unmarshaller to use for the actual work.
+     * @param internal {@code true} if the JAXB implementation is the one bundled in JDK 6,
+     *        or {@code false} if this is the external implementation provided as a JAR file
+     *        in the endorsed directory.
+     */
+    PooledUnmarshaller(final Unmarshaller unmarshaller, final boolean internal) {
+        super(internal);
+        this.unmarshaller = unmarshaller;
+    }
+
+    /**
+     * Resets the given unmarshaller property to its initial state.
+     * This method is invoked automatically by {@link #reset()}.
+     *
+     * @param  key   The property to reset.
+     * @param  value The saved initial value to give to the property.
+     * @throws JAXBException If an error occurred while restoring a property.
+     */
+    @Override
+    @SuppressWarnings({"unchecked","rawtypes","deprecation"})
+    protected void reset(final Object key, final Object value) throws JAXBException {
+        if (key instanceof String) {
+            unmarshaller.setProperty((String) key, value);
+        } else if (key == AttachmentUnmarshaller.class) {
+            unmarshaller.setAttachmentUnmarshaller((AttachmentUnmarshaller) value);
+        } else if (key == Schema.class) {
+            unmarshaller.setSchema((Schema) value);
+        } else if (key == Listener.class) {
+            unmarshaller.setListener((Listener) value);
+        } else if (key == ValidationEventHandler.class) {
+            unmarshaller.setEventHandler((ValidationEventHandler) value);
+        } else if (key == Boolean.class) {
+            unmarshaller.setValidating((Boolean) value);
+        } else {
+            unmarshaller.setAdapter((Class) key, (XmlAdapter) value);
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final InputStream input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final URL input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final File input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final Reader input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final InputSource input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final Node input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public <T> JAXBElement<T> unmarshal(final Node input, final Class<T> declaredType) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input, declaredType);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final Source input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public <T> JAXBElement<T> unmarshal(final Source input, final Class<T> declaredType) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input, declaredType);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final XMLStreamReader input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public <T> JAXBElement<T> unmarshal(final XMLStreamReader input, final Class<T> declaredType) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input, declaredType);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public Object unmarshal(final XMLEventReader input) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates the unmarshalling to the wrapped unmarshaller.
+     */
+    @Override
+    public <T> JAXBElement<T> unmarshal(final XMLEventReader input, final Class<T> declaredType) throws JAXBException {
+        final MarshalContext context = begin();
+        try {
+            return unmarshaller.unmarshal(input, declaredType);
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller.
+     */
+    @Override
+    public UnmarshallerHandler getUnmarshallerHandler() {
+        return unmarshaller.getUnmarshallerHandler();
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. This method is invoked by the parent
+     * class if the given name was not one of the {@link XML} constants.
+     */
+    @Override
+    void setStandardProperty(final String name, final Object value) throws PropertyException {
+        unmarshaller.setProperty(name, value);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. This method is invoked by the parent
+     * class if the given name was not one of the {@link XML} constants.
+     */
+    @Override
+    Object getStandardProperty(final String name) throws PropertyException {
+        return unmarshaller.getProperty(name);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public <A extends XmlAdapter> void setAdapter(final Class<A> type, final A adapter) {
+        super.setAdapter(type, adapter);
+        unmarshaller.setAdapter(type, adapter);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller.
+     */
+    @Override
+    @SuppressWarnings("rawtypes")
+    public <A extends XmlAdapter> A getAdapter(final Class<A> type) {
+        return unmarshaller.getAdapter(type);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     *
+     * @deprecated Replaced by {@link #setSchema(javax.xml.validation.Schema)} in JAXB 2.0.
+     */
+    @Override
+    @Deprecated
+    public void setValidating(final boolean validating) throws JAXBException {
+        if (!isPropertySaved(Boolean.class)) {
+            saveProperty(Boolean.class, unmarshaller.isValidating());
+        }
+        unmarshaller.setValidating(validating);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller.
+     *
+     * @deprecated Replaced by {@link #getSchema()} in JAXB 2.0.
+     */
+    @Override
+    @Deprecated
+    public boolean isValidating() throws JAXBException {
+        return unmarshaller.isValidating();
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setSchema(final Schema schema) {
+        super.setSchema(schema);
+        unmarshaller.setSchema(schema);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller.
+     */
+    @Override
+    public Schema getSchema() {
+        return unmarshaller.getSchema();
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setEventHandler(final ValidationEventHandler handler) throws JAXBException {
+        super.setEventHandler(handler);
+        unmarshaller.setEventHandler(handler);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller.
+     */
+    @Override
+    public ValidationEventHandler getEventHandler() throws JAXBException {
+        return unmarshaller.getEventHandler();
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setAttachmentUnmarshaller(final AttachmentUnmarshaller au) {
+        if (!isPropertySaved(AttachmentUnmarshaller.class)) {
+            saveProperty(AttachmentUnmarshaller.class, unmarshaller.getAttachmentUnmarshaller());
+        }
+        unmarshaller.setAttachmentUnmarshaller(au);
+    }
+
+    /**
+     * Delegates to the wrapped unmarshaller.
+     */
+    @Override
+    public AttachmentUnmarshaller getAttachmentUnmarshaller() {
+        return unmarshaller.getAttachmentUnmarshaller();
+    }
+
+    /**
+     * Delegates to the wrapped marshaller. The initial state will be saved
+     * if it was not already done, for future restoration by {@link #reset()}.
+     */
+    @Override
+    public void setListener(final Listener listener) {
+        if (!isPropertySaved(Listener.class)) {
+            saveProperty(Listener.class, unmarshaller.getListener());
+        }
+        unmarshaller.setListener(listener);
+    }
+
+    /**
+     * Delegates to the wrapped marshaller.
+     */
+    @Override
+    public Listener getListener() {
+        return unmarshaller.getListener();
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/PooledUnmarshaller.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/XML.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/XML.java?rev=1424365&r1=1424364&r2=1424365&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/XML.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/XML.java Thu Dec 20 08:27:01 2012
@@ -109,6 +109,7 @@ public final class XML extends Static {
      * </table>
      */
     public static final String SCHEMAS = "org.apache.sis.xml.schemas";
+    // If more keys are documented, update the Pooled.SCHEMAS_KEY array.
 
     /**
      * Specifies the GML version to be marshalled or unmarshalled. The GML version may affect the



Mime
View raw message