You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by ve...@apache.org on 2009/08/02 10:00:47 UTC
svn commit: r800006 - in
/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect:
BaseXLXPDialect.java CompliantXLXPDialect.java NonCompliantXLXPDialect.java
StAXDialectDetector.java
Author: veithen
Date: Sun Aug 2 08:00:46 2009
New Revision: 800006
URL: http://svn.apache.org/viewvc?rev=800006&view=rev
Log:
Improved the StAX dialect detection algorithm and added support for XLXP.
Added:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/BaseXLXPDialect.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CompliantXLXPDialect.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NonCompliantXLXPDialect.java (with props)
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/BaseXLXPDialect.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/BaseXLXPDialect.java?rev=800006&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/BaseXLXPDialect.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/BaseXLXPDialect.java Sun Aug 2 08:00:46 2009
@@ -0,0 +1,48 @@
+/*
+ * 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.axiom.util.stax.dialect;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+abstract class BaseXLXPDialect implements StAXDialect {
+ public void enableCDataReporting(XMLInputFactory factory) {
+ // TODO: check if that is enough
+ factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
+ }
+
+ public XMLInputFactory makeThreadSafe(XMLInputFactory factory) {
+ // XLXP's factories are thread safe
+ return factory;
+ }
+
+ public XMLOutputFactory makeThreadSafe(XMLOutputFactory factory) {
+ // XLXP's factories are thread safe
+ return factory;
+ }
+
+ public XMLInputFactory normalize(XMLInputFactory factory) {
+ return factory;
+ }
+
+ public XMLOutputFactory normalize(XMLOutputFactory factory) {
+ return factory;
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/BaseXLXPDialect.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CompliantXLXPDialect.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CompliantXLXPDialect.java?rev=800006&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CompliantXLXPDialect.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CompliantXLXPDialect.java Sun Aug 2 08:00:46 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.axiom.util.stax.dialect;
+
+class CompliantXLXPDialect extends BaseXLXPDialect {
+ public static final StAXDialect INSTANCE = new CompliantXLXPDialect();
+
+ public String getName() {
+ return "XL XP-J (StAX compliant versions)";
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CompliantXLXPDialect.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NonCompliantXLXPDialect.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NonCompliantXLXPDialect.java?rev=800006&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NonCompliantXLXPDialect.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NonCompliantXLXPDialect.java Sun Aug 2 08:00:46 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.axiom.util.stax.dialect;
+
+class NonCompliantXLXPDialect extends BaseXLXPDialect {
+ public static final StAXDialect INSTANCE = new NonCompliantXLXPDialect();
+
+ public String getName() {
+ return "XL XP-J (StAX non-compliant versions)";
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NonCompliantXLXPDialect.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java?rev=800006&r1=800005&r2=800006&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java Sun Aug 2 08:00:46 2009
@@ -57,9 +57,7 @@
* Map that stores detected dialects by location. The location is the URL corresponding to the
* root folder of the classpath entry from which the StAX implementation is loaded. Note that
* in the case of a JAR file, this is not the URL pointing to the JAR, but a <tt>jar:</tt>
- * URL that points to the root folder of the archive. The <code>null</code> location is used
- * to represent StAX implementations that are loaded from the bootstrap class loader, i.e.
- * which are part of the JRE.
+ * URL that points to the root folder of the archive.
*/
private static final Map/*<URL,StAXDialect>*/ dialectByUrl =
Collections.synchronizedMap(new HashMap());
@@ -75,6 +73,12 @@
* possible to determine the root URL
*/
private static URL getRootUrlForResource(ClassLoader classLoader, String resource) {
+ if (classLoader == null) {
+ // A null class loader means the bootstrap class loader. In this case we use the
+ // system class loader. This is safe since we can assume that the system class
+ // loader uses parent first as delegation policy.
+ classLoader = ClassLoader.getSystemClassLoader();
+ }
URL url = classLoader.getResource(resource);
if (url == null) {
return null;
@@ -92,6 +96,11 @@
}
}
+ private static URL getRootUrlForClass(Class cls) {
+ return getRootUrlForResource(cls.getClassLoader(),
+ cls.getName().replace('.', '/') + ".class");
+ }
+
/**
* Detect the dialect of a given {@link XMLInputFactory} and normalize it.
*
@@ -127,85 +136,46 @@
* @return the detected dialect
*/
public static StAXDialect getDialect(Class implementationClass) {
- URL rootUrl;
- ClassLoader classLoader = implementationClass.getClassLoader();
- if (classLoader == null) {
- // null means bootstrap classloader; represent this location as null
- rootUrl = null;
- } else {
- rootUrl = getRootUrlForResource(classLoader,
- implementationClass.getName().replace('.', '/') + ".class");
- if (rootUrl == null) {
- log.warn("Unable to determine location of StAX implementation containing class "
- + implementationClass.getName() + "; using default dialect");
- return UnknownStAXDialect.INSTANCE;
- }
+ URL rootUrl = getRootUrlForClass(implementationClass);
+ if (rootUrl == null) {
+ log.warn("Unable to determine location of StAX implementation containing class "
+ + implementationClass.getName() + "; using default dialect");
+ return UnknownStAXDialect.INSTANCE;
}
- return getDialect(rootUrl);
+ return getDialect(implementationClass.getClassLoader(), rootUrl);
}
- private static StAXDialect getDialect(URL rootUrl) {
+ private static StAXDialect getDialect(ClassLoader classLoader, URL rootUrl) {
StAXDialect dialect = (StAXDialect)dialectByUrl.get(rootUrl);
if (dialect != null) {
return dialect;
} else {
- dialect = detectDialect(rootUrl);
+ dialect = detectDialect(classLoader, rootUrl);
dialectByUrl.put(rootUrl, dialect);
return dialect;
}
}
- private static StAXDialect detectDialect(URL rootUrl) {
- StAXDialect dialect;
- if (rootUrl == null) {
- dialect = detectDialectFromJRE();
- } else {
- dialect = detectDialectFromJar(rootUrl);
- }
- if (log.isInfoEnabled()) {
- log.info("Detected StAX dialect: " + dialect.getName());
+ private static StAXDialect detectDialect(ClassLoader classLoader, URL rootUrl) {
+ StAXDialect dialect = detectDialectFromJarManifest(rootUrl);
+ if (dialect == null) {
+ // Note: We look for well defined classes instead of just checking the package name
+ // of the class passed to getDialect(Class) because in some parsers, the implementations
+ // of the StAX interfaces (factories, readers and writers) are not in the same package.
+ dialect = detectDialectFromClasses(classLoader, rootUrl);
}
- return dialect;
- }
-
- /**
- * Check that a given class is part of the bootstrap classes. This method is used to detect
- * different JRE flavors and to check which StAX implementation is part of the JRE.
- * <p>
- * Note: We look for a well defined class instead of just checking the package name of the class
- * passed to {@link #getDialect(Class)} because on some JREs, the implementations of the StAX
- * interfaces (factories, readers and writers) are not in the same package.
- *
- * @param className
- * the class name
- * @return <code>true</code> if the class can be loaded from the bootstrap class loader
- */
- private static boolean isBootstrapClass(String className) {
- try {
- Class cls = ClassLoader.getSystemClassLoader().loadClass(className);
- return cls.getClassLoader() == null;
- } catch (ClassNotFoundException ex) {
- return false;
- }
- }
-
- private static StAXDialect detectDialectFromJRE() {
- String vendor = System.getProperty("java.vendor");
- String version = System.getProperty("java.version");
- if (log.isDebugEnabled()) {
- log.debug("StAX implementation is part of the JRE:\n" +
- " Vendor: " + vendor + "\n" +
- " Version: " + version);
- }
- if (isBootstrapClass("com.sun.xml.internal.stream.XMLInputFactoryImpl")) {
- return SJSXPDialect.INSTANCE;
- } else {
- log.warn("Unable to determine dialect of StAX implementation provided by the JRE");
+ if (dialect == null) {
+ log.warn("Unable to determine dialect of the StAX implementation at " + rootUrl);
return UnknownStAXDialect.INSTANCE;
+ } else {
+ if (log.isInfoEnabled()) {
+ log.info("Detected StAX dialect: " + dialect.getName());
+ }
+ return dialect;
}
}
- private static StAXDialect detectDialectFromJar(URL rootUrl) {
+ private static StAXDialect detectDialectFromJarManifest(URL rootUrl) {
Manifest manifest;
try {
URL metaInfUrl = new URL(rootUrl, "META-INF/MANIFEST.MF");
@@ -236,9 +206,41 @@
} else if (title != null && title.indexOf("SJSXP") != -1) {
return SJSXPDialect.INSTANCE;
} else {
- log.warn("Unable to determine dialect of the StAX implementation at " + rootUrl
- + " (using JAR manifest)");
- return UnknownStAXDialect.INSTANCE;
+ return null;
+ }
+ }
+
+ private static Class loadClass(ClassLoader classLoader, URL rootUrl, String name) {
+ try {
+ Class cls = classLoader.loadClass(name);
+ // Cross check if the class was loaded from the same location (JAR)
+ return rootUrl.equals(getRootUrlForClass(cls)) ? cls : null;
+ } catch (ClassNotFoundException ex) {
+ return null;
+ }
+ }
+
+ private static StAXDialect detectDialectFromClasses(ClassLoader classLoader, URL rootUrl) {
+ // Try Sun's implementation found in JREs
+ if (loadClass(classLoader, rootUrl, "com.sun.xml.internal.stream.XMLInputFactoryImpl")
+ != null) {
+ return SJSXPDialect.INSTANCE;
+ }
+
+ // Try IBM's XL XP-J
+ Class cls = loadClass(classLoader, rootUrl, "com.ibm.xml.xlxp.api.stax.StAXImplConstants");
+ if (cls != null) {
+ boolean isStAXCompliant;
+ try {
+ cls.getField("IS_SETPREFIX_BEFORE_STARTELEMENT");
+ isStAXCompliant = true;
+ } catch (NoSuchFieldException ex) {
+ isStAXCompliant = false;
+ }
+ return isStAXCompliant ? CompliantXLXPDialect.INSTANCE
+ : NonCompliantXLXPDialect.INSTANCE;
}
+
+ return null;
}
}