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)) {
                 /*


Reply via email to