Author: desruisseaux
Date: Mon Feb 25 11:45:32 2013
New Revision: 1449667
URL: http://svn.apache.org/r1449667
Log:
Provided also a namespace prefix mapper for endorsed JAXB.
Added:
sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/bind/
- copied from r1449561,
sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/internal/bind/
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper_Endorsed.java
- copied, changed from r1449561,
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
Modified:
sis/branches/JDK7/pom.xml
sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/bind/marshaller/NamespacePrefixMapper.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java
Modified: sis/branches/JDK7/pom.xml
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/pom.xml?rev=1449667&r1=1449666&r2=1449667&view=diff
==============================================================================
--- sis/branches/JDK7/pom.xml (original)
+++ sis/branches/JDK7/pom.xml Mon Feb 25 11:45:32 2013
@@ -512,7 +512,7 @@ Apache SIS is a toolkit for describing l
</groups>
<!-- Internal packages to hide from javadoc. -->
- <excludePackageNames>org.apache.sis.internal</excludePackageNames>
+
<excludePackageNames>org.apache.sis.internal:com</excludePackageNames>
<!-- Custom taglets, some of them implemented in Java. -->
<tags>
Modified:
sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/bind/marshaller/NamespacePrefixMapper.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/bind/marshaller/NamespacePrefixMapper.java?rev=1449667&r1=1449561&r2=1449667&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/bind/marshaller/NamespacePrefixMapper.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/com/sun/xml/bind/marshaller/NamespacePrefixMapper.java
[UTF-8] Mon Feb 25 11:45:32 2013
@@ -14,32 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.sun.xml.internal.bind.marshaller;
+package com.sun.xml.bind.marshaller;
/**
- * A placeholder for an internal class from Sun/Oracle JDK 6. This class is
provided only for
- * compilation of {@link org.apache.sis.xml.OGCNamespacePrefixMapper}, and its
{@code .class}
- * file is deleted after compilation by the {@code maven-antrun-plugin} task
in the
- * {@code sis-utility/pom.xml} file.
- *
- * <p>The {@code NamespacePrefixMapper} class is part of Sun/Oracle JDK since
version 6,
- * but is considered internal API. For that reason, the JDK class is
intentionally hidden
- * by {@code javac} unless the non-standard {@code -XDignore.symbol.file}
option is given
- * to the compiler. We could declare a system dependency to the {@code rt.jar}
file in the
- * {@code pom.xml}, but this is specific to the Sun/Oracle JDK and would not
work with JDK 8.
- * Providing a skeleton class here, and deleting the {@code
NamespacePrefixMapper.class} file
- * after compilation, is the most portable approach we have found.</p>
- *
- * <p>Note that we do not declare any method in this class. This is not needed
if we make sure
- * that the method signatures in {@code OGCNamespacePrefixMapper} match the
ones in the JDK.</p>
+ * A copy of {@code
com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper} in the package
+ * used by the JAXB version <strong>not</strong> bundled with the JDK. This
class is identical
+ * to the one bundled with JDK 6 except that the package name does not
contains the
+ * "{@code internal}" part. Some servers like Glassfish uses this JAXB
implementation instead
+ * than the one bundled in JDK 6, so we must be able to support both.
*
* @author Cédric Briançon (Geomatys)
* @since 0.3 (derived from geotk-3.0)
* @version 0.3
* @module
*
- * @see <a href="https://issues.apache.org/jira/browse/SIS-74">SIS-74</a>
+ * @see com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper
*/
public abstract class NamespacePrefixMapper {
}
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java?rev=1449667&r1=1449666&r2=1449667&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
[UTF-8] Mon Feb 25 11:45:32 2013
@@ -65,10 +65,15 @@ public class MarshallerPool {
private static final long TIMEOUT = 15000000000L; // 15 seconds.
/**
- * The key to be used in the map given to the constructors for specifying
the root namespace.
+ * Kind of JAXB implementations.
+ */
+ private static final byte INTERNAL = 0, ENDORSED = 1, OTHER = 2;
+
+ /**
+ * The key to be used in the map given to the constructors for specifying
the default namespace.
* An example of value for this key is {@code
"http://www.isotc211.org/2005/gmd"}.
*/
- public static final String ROOT_NAMESPACE_KEY =
"org.apache.sis.xml.rootNamespace";
+ public static final String DEFAULT_NAMESPACE_KEY =
"org.apache.sis.xml.defaultNamespace";
/**
* The JAXB context to use for creating marshaller and unmarshaller.
@@ -76,11 +81,11 @@ public class MarshallerPool {
private final JAXBContext context;
/**
- * {@code true} if the JAXB implementation is the one bundled in JDK 6,
- * or {@code false} if this is an external implementation like a JAR put
- * in the endorsed directory.
+ * {@link #INTERNAL} if the JAXB implementation is the one bundled in the
JDK,
+ * {@link #ENDORSED} if the TAXB implementation is the endorsed JAXB
(Glassfish), or
+ * {@link #OTHER} if unknown.
*/
- private final boolean internal;
+ private final byte implementation;
/**
* The mapper between namespaces and prefix.
@@ -133,7 +138,7 @@ public class MarshallerPool {
/**
* Creates a new factory for the given class to be bound. The keys in the
{@code properties} map
- * shall be one or many of the constants defined in this class like {@link
#ROOT_NAMESPACE_KEY}.
+ * shall be one or many of the constants defined in this class like {@link
#DEFAULT_NAMESPACE_KEY}.
*
* @param properties The set of properties to be given to the pool.
* @param classesToBeBound The classes to be bound, for example {@code
DefaultMetadata.class}.
@@ -161,7 +166,7 @@ public class MarshallerPool {
/**
* Creates a new factory for the given packages. The separator character
for the packages is the
* colon. The keys in the {@code properties} map shall be one or many of
the constants defined
- * in this class like {@link #ROOT_NAMESPACE_KEY}.
+ * in this class like {@link #DEFAULT_NAMESPACE_KEY}.
*
* @param properties The set of properties to be given to the pool.
* @param packages The colon-separated list of packages in which
JAXB will search for annotated classes.
@@ -181,22 +186,28 @@ public class MarshallerPool {
@SuppressWarnings({"unchecked", "rawtypes"}) // Generic array creation
private MarshallerPool(final Map<String,String> properties, final
JAXBContext context) throws JAXBException {
this.context = context;
- String rootNamespace = properties.get(ROOT_NAMESPACE_KEY);
+ String rootNamespace = properties.get(DEFAULT_NAMESPACE_KEY);
if (rootNamespace == null) {
rootNamespace = "";
}
/*
* Detects if we are using the endorsed JAXB implementation (i.e. the
one provided in
- * separated JAR files). If not, we will assume that we are using the
implementation
- * bundled in JDK 6. We use the JAXB context package name as a
criterion.
+ * separated JAR files) or the one bundled in JDK 6. We use the JAXB
context package
+ * name as a criterion:
*
* JAXB endorsed JAR uses "com.sun.xml.bind"
* JAXB bundled in JDK uses "com.sun.xml.internal.bind"
*/
- internal =
!context.getClass().getName().startsWith("com.sun.xml.bind");
- String type = "org.apache.sis.xml.OGCNamespacePrefixMapper_Endorsed";
- if (internal) {
- type = type.substring(0, type.lastIndexOf('_'));
+ String classname = context.getClass().getName();
+ if (classname.startsWith("com.sun.xml.internal.bind.")) {
+ classname = "org.apache.sis.xml.OGCNamespacePrefixMapper";
+ implementation = INTERNAL;
+ } else if (classname.startsWith(Pooled.ENDORSED_PREFIX)) {
+ classname = "org.apache.sis.xml.OGCNamespacePrefixMapper_Endorsed";
+ implementation = ENDORSED;
+ } else {
+ classname = null;
+ implementation = OTHER;
}
/*
* Instantiates the OGCNamespacePrefixMapper appropriate for the
implementation
@@ -204,10 +215,12 @@ public class MarshallerPool {
* usual ClassNotFoundException if the class was found but its parent
class has
* not been found.
*/
- try {
- mapper =
Class.forName(type).getConstructor(String.class).newInstance(rootNamespace);
+ if (classname == null) {
+ mapper = null;
+ } else try {
+ mapper =
Class.forName(classname).getConstructor(String.class).newInstance(rootNamespace);
} catch (ReflectiveOperationException | NoClassDefFoundError
exception) {
- throw new JAXBException("Unsupported JAXB implementation.",
exception);
+ throw new JAXBException(exception);
}
marshallers = new ConcurrentLinkedDeque<>();
unmarshallers = new ConcurrentLinkedDeque<>();
@@ -325,7 +338,7 @@ public class MarshallerPool {
public Marshaller acquireMarshaller() throws JAXBException {
Marshaller marshaller = marshallers.poll();
if (marshaller == null) {
- marshaller = new PooledMarshaller(createMarshaller(), internal);
+ marshaller = new PooledMarshaller(createMarshaller(),
implementation == INTERNAL);
}
return marshaller;
}
@@ -352,7 +365,7 @@ public class MarshallerPool {
public Unmarshaller acquireUnmarshaller() throws JAXBException {
Unmarshaller unmarshaller = unmarshallers.poll();
if (unmarshaller == null) {
- unmarshaller = new PooledUnmarshaller(createUnmarshaller(),
internal);
+ unmarshaller = new PooledUnmarshaller(createUnmarshaller(),
implementation == INTERNAL);
}
return unmarshaller;
}
@@ -386,13 +399,20 @@ public class MarshallerPool {
* @throws JAXBException If an error occurred while creating and
configuring the marshaller.
*/
protected Marshaller createMarshaller() throws JAXBException {
- final String mapperKey = internal ?
- "com.sun.xml.internal.bind.namespacePrefixMapper" :
- "com.sun.xml.bind.namespacePrefixMapper";
final Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
- marshaller.setProperty(mapperKey, mapper);
+ switch (implementation) {
+ case INTERNAL: {
+
marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper",
mapper);
+ break;
+ }
+ case ENDORSED: {
+
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);
+ break;
+ }
+ // Do nothing for the OTHER case.
+ }
synchronized (AdapterReplacement.PROVIDER) {
for (final AdapterReplacement adapter :
AdapterReplacement.PROVIDER) {
adapter.register(marshaller);
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java?rev=1449667&r1=1449666&r2=1449667&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
[UTF-8] Mon Feb 25 11:45:32 2013
@@ -18,7 +18,6 @@ package org.apache.sis.xml;
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
import net.jcip.annotations.Immutable;
-import org.apache.sis.util.CharSequences;
/**
Copied:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper_Endorsed.java
(from r1449561,
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java)
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper_Endorsed.java?p2=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper_Endorsed.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java&r1=1449561&r2=1449667&rev=1449667&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper_Endorsed.java
[UTF-8] Mon Feb 25 11:45:32 2013
@@ -16,30 +16,24 @@
*/
package org.apache.sis.xml;
-import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
+import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
import net.jcip.annotations.Immutable;
-import org.apache.sis.util.CharSequences;
/**
* A mapper between namespace prefixes and URL they represent.
- * This class is an alternative to the standard {@link
javax.xml.bind.annotation.XmlSchema}
- * annotation. However this class extends the non-standard {@code
NamespacePrefixMapper} class,
- * which is bundled in Sun/Oracle JDK since version 6. We have to use this
mapper because the
- * {@code @XmlSchema} annotation doesn't work as expected before JAXB 2.2.4,
and the JDK 6 is
- * bundled with JAXB 2.1. Even with working {@code @XmlSchema} annotations,
this mapper still
- * a convenient may to gain more control like choosing a default namespace at
runtime.
+ * This class is identical to {@link OGCNamespacePrefixMapper} except that it
depends
+ * on the endorsed JAXB jar instead than the implementation bundled with JDK
6, i.e.
+ * the package name of the parent {@code NamespacePrefixMapper} class does not
have
+ * the "{@code internal}" part.
*
* @author Cédric Briançon (Geomatys)
* @since 0.3 (derived from geotk-2.5)
* @version 0.3
* @module
- *
- * @see <a
href="http://java.sun.com/webservices/docs/1.5/jaxb/vendorProperties.html">JAXB
extensions</a>
- * @see <a href="https://issues.apache.org/jira/browse/SIS-74">SIS-74</a>
*/
@Immutable
-final class OGCNamespacePrefixMapper extends NamespacePrefixMapper {
+final class OGCNamespacePrefixMapper_Endorsed extends NamespacePrefixMapper {
/**
* If non-null, this namespace will be the default namespace (the one
without prefix).
*/
@@ -50,7 +44,7 @@ final class OGCNamespacePrefixMapper ext
*
* @param defaultNamespace The namespace which doesn't need prefix, or
{@code null} if none.
*/
- public OGCNamespacePrefixMapper(final String defaultNamespace) {
+ public OGCNamespacePrefixMapper_Endorsed(final String defaultNamespace) {
this.defaultNamespace = defaultNamespace;
}
Modified:
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=1449667&r1=1449666&r2=1449667&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
[UTF-8] Mon Feb 25 11:45:32 2013
@@ -61,7 +61,7 @@ abstract class Pooled {
*
* @see #convertPropertyKey(String)
*/
- private static final String ENDORSED_PREFIX = "com.sun.xml.bind.";
+ 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}
Modified:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java?rev=1449667&r1=1449666&r2=1449667&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java
[UTF-8] Mon Feb 25 11:45:32 2013
@@ -44,26 +44,62 @@ import static org.junit.Assert.*;
*/
public final strictfp class OGCNamespacePrefixMapperTest extends TestCase {
/**
- * Ensures that the class overrides all abstract methods defined in the
JDK class.
- * This test invokes every public methods declared in {@code
NamespacePrefixMapper},
- * which will throw {@link AbstractMethodError} if we forgot to override
an abstract
- * method. Additionally, this test check the result of some method calls
in order to
- * ensure that the invoked method was the one defined in {@link
OGCNamespacePrefixMapper}.
+ * Ensures that the {@link OGCNamespacePrefixMapper} class overrides all
abstract methods
+ * defined in the JDK class. This test is ignored if the Java framework
running this test
+ * is not the Oracle one (i.e. if it does not bundle the Sun internal JAXB
implementation).
*
* @throws ReflectiveOperationException If an error occurred while
invoking a method by
* the reflection API.
*/
@Test
- public void ensureOverrideMethods() throws ReflectiveOperationException {
- final OGCNamespacePrefixMapper mapper;
+ public void testInternalJAXB() throws ReflectiveOperationException {
try {
- mapper = new OGCNamespacePrefixMapper(null);
+ ensureOverrideMethods(new OGCNamespacePrefixMapper(null));
} catch (NoClassDefFoundError e) {
assumeNoException(e);
- return;
}
+ }
+
+ /**
+ * Ensures that the {@link OGCNamespacePrefixMapper_Endorsed} class
overrides all abstract
+ * methods defined in the JAXB class. This test is ignored if the Java
framework running
+ * this test does not contains JAXB in its endorsed directory.
+ *
+ * @throws ReflectiveOperationException If an error occurred while
invoking a method by
+ * the reflection API.
+ */
+ @Test
+ public void testEndorsedJAXB() throws ReflectiveOperationException {
+ try {
+ ensureOverrideMethods(new OGCNamespacePrefixMapper_Endorsed(null));
+ } catch (NoClassDefFoundError e) {
+ assumeNoException(e);
+ }
+ }
+
+ /**
+ * Ensures that the class of the given instance overrides all abstract
methods defined by JAXB.
+ * This test invokes every public methods declared in {@code
NamespacePrefixMapper},
+ * which will throw {@link AbstractMethodError} if we forgot to override
an abstract
+ * method. Additionally, this test checks the result of some method calls
in order to
+ * ensure that the invoked method was the one defined in {@link
OGCNamespacePrefixMapper}.
+ *
+ * @param The {@code OGCNamespacePrefixMapper} or {@code
OGCNamespacePrefixMapper_Endorsed}
+ * instance to check.
+ * @throws ReflectiveOperationException If an error occurred while
invoking a method by
+ * the reflection API.
+ */
+ private void ensureOverrideMethods(final Object mapper) throws
ReflectiveOperationException {
String preferredPrefix =
"getPreferredPrefix_method_has_not_been_found";
- for (final Method method :
mapper.getClass().getSuperclass().getDeclaredMethods()) {
+ final Method[] methods =
mapper.getClass().getSuperclass().getDeclaredMethods();
+ /*
+ * The methods array is empty if the JVM has loaded the SIS
placeholder instead than the
+ * real JAXB class. It should never happen during the Maven build
because those classes
+ * are deleted before the tests execution. However this may happen if
the tests are run
+ * from an IDE.
+ */
+ assumeTrue(methods.length != 0);
+ for (final Method method : methods) {
final int modifiers = method.getModifiers();
if (Modifier.isPublic(modifiers)) {
/*