diff options
Diffstat (limited to 'sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl')
3 files changed, 559 insertions, 0 deletions
diff --git a/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/ExternalizableDelegator.java b/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/ExternalizableDelegator.java new file mode 100644 index 0000000000..03220a8a32 --- /dev/null +++ b/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/ExternalizableDelegator.java @@ -0,0 +1,90 @@ +/** + * <copyright> + * + * Service Data Objects + * Version 2.1.0 + * Licensed Materials + * + * (c) Copyright BEA Systems, Inc., International Business Machines Corporation, + * Oracle Corporation, Primeton Technologies Ltd., Rogue Wave Software, SAP AG., + * Software AG., Sun Microsystems, Sybase Inc., Xcalia, Zend Technologies, + * 2005, 2006. All rights reserved. + * + * </copyright> + * + */ + +package commonj.sdo.impl; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.ObjectStreamException; + +/** + * Delegates DataObject serialization while ensuring implementation independent + * java.io.Serialization. An implementation of DataObject + * returns an ExternalizableDelegator from its writeReplace() method. + * + * The root DataObject is the object returned from do.getRootObject() where + * do is the DataObject being serialized in a java.io.ObjectOutputStream. + * When do.getContainer() == null then do is a root object. + * + * The byte format for each DataObject in the stream is: + * [0] [path] [root] // when do is not a root object + * [1] [rootXML] // when do is a root object + * + * where: + * [0] is the byte 0, serialized using writeByte(0). + * [1] is the byte 1, serialized using writeByte(1). + * + * [path] is an SDO path expression from the root DataObject to the serialized + * DataObject such that root.getDataObject(path) == do. + * Serialized using writeUTF(path). + * + * [root] is the root object serialized using writeObject(root). + * + * [rootXML] is the GZip of the XML serialization of the root DataObject. + * The XML serialization is the same as + * XMLHelper.INSTANCE.save(root, "commonj.sdo", "dataObject", stream); + * where stream is a GZIPOutputStream, length is the number of bytes + * in the stream, and bytes are the contents of the stream. + * Serialized using writeInt(length), write(bytes). + * + */ +public class ExternalizableDelegator implements Externalizable +{ + public interface Resolvable extends Externalizable + { + Object readResolve() throws ObjectStreamException; + } + + static final long serialVersionUID = 1; + transient Resolvable delegate; + + public ExternalizableDelegator() + { + delegate = HelperProvider.createResolvable(); + } + + public ExternalizableDelegator(Object target) + { + delegate = HelperProvider.createResolvable(target); + } + + public void writeExternal(ObjectOutput out) throws IOException + { + delegate.writeExternal(out); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + delegate.readExternal(in); + } + + public Object readResolve() throws ObjectStreamException + { + return delegate.readResolve(); + } +} diff --git a/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/HelperProvider.java b/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/HelperProvider.java new file mode 100644 index 0000000000..be513c43e8 --- /dev/null +++ b/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/HelperProvider.java @@ -0,0 +1,411 @@ +/** + * + * 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 commonj.sdo.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import commonj.sdo.helper.CopyHelper; +import commonj.sdo.helper.DataFactory; +import commonj.sdo.helper.DataHelper; +import commonj.sdo.helper.EqualityHelper; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.TypeHelper; +import commonj.sdo.helper.XMLHelper; +import commonj.sdo.helper.XSDHelper; + +/** + * A HelperProvider obtains specific default helpers and other + * implementation-specific objects used by a Java implementation of SDO. + * + * @version $Rev$ $Date$ + */ +public abstract class HelperProvider { + /** + * The default HelperProvider INSTANCE. This is located using the ClassLoader used + * to load the HelperProvider class itself and if no default implementation is available + * this field will be set to null. + */ + public static HelperProvider INSTANCE; + + /** + * The name of the resource that is used for service location. + */ + public static final String SERVICE_RESOURCE_NAME = "META-INF/services/commonj.sdo.impl.HelperProvider"; + + /** + * The name of the system property that will be checked for an implementation name. + */ + public static final String PROPERTY_NAME = "commonj.sdo.impl.HelperProvider"; + + static { + // initialize the default instance using this class's classloader + // set to null if none could be located (implies no default implementation) + HelperProvider provider; + try { + provider = getInstance(HelperProvider.class.getClassLoader()); + } catch (NoHelperProviderException e) { + provider = null; + } + INSTANCE = provider; + } + + public static synchronized void setDefaultInstance(ClassLoader cl) { + if (INSTANCE == null) { + try { + INSTANCE = getInstance(cl); + } catch (NoHelperProviderException e) { + } + } + } + + /** + * Locate and instantiate a HelperProvider. + * <p/> + * Attempt to locate a HelperProvider using first the Thread's current context classloader and then, + * if that is not set, not readable, or does not provide an implementation, using the classloader + * used to load the HelperProvider class itself. + * <p/> + * A new instance is returned for each sucessful invocation. + * + * @return an implementation of HelperProvider + * @throws NoHelperProviderException if no provider implementation was defined or it could not be instantiated + */ + public static HelperProvider getInstance() throws NoHelperProviderException { + String implName = getImplementationName(); + + ClassLoader cl = getContextClassLoader(); + if (cl != null) { + HelperProvider provider = loadImplementation(cl, implName); + if (provider != null) { + return provider; + } + } + + cl = HelperProvider.class.getClassLoader(); + HelperProvider provider = loadImplementation(cl, implName); + if (provider != null) { + return provider; + } + + throw new NoHelperProviderException(implName); + } + + + /** + * Locate and instantiate a HelperProvider using the supplied ClassLoader. + * <p/> + * The name of the implementation to use is determined by the value of the "commonj.sdo.impl.HelperProvider" + * system property. If this is not set or this code does not have permission to read it then the name + * will be retrieved from the META-INF/services/commonj.sdo.impl.HelperProvider resource as returned + * by the supplied classloader as described in the + * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">JAR file specification</a>. + * <p/> + * A new instance is returned for each sucessful invocation. + * + * @param cl the classloader to use to locate and instantiate the implementation + * @return the specified implementation of HelperProvider + * @throws NoHelperProviderException if no provider implementation was defined or it could not be instantiated + */ + public static HelperProvider getInstance(ClassLoader cl) throws NoHelperProviderException { + String implName = getImplementationName(); + HelperProvider provider = loadImplementation(cl, implName); + if (provider == null) { + throw new NoHelperProviderException(implName); + } + return provider; + } + + private static ClassLoader getContextClassLoader() { + try { + return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } catch (SecurityException e) { + return null; + } + } + + private static HelperProvider loadImplementation(ClassLoader cl, String implName) throws NoHelperProviderException { + // if no name is requested, locate using the supplied classloader + if (implName == null) { + implName = getImplementationName(cl); + } + // no implementation to try, return null + if (implName == null) { + return null; + } + + // try an instantiate the implementation + try { + return (HelperProvider) cl.loadClass(implName).newInstance(); + } catch (InstantiationException e) { + throw new NoHelperProviderException(implName, e); + } catch (IllegalAccessException e) { + throw new NoHelperProviderException(implName, e); + } catch (ClassNotFoundException e) { + throw new NoHelperProviderException(implName, e); + } + } + + private static String getImplementationName() { + try { + return (String)AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(PROPERTY_NAME); + } + }); + } catch (SecurityException e) { + return null; + } + } + + private static String getImplementationName(ClassLoader cl) { + InputStream is = cl.getResourceAsStream(SERVICE_RESOURCE_NAME); + if (is == null) { + return null; + } + + InputStreamReader in; + try { + in = new InputStreamReader(is, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new AssertionError("UTF-8 encoding not available"); + } + + try { + BufferedReader reader = new BufferedReader(in, 128); + try { + String line; + while ((line = reader.readLine()) != null) { + int i = line.indexOf('#'); + if (i != -1) { + line = line.substring(0, i); + } + line = line.trim(); + if (line.length() > 0) { + return line; + } + } + return null; + } finally { + reader.close(); + } + } catch (IOException e) { + throw new NoHelperProviderException(e); + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // implementation specific methods for users that don't want to use the default implementation + + /** + * Returns a CopyHelper obtained from this implementation. + * + * @return a CopyHelper obtained from this implementation + */ + public abstract CopyHelper copyHelper(); + + /** + * Returns a DataFactory obtained from this implementation. + * + * @return a DataFactory obtained from this implementation + */ + public abstract DataFactory dataFactory(); + + /** + * Returns a DataHelper obtained from this implementation. + * + * @return a DataHelper obtained from this implementation + */ + public abstract DataHelper dataHelper(); + + /** + * Returns a EqualityHelper obtained from this implementation. + * + * @return a EqualityHelper obtained from this implementation + */ + public abstract EqualityHelper equalityHelper(); + + /** + * Returns a TypeHelper obtained from this implementation. + * + * @return a TypeHelper obtained from this implementation + */ + public abstract TypeHelper typeHelper(); + + /** + * Returns a XMLHelper obtained from this implementation. + * + * @return a XMLHelper obtained from this implementation + */ + public abstract XMLHelper xmlHelper(); + + /** + * Returns a XSDHelper obtained from this implementation. + * + * @return a XSDHelper obtained from this implementation + */ + public abstract XSDHelper xsdHelper(); + + /** + * Create a Resolvable using this implementation + * + * @return a Resolvable created using this implementation + */ + public abstract ExternalizableDelegator.Resolvable resolvable(); + + /** + * Create a Resolvable using this implementation + * + * @param target the object to be resolved + * @return a Resolvable created using this implementation + */ + public abstract ExternalizableDelegator.Resolvable resolvable(Object target); + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // static helper methods required by the specification + + /** + * Returns a CopyHelper obtained from the default HelperProvider. + * + * @return a CopyHelper obtained from the default HelperProvider + */ + public static CopyHelper getCopyHelper() { + return INSTANCE.copyHelper(); + } + + /** + * Returns a DataFactory obtained from the default HelperProvider. + * + * @return a DataFactory obtained from the default HelperProvider + */ + public static DataFactory getDataFactory() { + return INSTANCE.dataFactory(); + } + + /** + * Returns a DataHelper obtained from the default HelperProvider. + * + * @return a DataHelper obtained from the default HelperProvider + */ + public static DataHelper getDataHelper() { + return INSTANCE.dataHelper(); + } + + /** + * Returns a EqualityHelper obtained from the default HelperProvider. + * + * @return a EqualityHelper obtained from the default HelperProvider + */ + public static EqualityHelper getEqualityHelper() { + return INSTANCE.equalityHelper(); + } + + /** + * Returns a TypeHelper obtained from the default HelperProvider. + * + * @return a TypeHelper obtained from the default HelperProvider + */ + public static TypeHelper getTypeHelper() { + return INSTANCE.typeHelper(); + } + + /** + * Returns a XMLHelper obtained from the default HelperProvider. + * + * @return a XMLHelper obtained from the default HelperProvider + */ + public static XMLHelper getXMLHelper() { + return INSTANCE.xmlHelper(); + } + + /** + * Returns a XSDHelper obtained from the default HelperProvider. + * + * @return a XSDHelper obtained from the default HelperProvider + */ + public static XSDHelper getXSDHelper() { + return INSTANCE.xsdHelper(); + } + + /** + * Create a Resolvable using the default HelperProvider + * + * @return a Resolvable created using the default HelperProvider + */ + public static ExternalizableDelegator.Resolvable createResolvable() { + return INSTANCE.resolvable(); + } + + /** + * Create a Resolvable using the default HelperProvider + * + * @param target the object to be resolved + * @return a Resolvable created using the default HelperProvider + */ + public static ExternalizableDelegator.Resolvable createResolvable(Object target) { + return INSTANCE.resolvable(target); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + // New in SDO 2.1 + //////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Gets the default HelperContext + * @return a HelperContext object + */ + public static HelperContext getDefaultContext() + { + return INSTANCE.helperContext(); + } + + HelperContext helperContext() + { + return defaultContext; + } + +// static HelperContext defaultContext = new DefaultHelperContext(); +// TODO: Tuscany SDO implementation specific to create a special implementation of HelperContext + protected static HelperContext defaultContext; + + static class DefaultHelperContext implements HelperContext + { + public CopyHelper getCopyHelper() { return INSTANCE.copyHelper(); } + public DataFactory getDataFactory() { return INSTANCE.dataFactory(); } + public DataHelper getDataHelper() { return INSTANCE.dataHelper(); } + public EqualityHelper getEqualityHelper() { return INSTANCE.equalityHelper(); } + public TypeHelper getTypeHelper() { return INSTANCE.typeHelper(); } + public XMLHelper getXMLHelper() { return INSTANCE.xmlHelper(); } + public XSDHelper getXSDHelper() { return INSTANCE.xsdHelper(); } + } + +} diff --git a/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/NoHelperProviderException.java b/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/NoHelperProviderException.java new file mode 100644 index 0000000000..83f0b21e2e --- /dev/null +++ b/sdo-java/branches/emf-2.5/sdo-api/src/main/java/commonj/sdo/impl/NoHelperProviderException.java @@ -0,0 +1,58 @@ +/** + * + * 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 commonj.sdo.impl; + +/** + * Exception indicating that a HelperProvider could not be located or instantiated. + * The message will be set to the name of the implementation class; a null value + * indicates that the name of the implementation could not be determined. + * The cause will be set to the Throwable that prevented the provider from being + * located or created. + * + * @version $Revision$ $Date$ + */ +public class NoHelperProviderException extends RuntimeException { + private static final long serialVersionUID = 727646133930924084L; + + public NoHelperProviderException() { + } + + public NoHelperProviderException(String message) { + super(message); + } + + public NoHelperProviderException(String message, Throwable cause) { + super(message, cause); + } + + public NoHelperProviderException(Throwable cause) { + super(cause); + } + + /** + * Return the name of the implementation class that could not be provided. + * + * @return the name of the implementation class; may be null if not known + */ + public String getImplementationName() { + return getMessage(); + } +} |