You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2012/12/20 09:27:02 UTC
svn commit: r1424365 - in
/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis:
util/resources/ xml/
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