Mercurial > hg > openjdk > jdk6 > jaxws
changeset 26:dff2df398817 jdk6-b14
6775264: Changes for openjdk6 build 14
6592792: Add com.sun.xml.internal to the "package.access" property in $JAVA_HOME/lib/security/java.security
Summary: Final b14 state (as defined by the source bundle)
Reviewed-by: darcy
line wrap: on
line diff
--- a/src/share/classes/com/sun/xml/internal/ws/spi/ProviderImpl.java Fri Jan 30 17:16:58 2009 -0800 +++ b/src/share/classes/com/sun/xml/internal/ws/spi/ProviderImpl.java Fri Jan 30 17:21:27 2009 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,6 +56,8 @@ import javax.xml.ws.spi.ServiceDelegate; import javax.xml.ws.wsaddressing.W3CEndpointReference; import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.List; /** @@ -94,14 +96,20 @@ return endpoint; } - public EndpointReference readEndpointReference(Source eprInfoset) { - Unmarshaller unmarshaller; - try { - unmarshaller = eprjc.createUnmarshaller(); - return (EndpointReference) unmarshaller.unmarshal(eprInfoset); - } catch (JAXBException e) { - throw new WebServiceException("Error creating Marshaller or marshalling.", e); - } + public EndpointReference readEndpointReference(final Source eprInfoset) { + // EPR constructors are private, so we need privilege escalation. + // this unmarshalling can only access instances of a fixed, known set of classes, + // so doing that shouldn't introduce security vulnerability. + return AccessController.doPrivileged(new PrivilegedAction<EndpointReference>() { + public EndpointReference run() { + try { + Unmarshaller unmarshaller = eprjc.createUnmarshaller(); + return (EndpointReference) unmarshaller.unmarshal(eprInfoset); + } catch (JAXBException e) { + throw new WebServiceException("Error creating Marshaller or marshalling.", e); + } + } + }); } public <T> T getPort(EndpointReference endpointReference, Class<T> clazz, WebServiceFeature... webServiceFeatures) { @@ -185,10 +193,17 @@ } private static JAXBContext getEPRJaxbContext() { - try { - return JAXBContext.newInstance(MemberSubmissionEndpointReference.class, W3CEndpointReference.class); - } catch (JAXBException e) { - throw new WebServiceException("Error creating JAXBContext for W3CEndpointReference. ", e); - } + // EPRs have package and private fields, so we need privilege escalation. + // this access only fixed, known set of classes, so doing that + // shouldn't introduce security vulnerability. + return AccessController.doPrivileged(new PrivilegedAction<JAXBContext>() { + public JAXBContext run() { + try { + return JAXBContext.newInstance(MemberSubmissionEndpointReference.class, W3CEndpointReference.class); + } catch (JAXBException e) { + throw new WebServiceException("Error creating JAXBContext for W3CEndpointReference. ", e); + } + } + }); } }
--- a/src/share/classes/javax/xml/bind/ContextFinder.java Fri Jan 30 17:16:58 2009 -0800 +++ b/src/share/classes/javax/xml/bind/ContextFinder.java Fri Jan 30 17:21:27 2009 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,12 +130,7 @@ throws JAXBException { try { - Class spiClass; - if (classLoader == null) { - spiClass = Class.forName(className); - } else { - spiClass = classLoader.loadClass(className); - } + Class spiClass = safeLoadClass(className,classLoader); /* * javax.xml.bind.context.factory points to a class which has a @@ -207,11 +202,7 @@ ClassLoader cl = Thread.currentThread().getContextClassLoader(); Class spi; try { - logger.fine("Trying to load "+className); - if (cl != null) - spi = cl.loadClass(className); - else - spi = Class.forName(className); + spi = safeLoadClass(className,cl); } catch (ClassNotFoundException e) { throw new JAXBException(e); } @@ -488,4 +479,31 @@ * For this reason, we have to hard-code the class name into the API. */ private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory"; + + /** + * Loads the class, provided that the calling thread has an access to the class being loaded. + */ + private static Class safeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { + logger.fine("Trying to load "+className); + try { + // make sure that the current thread has an access to the package of the given name. + SecurityManager s = System.getSecurityManager(); + if (s != null) { + int i = className.lastIndexOf('.'); + if (i != -1) { + s.checkPackageAccess(className.substring(0,i)); + } + } + + if (classLoader == null) + return Class.forName(className); + else + return classLoader.loadClass(className); + } catch (SecurityException se) { + // anyone can access the platform default factory class without permission + if (PLATFORM_DEFAULT_FACTORY_CLASS.equals(className)) + return Class.forName(className); + throw se; + } + } }
--- a/src/share/classes/javax/xml/ws/spi/FactoryFinder.java Fri Jan 30 17:16:58 2009 -0800 +++ b/src/share/classes/javax/xml/ws/spi/FactoryFinder.java Fri Jan 30 17:21:27 2009 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,12 +47,7 @@ ClassLoader classLoader) { try { - Class spiClass; - if (classLoader == null) { - spiClass = Class.forName(className); - } else { - spiClass = classLoader.loadClass(className); - } + Class spiClass = safeLoadClass(className, classLoader); return spiClass.newInstance(); } catch (ClassNotFoundException x) { throw new WebServiceException( @@ -152,4 +147,33 @@ return newInstance(fallbackClassName, classLoader); } + + + private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.ws.spi.ProviderImpl"; + + /** + * Loads the class, provided that the calling thread has an access to the class being loaded. + */ + private static Class safeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { + try { + // make sure that the current thread has an access to the package of the given name. + SecurityManager s = System.getSecurityManager(); + if (s != null) { + int i = className.lastIndexOf('.'); + if (i != -1) { + s.checkPackageAccess(className.substring(0,i)); + } + } + + if (classLoader == null) + return Class.forName(className); + else + return classLoader.loadClass(className); + } catch (SecurityException se) { + // anyone can access the platform default factory class without permission + if (PLATFORM_DEFAULT_FACTORY_CLASS.equals(className)) + return Class.forName(className); + throw se; + } + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/Datatype.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,262 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * Datatype object. + * + * This object has the following functionality: + * + * <ol> + * <li> functionality to identify a class of character sequences. This is + * done through the isValid method. + * + * <li> functionality to produce a "value object" from a character sequence and + * context information. + * + * <li> functionality to test the equality of two value objects. + * </ol> + * + * This interface also defines the createStreamingValidator method, + * which is intended to efficiently support the validation of + * large character sequences. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface Datatype { + + /** + * Checks if the specified 'literal' matches this Datatype + * with respect to the current context. + * + * @param literal + * the lexical representation to be checked. + * @param context + * If this datatype is context-dependent + * (i.e. the {@link #isContextDependent} method returns true), + * then the caller must provide a non-null valid context object. + * Otherwise, the caller can pass null. + * + * @return + * true if the 'literal' is a member of this Datatype; + * false if it's not a member of this Datatype. + */ + boolean isValid( String literal, ValidationContext context ); + + /** + * Similar to the isValid method but throws an exception with diagnosis + * in case of errors. + * + * <p> + * If the specified 'literal' is a valid lexical representation for this + * datatype, then this method must return without throwing any exception. + * If not, the callee must throw an exception (with diagnosis message, + * if possible.) + * + * <p> + * The application can use this method to provide detailed error message + * to users. This method is kept separate from the isValid method to + * achieve higher performance during normal validation. + * + * @exception DatatypeException + * If the given literal is invalid, then this exception is thrown. + * If the callee supports error diagnosis, then the exception should + * contain a diagnosis message. + */ + void checkValid( String literal, ValidationContext context ) + throws DatatypeException; + + /** + * Creates an instance of a streaming validator for this type. + * + * <p> + * By using streaming validators instead of the isValid method, + * the caller can avoid keeping the entire string, which is + * sometimes quite big, in memory. + * + * @param context + * If this datatype is context-dependent + * (i.e. the {@link #isContextDependent} method returns true), + * then the caller must provide a non-null valid context object. + * Otherwise, the caller can pass null. + * The callee may keep a reference to this context object + * only while the returned streaming validator is being used. + */ + DatatypeStreamingValidator createStreamingValidator( ValidationContext context ); + + /** + * Converts lexcial value and the current context to the corresponding + * value object. + * + * <p> + * The caller cannot generally assume that the value object is + * a meaningful Java object. For example, the caller cannot expect + * this method to return <code>java.lang.Number</code> type for + * the "integer" type of XML Schema Part 2. + * + * <p> + * Also, the caller cannot assume that the equals method and + * the hashCode method of the value object are consistent with + * the semantics of the datatype. For that purpose, the sameValue + * method and the valueHashCode method have to be used. Note that + * this means you cannot use classes like + * <code>java.util.Hashtable</code> to store the value objects. + * + * <p> + * The returned value object should be used solely for the sameValue + * and valueHashCode methods. + * + * @param context + * If this datatype is context-dependent + * (when the {@link #isContextDependent} method returns true), + * then the caller must provide a non-null valid context object. + * Otherwise, the caller can pass null. + * + * @return null + * when the given lexical value is not a valid lexical + * value for this type. + */ + Object createValue( String literal, ValidationContext context ); + + /** + * Tests the equality of two value objects which were originally + * created by the createValue method of this object. + * + * The behavior is undefined if objects not created by this type + * are passed. It is the caller's responsibility to ensure that + * value objects belong to this type. + * + * @return + * true if two value objects are considered equal according to + * the definition of this datatype; false if otherwise. + */ + boolean sameValue( Object value1, Object value2 ); + + + /** + * Computes the hash code for a value object, + * which is consistent with the sameValue method. + * + * @return + * hash code for the specified value object. + */ + int valueHashCode( Object value ); + + + + + /** + * Indicates that the datatype doesn't have ID/IDREF semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_NULL = 0; + + /** + * Indicates that RELAX NG compatibility processors should + * treat this datatype as having ID semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_ID = 1; + + /** + * Indicates that RELAX NG compatibility processors should + * treat this datatype as having IDREF semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_IDREF = 2; + + /** + * Indicates that RELAX NG compatibility processors should + * treat this datatype as having IDREFS semantics. + * + * This value is one of the possible return values of the + * {@link #getIdType} method. + */ + public static final int ID_TYPE_IDREFS = 3; + + /** + * Checks if the ID/IDREF semantics is associated with this + * datatype. + * + * <p> + * This method is introduced to support the RELAX NG DTD + * compatibility spec. (Of course it's always free to use + * this method for other purposes.) + * + * <p> + * If you are implementing a datatype library and have no idea about + * the "RELAX NG DTD compatibility" thing, just return + * <code>ID_TYPE_NULL</code> is fine. + * + * @return + * If this datatype doesn't have any ID/IDREF semantics, + * it returns {@link #ID_TYPE_NULL}. If it has such a semantics + * (for example, XSD:ID, XSD:IDREF and comp:ID type), then + * it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or + * {@link #ID_TYPE_IDREFS}. + */ + public int getIdType(); + + + /** + * Checks if this datatype may need a context object for + * the validation. + * + * <p> + * The callee must return true even when the context + * is not always necessary. (For example, the "QName" type + * doesn't need a context object when validating unprefixed + * string. But nonetheless QName must return true.) + * + * <p> + * XSD's <code>string</code> and <code>short</code> types + * are examples of context-independent datatypes. + * Its <code>QName</code> and <code>ENTITY</code> types + * are examples of context-dependent datatypes. + * + * <p> + * When a datatype is context-independent, then + * the {@link #isValid} method, the {@link #checkValid} method, + * the {@link #createStreamingValidator} method and + * the {@link #createValue} method can be called without + * providing a context object. + * + * @return + * <b>true</b> if this datatype is context-dependent + * (it needs a context object sometimes); + * + * <b>false</b> if this datatype is context-<b>in</b>dependent + * (it never needs a context object). + */ + public boolean isContextDependent(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/DatatypeBuilder.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,70 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * Creates a user-defined type by adding parameters to + * the pre-defined type. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeBuilder { + + /** + * Adds a new parameter. + * + * @param name + * The name of the parameter to be added. + * @param strValue + * The raw value of the parameter. Caller may not normalize + * this value because any white space is potentially significant. + * @param context + * The context information which can be used by the callee to + * acquire additional information. This context object is + * valid only during this method call. The callee may not + * keep a reference to this object. + * @exception DatatypeException + * When the given parameter is inappropriate for some reason. + * The callee is responsible to recover from this error. + * That is, the object should behave as if no such error + * was occured. + */ + void addParameter( String name, String strValue, ValidationContext context ) + throws DatatypeException; + + /** + * Derives a new Datatype from a Datatype by parameters that + * were already set through the addParameter method. + * + * @exception DatatypeException + * DatatypeException must be thrown if the derivation is + * somehow invalid. For example, a required parameter is missing, + * etc. The exception should contain a diagnosis message + * if possible. + */ + Datatype createDatatype() throws DatatypeException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/DatatypeException.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,64 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * Signals Datatype related exceptions. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public class DatatypeException extends Exception { + + public DatatypeException( int index, String msg ) { + super(msg); + this.index = index; + } + public DatatypeException( String msg ) { + this(UNKNOWN,msg); + } + /** + * A constructor for those datatype libraries which don't support any + * diagnostic information at all. + */ + public DatatypeException() { + this(UNKNOWN,null); + } + + + private final int index; + + public static final int UNKNOWN = -1; + + /** + * Gets the index of the content where the error occured. + * UNKNOWN can be returned to indicate that no index information + * is available. + */ + public int getIndex() { + return index; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/DatatypeLibrary.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * A Datatype library + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeLibrary { + + /** + * Creates a new instance of DatatypeBuilder. + * + * The callee should throw a DatatypeException in case of an error. + * + * @param baseTypeLocalName + * The local name of the base type. + * + * @return + * A non-null valid datatype object. + */ + DatatypeBuilder createDatatypeBuilder( String baseTypeLocalName ) + throws DatatypeException; + + /** + * Gets or creates a pre-defined type. + * + * This is just a short-cut of + * <code>createDatatypeBuilder(typeLocalName).createDatatype();</code> + * + * The callee should throw a DatatypeException in case of an error. + * + * @return + * A non-null valid datatype object. + */ + Datatype createDatatype( String typeLocalName ) throws DatatypeException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/DatatypeLibraryFactory.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * Factory class for the DatatypeLibrary class. + * + * <p> + * The datatype library should provide the implementation of + * this interface if it wants to be found by the schema processors. + * The implementor also have to place a file in your jar file. + * See the reference datatype library implementation for detail. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeLibraryFactory +{ + /** + * Creates a new instance of a DatatypeLibrary that supports + * the specified namespace URI. + * + * @return + * <code>null</code> if the specified namespace URI is not + * supported. + */ + DatatypeLibrary createDatatypeLibrary( String namespaceURI ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/DatatypeStreamingValidator.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * Datatype streaming validator. + * + * <p> + * The streaming validator is an optional feature that is useful for + * certain Datatypes. It allows the caller to incrementally provide + * the literal. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface DatatypeStreamingValidator { + + /** + * Passes an additional fragment of the literal. + * + * <p> + * The application can call this method several times, then call + * the isValid method (or the checkValid method) to check the validity + * of the accumulated characters. + */ + void addCharacters( char[] buf, int start, int len ); + + /** + * Tells if the accumulated literal is valid with respect to + * the underlying Datatype. + * + * @return + * True if it is valid. False if otherwise. + */ + boolean isValid(); + + /** + * Similar to the isValid method, but this method throws + * Exception (with possibly diagnostic information), instead of + * returning false. + * + * @exception DatatypeException + * If the callee supports the diagnosis and the accumulated + * literal is invalid, then this exception that possibly + * contains diagnosis information is thrown. + */ + void checkValid() throws DatatypeException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/ValidationContext.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,91 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype; + +/** + * An interface that must be implemented by caller to + * provide context information that is necessary to + * perform validation of some Datatypes. + * + * @author <a href="mailto:jjc@jclark.com">James Clark</a> + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public interface ValidationContext { + + /** + * Resolves a namespace prefix to the corresponding namespace URI. + * + * This method is used for validating the QName type, for example. + * + * <p> + * If the prefix is "" (empty string), it indicates + * an unprefixed value. The callee + * should resolve it as for an unprefixed + * element, rather than for an unprefixed attribute. + * + * <p> + * If the prefix is "xml", then the callee must resolve + * this prefix into "http://www.w3.org/XML/1998/namespace", + * as defined in the XML Namespaces Recommendation. + * + * @return + * namespace URI of this prefix. + * If the specified prefix is not declared, + * the implementation must return null. + */ + String resolveNamespacePrefix( String prefix ); + + /** + * Returns the base URI of the context. The null string may be returned + * if no base URI is known. + */ + String getBaseUri(); + + /** + * Checks if an unparsed entity is declared with the + * specified name. + * + * @return + * true + * if the DTD has an unparsed entity declaration for + * the specified name. + * false + * otherwise. + */ + boolean isUnparsedEntity( String entityName ); + + /** + * Checks if a notation is declared with the + * specified name. + * + * @return + * true + * if the DTD has a notation declaration for the specified name. + * false + * otherwise. + */ + boolean isNotation( String notationName ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2001, Thai Open Source Software Center Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Thai Open Source Software Center Ltd nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.relaxng.datatype.helpers; + +import org.relaxng.datatype.DatatypeLibraryFactory; +import org.relaxng.datatype.DatatypeLibrary; +import java.util.Enumeration; +import java.util.NoSuchElementException; +import java.util.Vector; +import java.io.Reader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; + +/** + * Discovers the datatype library implementation from the classpath. + * + * <p> + * The call of the createDatatypeLibrary method finds an implementation + * from a given datatype library URI at run-time. + */ +public class DatatypeLibraryLoader implements DatatypeLibraryFactory { + private final Service service = new Service(DatatypeLibraryFactory.class); + + public DatatypeLibrary createDatatypeLibrary(String uri) { + for (Enumeration e = service.getProviders(); + e.hasMoreElements();) { + DatatypeLibraryFactory factory + = (DatatypeLibraryFactory)e.nextElement(); + DatatypeLibrary library = factory.createDatatypeLibrary(uri); + if (library != null) + return library; + } + return null; + } + + private static class Service { + private final Class serviceClass; + private final Enumeration configFiles; + private Enumeration classNames = null; + private final Vector providers = new Vector(); + private Loader loader; + + private class ProviderEnumeration implements Enumeration { + private int nextIndex = 0; + + public boolean hasMoreElements() { + return nextIndex < providers.size() || moreProviders(); + } + + public Object nextElement() { + try { + return providers.elementAt(nextIndex++); + } + catch (ArrayIndexOutOfBoundsException e) { + throw new NoSuchElementException(); + } + } + } + + private static class Singleton implements Enumeration { + private Object obj; + private Singleton(Object obj) { + this.obj = obj; + } + + public boolean hasMoreElements() { + return obj != null; + } + + public Object nextElement() { + if (obj == null) + throw new NoSuchElementException(); + Object tem = obj; + obj = null; + return tem; + } + } + + // JDK 1.1 + private static class Loader { + Enumeration getResources(String resName) { + ClassLoader cl = Loader.class.getClassLoader(); + URL url; + if (cl == null) + url = ClassLoader.getSystemResource(resName); + else + url = cl.getResource(resName); + return new Singleton(url); + } + + Class loadClass(String name) throws ClassNotFoundException { + return Class.forName(name); + } + } + + // JDK 1.2+ + private static class Loader2 extends Loader { + private ClassLoader cl; + + Loader2() { + cl = Loader2.class.getClassLoader(); + // If the thread context class loader has the class loader + // of this class as an ancestor, use the thread context class + // loader. Otherwise, the thread context class loader + // probably hasn't been set up properly, so don't use it. + ClassLoader clt = Thread.currentThread().getContextClassLoader(); + for (ClassLoader tem = clt; tem != null; tem = tem.getParent()) + if (tem == cl) { + cl = clt; + break; + } + } + + Enumeration getResources(String resName) { + try { + return cl.getResources(resName); + + } + catch (IOException e) { + return new Singleton(null); + } + } + + Class loadClass(String name) throws ClassNotFoundException { + return Class.forName(name, true, cl); + } + } + + public Service(Class cls) { + try { + loader = new Loader2(); + } + catch (NoSuchMethodError e) { + loader = new Loader(); + } + serviceClass = cls; + String resName = "META-INF/services/" + serviceClass.getName(); + configFiles = loader.getResources(resName); + } + + public Enumeration getProviders() { + return new ProviderEnumeration(); + } + + synchronized private boolean moreProviders() { + for (;;) { + while (classNames == null) { + if (!configFiles.hasMoreElements()) + return false; + classNames = parseConfigFile((URL)configFiles.nextElement()); + } + while (classNames.hasMoreElements()) { + String className = (String)classNames.nextElement(); + try { + Class cls = loader.loadClass(className); + Object obj = cls.newInstance(); + if (serviceClass.isInstance(obj)) { + providers.addElement(obj); + return true; + } + } + catch (ClassNotFoundException e) { } + catch (InstantiationException e) { } + catch (IllegalAccessException e) { } + catch (LinkageError e) { } + } + classNames = null; + } + } + + private static final int START = 0; + private static final int IN_NAME = 1; + private static final int IN_COMMENT = 2; + + private static Enumeration parseConfigFile(URL url) { + try { + InputStream in = url.openStream(); + Reader r; + try { + r = new InputStreamReader(in, "UTF-8"); + } + catch (UnsupportedEncodingException e) { + r = new InputStreamReader(in, "UTF8"); + } + r = new BufferedReader(r); + Vector tokens = new Vector(); + StringBuffer tokenBuf = new StringBuffer(); + int state = START; + for (;;) { + int n = r.read(); + if (n < 0) + break; + char c = (char)n; + switch (c) { + case '\r': + case '\n': + state = START; + break; + case ' ': + case '\t': + break; + case '#': + state = IN_COMMENT; + break; + default: + if (state != IN_COMMENT) { + state = IN_NAME; + tokenBuf.append(c); + } + break; + } + if (tokenBuf.length() != 0 && state != IN_NAME) { + tokens.addElement(tokenBuf.toString()); + tokenBuf.setLength(0); + } + } + if (tokenBuf.length() != 0) + tokens.addElement(tokenBuf.toString()); + return tokens.elements(); + } + catch (IOException e) { + return null; + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype.helpers; + +import org.relaxng.datatype.*; + +/** + * Dummy implementation of {@link DatatypeBuilder}. + * + * This implementation can be used for Datatypes which have no parameters. + * Any attempt to add parameters will be rejected. + * + * <p> + * Typical usage would be: + * <PRE><XMP> + * class MyDatatypeLibrary implements DatatypeLibrary { + * .... + * DatatypeBuilder createDatatypeBuilder( String typeName ) { + * return new ParameterleessDatatypeBuilder(createDatatype(typeName)); + * } + * .... + * } + * </XMP></PRE> + * + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public final class ParameterlessDatatypeBuilder implements DatatypeBuilder { + + /** This type object is returned for the derive method. */ + private final Datatype baseType; + + public ParameterlessDatatypeBuilder( Datatype baseType ) { + this.baseType = baseType; + } + + public void addParameter( String name, String strValue, ValidationContext context ) + throws DatatypeException { + throw new DatatypeException(); + } + + public Datatype createDatatype() throws DatatypeException { + return baseType; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java Fri Jan 30 17:21:27 2009 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.relaxng.datatype.helpers; + +import org.relaxng.datatype.*; + +/** + * Dummy implementation of {@link DatatypeStreamingValidator}. + * + * <p> + * This implementation can be used as a quick hack when the performance + * of streaming validation is not important. And this implementation + * also shows you how to implement the DatatypeStreamingValidator interface. + * + * <p> + * Typical usage would be: + * <PRE><XMP> + * class MyDatatype implements Datatype { + * .... + * public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) { + * return new StreamingValidatorImpl(this,context); + * } + * .... + * } + * </XMP></PRE> + * + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a> + */ +public final class StreamingValidatorImpl implements DatatypeStreamingValidator { + + /** This buffer accumulates characters. */ + private final StringBuffer buffer = new StringBuffer(); + + /** Datatype obejct that creates this streaming validator. */ + private final Datatype baseType; + + /** The current context. */ + private final ValidationContext context; + + public void addCharacters( char[] buf, int start, int len ) { + // append characters to the current buffer. + buffer.append(buf,start,len); + } + + public boolean isValid() { + return baseType.isValid(buffer.toString(),context); + } + + public void checkValid() throws DatatypeException { + baseType.checkValid(buffer.toString(),context); + } + + public StreamingValidatorImpl( Datatype baseType, ValidationContext context ) { + this.baseType = baseType; + this.context = context; + } +}