Upgrading to JAXP 1.3 APIs.

git-svn-id: https://svn.apache.org/repos/asf/xml/commons/trunk@226188 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
neeraj 2005-04-11 07:49:39 +00:00
parent f672902d3f
commit e238b84fd0
2 changed files with 552 additions and 0 deletions

View File

@ -0,0 +1,405 @@
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed 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.
*/
// $Id$
package javax.xml.datatype;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
/**
* <p>Implement pluggabile Datatypes.</p>
*
* <p>This class is duplicated for each JAXP subpackage so keep it in
* sync. It is package private for secure class loading.</p>
*
* @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
* @version $Revision$, $Date$
* @since 1.5
*/
class FactoryFinder {
/**
* <p>Name of class to display in output messages.</p>
*/
private static final String CLASS_NAME = "javax.xml.datatype.FactoryFinder";
/**
* <p>Debug flag to trace loading process.</p>
*/
private static boolean debug = false;
/**
* <p>Cache properties for performance.</p>
*/
private static Properties cacheProps = new Properties();
/**
* <p>First time requires initialization overhead.</p>
*/
private static boolean firstTime = true;
/**
*<p> Take care of restrictions imposed by java security model </p>
*/
private static SecuritySupport ss = new SecuritySupport();
/**
* <p>Check to see if debugging enabled by property.</p>
*
* <p>Use try/catch block to support applets, which throws
* SecurityException out of this code.</p>
*
*/
static {
try {
debug = ss.getSystemProperty("jaxp.debug") != null;
} catch (Exception x) {
; // NOP, ignore exception
}
}
/**
* <p>Output debugging messages.</p>
*
* @param msg <code>String</code> to print to <code>stderr</code>.
*/
private static void debugPrintln(String msg) {
if (debug) {
System.err.println(
CLASS_NAME
+ ":"
+ msg);
}
}
/**
* <p>Find the appropriate <code>ClassLoader</code> to use.</p>
*
* <p>The context ClassLoader is prefered.</p>
*
* @return <code>ClassLoader</code> to use.
*
* @throws ConfigurationError If a valid <code>ClassLoader</code> cannot be identified.
*/
private static ClassLoader findClassLoader()
throws ConfigurationError {
ClassLoader classLoader;
// Figure out which ClassLoader to use for loading the provider
// class. If there is a Context ClassLoader then use it.
classLoader = ss.getContextClassLoader();
debugPrintln(
"Using context class loader: "
+ classLoader);
if (classLoader == null) {
// if we have no Context ClassLoader
// so use the current ClassLoader
classLoader = FactoryFinder.class.getClassLoader();
debugPrintln(
"Using the class loader of FactoryFinder: "
+ classLoader);
}
return classLoader;
}
/**
* <p>Create an instance of a class using the specified ClassLoader.</p>
*
* @param className Name of class to create.
* @param classLoader ClassLoader to use to create named class.
*
* @return New instance of specified class created using the specified ClassLoader.
*
* @throws ConfigurationError If class could not be created.
*/
private static Object newInstance(
String className,
ClassLoader classLoader)
throws ConfigurationError {
try {
Class spiClass;
if (classLoader == null) {
spiClass = Class.forName(className);
} else {
spiClass = classLoader.loadClass(className);
}
if (debug) {
debugPrintln("Loaded " + className + " from " + which(spiClass));
}
return spiClass.newInstance();
} catch (ClassNotFoundException x) {
throw new ConfigurationError(
"Provider " + className + " not found", x);
} catch (Exception x) {
throw new ConfigurationError(
"Provider " + className + " could not be instantiated: " + x,
x);
}
}
/**
* Finds the implementation Class object in the specified order. Main
* entry point.
* Package private so this code can be shared.
*
* @param factoryId Name of the factory to find, same as a property name
* @param fallbackClassName Implementation class name, if nothing else is found. Use null to mean no fallback.
*
* @return Class Object of factory, never null
*
* @throws ConfigurationError If Class cannot be found.
*/
static Object find(String factoryId, String fallbackClassName)
throws ConfigurationError {
ClassLoader classLoader = findClassLoader();
// Use the system property first
try {
String systemProp = ss.getSystemProperty(factoryId);
if (systemProp != null) {
debugPrintln("found " + systemProp + " in the system property " + factoryId);
return newInstance(systemProp, classLoader);
}
} catch (SecurityException se) {
; // NOP, explicitly ignore SecurityException
}
// try to read from $java.home/lib/jaxp.properties
try {
String javah = ss.getSystemProperty("java.home");
String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
String factoryClassName = null;
if (firstTime) {
synchronized (cacheProps) {
if (firstTime) {
File f = new File(configFile);
firstTime = false;
if (ss.doesFileExist(f)) {
debugPrintln("Read properties file " + f);
cacheProps.load(ss.getFileInputStream(f));
}
}
}
}
factoryClassName = cacheProps.getProperty(factoryId);
debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
if (factoryClassName != null) {
return newInstance(factoryClassName, classLoader);
}
} catch (Exception ex) {
if (debug) {
ex.printStackTrace();
}
}
// Try Jar Service Provider Mechanism
Object provider = findJarServiceProvider(factoryId);
if (provider != null) {
return provider;
}
if (fallbackClassName == null) {
throw new ConfigurationError(
"Provider for " + factoryId + " cannot be found", null);
}
debugPrintln("loaded from fallback value: " + fallbackClassName);
return newInstance(fallbackClassName, classLoader);
}
/*
* Try to find provider using Jar Service Provider Mechanism
*
* @return instance of provider class if found or null
*/
private static Object findJarServiceProvider(String factoryId)
throws ConfigurationError
{
String serviceId = "META-INF/services/" + factoryId;
InputStream is = null;
// First try the Context ClassLoader
ClassLoader cl = ss.getContextClassLoader();
if (cl != null) {
is = ss.getResourceAsStream(cl, serviceId);
// If no provider found then try the current ClassLoader
if (is == null) {
cl = FactoryFinder.class.getClassLoader();
is = ss.getResourceAsStream(cl, serviceId);
}
} else {
// No Context ClassLoader, try the current
// ClassLoader
cl = FactoryFinder.class.getClassLoader();
is = ss.getResourceAsStream(cl, serviceId);
}
if (is == null) {
// No provider found
return null;
}
debugPrintln("found jar resource=" + serviceId +
" using ClassLoader: " + cl);
BufferedReader rd;
try {
rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
} catch (java.io.UnsupportedEncodingException e) {
rd = new BufferedReader(new InputStreamReader(is));
}
String factoryClassName = null;
try {
// XXX Does not handle all possible input as specified by the
// Jar Service Provider specification
factoryClassName = rd.readLine();
rd.close();
} catch (IOException x) {
// No provider found
return null;
}
if (factoryClassName != null &&
! "".equals(factoryClassName)) {
debugPrintln("found in resource, value="
+ factoryClassName);
return newInstance(factoryClassName, cl);
}
// No provider found
return null;
}
/**
* <p>Configuration Error.</p>
*/
static class ConfigurationError extends Error {
/**
* <p>Exception that caused the error.</p>
*/
private Exception exception;
/**
* <p>Construct a new instance with the specified detail string and
* exception.</p>
*
* @param msg Detail message for this error.
* @param x Exception that caused the error.
*/
ConfigurationError(String msg, Exception x) {
super(msg);
this.exception = x;
}
/**
* <p>Get the Exception that caused the error.</p>
*
* @return Exception that caused the error.
*/
Exception getException() {
return exception;
}
}
/**
* Returns the location where the given Class is loaded from.
*
* @param clazz Class to find load location.
*
* @return Location where class would be loaded from.
*/
private static String which(Class clazz) {
try {
String classnameAsResource = clazz.getName().replace('.', '/') + ".class";
ClassLoader loader = clazz.getClassLoader();
URL it;
if (loader != null) {
it = loader.getResource(classnameAsResource);
} else {
it = ClassLoader.getSystemResource(classnameAsResource);
}
if (it != null) {
return it.toString();
}
} catch (Throwable t) {
// work defensively.
if (debug) {
t.printStackTrace();
}
}
return "unknown location";
}
/**
* The following nested classes allow getContextClassLoader() to be
* called only on JDK 1.2 and yet run in older JDK 1.1 JVMs
*/
private abstract static class ClassLoaderFinder {
/**
* <p>Get Context Class loader.</p>
*
* @return Context class loader.
*/
abstract ClassLoader getContextClassLoader();
}
/**
* <p>Actual ClassLoader finder implementation.</p>
*/
static class ClassLoaderFinderConcrete extends ClassLoaderFinder {
/**
* <p>Get Context Class loader.</p>
*
* @return Context class loader.
*/
ClassLoader getContextClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
}
}

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id$ -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>javax.xml.xpath</title>
<meta name="@author" content="mailto:Jeff.Suttor@Sun.com" />
<meta name="@version" content="$Revision$, $Date$" />
<meta name="@see" content='<a href="http://www.w3.org/TR/xmlschema-2/#dateTime">W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a>' />
<meta name="@see" content='<a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>' />
<meta name="@see" content='<a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>' />
<meta name="@since" content="1.5" />
</head>
<body>
<p>XML/Java Type Mappings.</p>
<p><code>javax.xml.datatype</code>API provides XML/Java type mappings.</p>
<p>The following XML standards apply:</p>
<ul>
<li><a href="http://www.w3.org/TR/xmlschema-2/#dateTime">W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a></li>
<li><a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a></li>
<li><a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a></li>
</ul>
<hr />
<table border="1" cellpadding="2">
<thead>
<tr>
<th>W3C XML Schema Data Type</th>
<th>Java Data Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>xs:date</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:dateTime</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:duration</td>
<td>{@link javax.xml.datatype.Duration}</td>
</tr>
<tr>
<td>xs:gDay</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:gMonth </td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:gMonthDay</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:gYear</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:gYearMonth</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
<tr>
<td>xs:time</td>
<td>{@link javax.xml.datatype.XMLGregorianCalendar}</td>
</tr>
</tbody>
</table>
<hr />
<table border="1" cellpadding="2">
<thead>
<tr>
<th>XQuery 1.0 and XPath 2.0 Data Model</th>
<th>Java Data Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>xdt:dayTimeDuration</td>
<td>{@link javax.xml.datatype.Duration}</td>
</tr>
<tr>
<td>xdt:yearMonthDuration</td>
<td>{@link javax.xml.datatype.Duration}</td>
</tr>
</tbody>
</table>
<hr />
<p>
W3C XML Schema data types that have a "<em>natural</em>" mapping to Java types are defined by
JSR 31: Java&trade; Architecture for XML Binding (JAXB) Specification, Binding XML Schema to Java Representations.
JAXB defined mappings for XML Schema built-in data types include:
</p>
<ul>
<li>xs:anySimpleType</li>
<li>xs:base64Binary</li>
<li>xs:boolean</li>
<li>xs:byte</li>
<li>xs:decimal</li>
<li>xs:double</li>
<li>xs:float</li>
<li>xs:hexBinary</li>
<li>xs:int</li>
<li>xs:integer</li>
<li>xs:long</li>
<li>xs:QName</li>
<li>xs:short</li>
<li>xs:string</li>
<li>xs:unsignedByte</li>
<li>xs:unsignedInt</li>
<li>xs:unsignedShort</li>
</ul>
<hr />
<ul>
<li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li>
<li>See <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a></li>
<li>See <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a></li>
<li>See <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a></li>
<li>Since 1.5</li>
</ul>
<hr />
</body>
</html>