org.exolab.castor.mapping.loader.CollectionHandlers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of castor-xml Show documentation
Show all versions of castor-xml Show documentation
The core XML data binding framework with support for marshalling Java objects to
and unmarshalling from XML documents.
The newest version!
/**
* Redistribution and use of this software and associated documentation ("Software"), with or
* without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and notices. Redistributions
* must also contain a copy of this document.
*
* 2. 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.
*
* 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
* without prior written permission of Intalio, Inc. For written permission, please contact
* [email protected].
*
* 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
* their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
* Intalio, Inc.
*
* 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
*
* THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED 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 INTALIO, INC. OR ITS
* 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.
*
* Copyright 1999-2003 (C) Intalio, Inc. All Rights Reserved.
*
* $Id$
*/
package org.exolab.castor.mapping.loader;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.List;
import org.castor.core.util.AbstractProperties;
import org.castor.xml.XMLProperties;
import org.exolab.castor.mapping.CollectionHandler;
import org.exolab.castor.mapping.MappingException;
/**
* Utility class for obtaining collection handlers. Based on the configuration and supported classes
* it will return collections suitable for Java 1.1 and Java 1.2 run times.
*
* @author Assaf Arkin
* @version $Revision$ $Date: 2005-05-02 14:58:59 -0600 (Mon, 02 May 2005) $
* @see CollectionHandler
*/
public final class CollectionHandlers {
private static Info[] _info;
// For JDK 1.1 compatilibity
private static Class _collectionClass = null;
private static boolean _loadedCollectionClass = false;
static {
List allInfo = new ArrayList<>();
AbstractProperties properties = XMLProperties.newInstance();
StringTokenizer tokenizer = new StringTokenizer(
properties.getString(XMLProperties.COLLECTION_HANDLERS_FOR_JAVA_11_OR_12, ""), ", ");
while (tokenizer.hasMoreTokens()) {
try {
Class infoClass;
if (CollectionHandlers.class.getClassLoader() != null)
infoClass = CollectionHandlers.class.getClassLoader().loadClass(tokenizer.nextToken());
else
infoClass = Class.forName(tokenizer.nextToken());
Method method = infoClass.getMethod("getCollectionHandlersInfo", (Class[]) null);
Info[] info = (Info[]) method.invoke(null, (Object[]) null);
for (int i = 0; i < info.length; ++i)
allInfo.add(info[i]);
} catch (Exception except) {
// System.err.println( "CollectionHandlers: " + except.toString()
// );
}
}
_info = allInfo.toArray(new Info[allInfo.size()]);
}
/**
* Returns the collection's Java class from the collection name. The collection name may be a
* short name (e.g. vector) or the collection Java class name (e.g.
* java.util.Vector). If the collection is not supported, an exception is thrown.
*
* @param name The collection name
* @return The collection Java class
* @throws MappingException The named collection is not supported
*/
public static Class getCollectionType(String name) throws MappingException {
for (Info info : _info) {
if (info.getShortName().equalsIgnoreCase(name)
|| info.getJavaClass().getName().equals(name)) {
return info.getJavaClass();
}
}
// for (int i = 0; i < _info.length; ++i) {
// if (_info[i].getShortName().equalsIgnoreCase(name) ||
// _info[i].getJavaClass().getName().equals(name)) {
// return _info[i].getJavaClass();
// // throw new MappingException( "mapping.noCollectionHandler", name);
// }
// }
// -- Fix for JDK 1.1 compatibility
// old code: return Collection.class;
if (!_loadedCollectionClass) {
_loadedCollectionClass = true;
try {
_collectionClass = Class.forName("java.util.Collection");
} catch (ClassNotFoundException cnfe) {
// Do nothing we are just here for JDK 1.1
// compatibility
}
}
return _collectionClass;
}
/**
* Returns true if the given class has an associated CollectionHandler.
*
* @param javaClass the class to search collection handlers for
* @return true if the given class has an associated CollectionHandler, otherwise false.
*/
public static boolean hasHandler(Class javaClass) {
// -- Adjust javaClass for arrays, needed for arrays of
// -- primitives, except for byte[] which shouldn't
// -- use a collection handler
if (javaClass.isArray()) {
if (javaClass.getComponentType() != Byte.TYPE)
javaClass = Object[].class;
}
for (Info info : _info) {
if (info.getJavaClass().isAssignableFrom(javaClass)) {
return true;
}
}
// for (int i = 0; i < _info.length; ++i)
// if (_info[i].getJavaClass().isAssignableFrom(javaClass))
// return true;
return false;
}
/**
* Returns the associated string name for a given collection.
*
* @param javaClass the class to search collection handlers for
* @return the string name for the given collection type or null if no association has been
* defined.
*/
public static String getCollectionName(Class javaClass) {
// -- Adjust javaClass for arrays, needed for arrays of
// -- primitives, except for byte[] which shouldn't
// -- use a collection handler
if (javaClass.isArray()) {
if (javaClass.getComponentType() != Byte.TYPE)
javaClass = Object[].class;
}
// -- First check direct class equality, to provide a better match
// -- (for example in JDK 1.2 a Vector is also a Collection)
for (int i = 0; i < _info.length; ++i)
if (_info[i].getJavaClass().equals(javaClass))
return _info[i].getShortName();
// -- handle Possible inheritance
for (int i = 0; i < _info.length; ++i)
if (_info[i].getJavaClass().isAssignableFrom(javaClass))
return _info[i].getShortName();
return null;
} // -- hasHandler
/**
* Returns the collection's handler based on the Java class.
*
* @param javaClass The collection's Java class
* @return The collection handler
* @throws MappingException The collection class is not supported
*/
public static CollectionHandler getHandler(Class javaClass) throws MappingException {
// -- Adjust javaClass for arrays, needed for arrays of
// -- primitives, except for byte[] which shouldn't
// -- use a collection handler
if (javaClass.isArray()) {
if (javaClass.getComponentType() != Byte.TYPE)
javaClass = Object[].class;
}
// -- First check direct class equality, to provide a better match
// -- (for example in JDK 1.2 a Vector is also a Collection)
for (int i = 0; i < _info.length; ++i)
if (_info[i].getJavaClass().equals(javaClass))
return _info[i].handler;
// -- handle Possible inheritence
for (int i = 0; i < _info.length; ++i)
if (_info[i].getJavaClass().isAssignableFrom(javaClass))
return _info[i].handler;
throw new MappingException("mapping.noCollectionHandler", javaClass.getName());
}
/**
* Returns true if the collection requires get/set methods. java.util collections only
* require a get method, but an array collection required both get and set methods.
*
* @param javaClass The collection's java class
* @return True if collection requires get/set methods, false if collection requires only get
* method
* @throws MappingException The collection class is not supported
*/
public static boolean isGetSetCollection(Class javaClass) throws MappingException {
for (int i = 0; i < _info.length; ++i)
if (_info[i].getJavaClass().equals(javaClass))
return _info[i].getSetCollection;
throw new MappingException("mapping.noCollectionHandler", javaClass.getName());
}
static class Info {
/**
* The short name of the collection (e.g. vector).
*/
private final String shortName;
/**
* The Java class of the collection (e.g. java.util.Vector).
*/
private final Class javaClass;
/**
* The collection handler instance.
*/
private final CollectionHandler handler;
/**
* True for collections that require both get and set methods.
*/
final boolean getSetCollection;
Info(String shortName, Class javaClass, boolean getSetCollection,
CollectionHandler handler) {
this.shortName = shortName;
this.javaClass = javaClass;
this.handler = handler;
this.getSetCollection = getSetCollection;
}
String getShortName() {
return shortName;
}
Class getJavaClass() {
return javaClass;
}
CollectionHandler getHandler() {
return handler;
}
}
/**
* Enumerator for a null collection.
*/
public static final class EmptyEnumerator implements Enumeration, Serializable {
public boolean hasMoreElements() {
return false;
}
public T nextElement() {
throw new NoSuchElementException();
}
}
}