FileDocCategorySizeDatePackage
Model.javaAPI DocGlassfish v2 API63643Fri May 04 22:34:42 BST 2007com.sun.jdo.api.persistence.model

Model

public abstract class Model extends Object
author
raccah
version
%I%

Fields Summary
public static final Model
RUNTIME
Default instance of the model for use at runtime.
public static final Model
ENHANCER
Default instance of the model used by the enhancer.
public static final String[]
EQUALS_ARGS
Standard set of arguments for comparison with equals method.
public static final String[]
NO_ARGS
Standard set of empty arguments (for comparison with hashCode method and no-arg constructor).
public static final String[]
READ_OBJECT_ARGS
Standard set of arguments for comparison with readObject method.
public static final String[]
WRITE_OBJECT_ARGS
Standard set of arguments for comparison with writeObject method.
private final Map
_classes
Map of mapping class elements which have been loaded. Keys are fully qualified class names.
private final Set
_nonPCClasses
Set of fully qualified names of classes known to be non persistence-capable.
private static List
_illegalPrefixes
List of illegal package name prefixes for superclasses of persistence capable classes.
private static List
_illegalClasses
List of illegal class names for superclasses of persistence capable classes.
private static List
_scoClasses
List of class names for second class objects.
private static List
_mutableScoClasses
List of class names for mutable second class objects.
private static List
_collectionClasses
List of class names for collections.
public static final String
messageBase
I18N message base
private static final ResourceBundle
_messages
I18N message handler
Constructors Summary
Methods Summary
protected static com.sun.jdo.api.persistence.model.ModelNewModel(java.lang.String testName, java.lang.String modelName)
Create a new Model of the requested type. If the class definition exists in the class path of the environment, then this method will create a new instance of the Model.

param
modelName the fully qualified name of the class to be instantiated.
param
testName the fully qualified name of the class to be tested as a precondition to loading.
return
a new instance of the requested class (which implements Model).


	
	
		String prefixes[] =
			{"java.awt", "java.applet", "javax.swing", "javax.ejb"};// NOI18N
		String classes[] = {"java.lang.Throwable"};					// NOI18N
		String collectionClasses[] = { "java.util.Collection",		// NOI18N
			"java.util.AbstractCollection", 						// NOI18N
			//"java.util.List", "java.util.AbstractList",			// NOI18N
			"java.util.Set", "java.util.AbstractSet", 				// NOI18N
			//"java.util.ArrayList", "java.util.Vector", 			// NOI18N
			"java.util.HashSet", 									// NOI18N
			//"com.sun.jdo.spi.persistence.support.sqlstore.sco.ArrayList",	// NOI18N
			//"com.sun.jdo.spi.persistence.support.sqlstore.sco.Vector", // NOI18N
			"com.sun.jdo.spi.persistence.support.sqlstore.sco.HashSet"}; // NOI18N
		String mutableScoClasses[] = {"java.util.Date", 			// NOI18N
			"com.sun.jdo.spi.persistence.support.sqlstore.sco.Date", "java.sql.Date",// NOI18N
			"com.sun.jdo.spi.persistence.support.sqlstore.sco.SqlDate", // NOI18N
			"java.sql.Time", "com.sun.jdo.spi.persistence.support.sqlstore.sco.SqlTime", // NOI18N
			"java.sql.Timestamp", 									// NOI18N
			"com.sun.jdo.spi.persistence.support.sqlstore.sco.SqlTimestamp"};		// NOI18N
		String scoClasses[] = {"java.lang.String", 					// NOI18N
			"java.lang.Character", "java.lang.Boolean", 			// NOI18N
			"java.lang.Long", "java.lang.Number", "java.lang.Byte", // NOI18N
			"java.lang.Short", "java.lang.Integer", "java.lang.Float", // NOI18N
			"java.lang.Double", "java.math.BigDecimal",				// NOI18N
			"java.math.BigInteger"};								// NOI18N

		_illegalPrefixes = Arrays.asList(prefixes);
		_illegalClasses = Arrays.asList(classes);
		_collectionClasses = Arrays.asList(collectionClasses);
		_mutableScoClasses = new ArrayList(Arrays.asList(mutableScoClasses));
		_mutableScoClasses.addAll(_collectionClasses);
		_scoClasses = new ArrayList(Arrays.asList(scoClasses));
		_scoClasses.addAll(_mutableScoClasses);

		// always load the runtime model
		RUNTIME = NewModel(null, "com.sun.jdo.api.persistence.model.RuntimeModel"); //NOI18N
		// always load the enhancer model
		ENHANCER = NewModel(null, "com.sun.jdo.api.persistence.model.EnhancerModel"); //NOI18N
	
			Class DynamicClass = null;
			Model model = null;
			try {
				if (testName != null)
					// try this class as a precondition to the real class to load
					Class.forName (testName); 
				DynamicClass = Class.forName (modelName);
				if (DynamicClass != null)
					model = (Model) DynamicClass.newInstance();
			}
			catch (Exception e) {
				// this is expected in the environment
			}
			return model;
		
public booleanaddFieldElement(PersistenceClassElement element, java.lang.String fieldName)
Adds a PersistenceFieldElement for the specified field to the supplied PersistenceClassElement, creating a RelationshipElement if necessary.

param
element the persistence class element to be used
param
fieldName the name of the field to be added

		String fieldType = getFieldType(element.getName(), fieldName);
		boolean isCollection = isCollection(fieldType);

		try
		{
			// check if should be relationship here
			if (isPersistent(fieldType) || isCollection)
			{
				RelationshipElement relationship = new RelationshipElement(
					new RelationshipElementImpl(fieldName), element);

				if (isCollection)
				{
					relationship.setCollectionClass(
						getDefaultCollectionClass(fieldType));
				}
				else	// set upper bound = 1 (jdo model should really do this)
					relationship.setUpperBound(1);

				element.addField(relationship);
			}
			else
			{
				element.addField(new PersistenceFieldElement(new
					PersistenceFieldElementImpl(fieldName), element));
			}

			return true;
		}
		catch (ModelException e)
		{}	// will return false

		return false;
	
public voidconvertDefaultFields(java.lang.String className)
Adds the default allowable persistent fields to the persistent class with the specified name. This is the second phase of converting a class to be persistence-capable.

param
className the fully qualified name of the class
see
#createSkeletonMappingClass
see
#convertFields

		convertFields(className, getFields(className));
	
public voidconvertFields(java.lang.String className, java.util.List fields)
Adds the allowable persistent fields from the supplied list to the persistent class with the specified name.

param
className the fully qualified name of the class
param
fields a list of (short) field names
see
#convertDefaultFields

		PersistenceClassElement element = getPersistenceClass(className);

		if (element != null)
		{
			Iterator iterator = fields.iterator();

			// iterate the list of fields and create corresponding
			// PersistenceFieldElements (& RelationshipElements)
			while (iterator.hasNext())
			{
				String fieldName = (String)iterator.next();

				if (isPersistentAllowed(className, fieldName) &&
					shouldBePersistent(className, fieldName))
				{
					addFieldElement(element, fieldName);
				}
			}

			/* comment out -- not supporting concurrency groups for beta
			// add everything to one concurrency group by default
			PersistenceFieldElement[] persistentFields = element.getFields();
			if ((persistentFields != null) && (persistentFields.length > 0))
			{
				String defaultGroupName = I18NHelper.getMessage(getMessages(),
					"jdo.concurrency_group.default");
				ConcurrencyGroupElement group = new ConcurrencyGroupElement(
					new ConcurrencyGroupElementImpl(defaultGroupName), element);

				try
				{
					group.addFields(persistentFields);
					element.addConcurrencyGroup(group);
				}
				catch (ModelException e)
				{}	// just don't add this group
			}*/
		}
	
public voidconvertToPersistenceCapable(java.lang.String className, boolean flag)
Converts the class with the supplied name to or from persistence capable depending on the flag.

param
className the fully qualified name of the class
param
flag if true, convert this class to be persistence capable, if false, convert this class to be non-persistence capable
exception
IOException if there is some error converting the class

		boolean classIsPersistent = isPersistent(className);
		Exception conversionException = null;

		if (flag && !classIsPersistent &&
			isPersistenceCapableAllowed(className))
		{
			try
			{
				// this calls updateKeyForClass which updates 
				// the mapping cache and the set of classes known to be non PC
				createSkeletonMappingClass(className);
			}
			catch (Exception e)
			{
				// need to unconvert whatever partial conversion succeeded
				conversionException = e;
			}
		}

		if ((!flag && classIsPersistent) || (conversionException != null))
		{
			try
			{
				// delete the mapping file
				deleteFile(className, getFileNameWithExtension(className));

				synchronized (this._classes)
				{
					// remove the corresponding MappingClassElement from cache
					_classes.remove(className);
					
					// put the class in the set of classes known to be non PC
					_nonPCClasses.add(className);
				}
			}
			catch (Exception e)	// rethrow if not a problem during unconvert
			{
				if (conversionException == null)
					conversionException = e;
			}
		}

		if (conversionException != null)		// rethrow the exception
		{
			if (conversionException instanceof RuntimeException)
				throw (RuntimeException)conversionException;
			else if (conversionException instanceof IOException)
				throw (IOException)conversionException;
		}
	
public voidconvertToPersistenceCapable(java.lang.String className)
Converts the class with the supplied name to persistence-capable, then convert its default fields and save it to the xml file.

param
className the fully qualified name of the class
exception
IOException if there is some error storing the class

		convertToPersistenceCapable(className, true);
		convertDefaultFields(className);
		storeMappingClass(className);
	
protected abstract java.io.BufferedOutputStreamcreateFile(java.lang.String className, java.lang.String baseFileName, java.lang.String extension)
Creates a file with the given base file name and extension parallel to the supplied class (if it does not yet exist).

param
className the fully qualified name of the class
param
baseFileName the name of the base file
param
extension the file extension
return
the output stream for the specified resource, null if an error occurs or none exists
exception
IOException if there is some error creating the file

private voidcreateSkeletonMappingClass(java.lang.String className)
Creates a PersistenceClassElement with the specified name, then wraps it in a mapping class and stores it in the hash map of classes. This is the first phase of converting a class to be persistence-capable.

param
className the fully qualified name of the class
see
#convertDefaultFields
see
#updateKeyForClass

		PersistenceClassElement element = new PersistenceClassElement(
			new PersistenceClassElementImpl(className));

		updateKeyForClass(new MappingClassElementImpl(element), null);
	
protected abstract voiddeleteFile(java.lang.String className, java.lang.String fileName)
Deletes the file with the given file name which is parallel to the supplied class.

param
className the fully qualified name of the class
param
fileName the name of the file
exception
IOException if there is some error deleting the file

protected abstract java.lang.StringfindPenultimateSuperclass(java.lang.String className)
Returns the name of the second to top (top excluding java.lang.Object) superclass for the given class name.

param
className the fully qualified name of the class to be checked
return
the top non-Object superclass for className, className if an error occurs or none exists

public java.util.ListgetAllFields(java.lang.String className)
Returns a list of names of all the field elements in the class with the specified name. This list includes the inherited fields.

param
className the fully qualified name of the class to be checked
return
the names of the field elements for the specified class

		List returnList = new ArrayList();
		
		while (className != null)
		{
			returnList.addAll(getFields(className));
			className = getSuperclass(className);
		}

		return returnList;
	
public java.lang.ObjectgetClass(java.lang.String className)
Returns the class element with the specified className.

param
className the fully qualified name of the class to be checked
return
the class element for the specified className

		return getClass(className, null);
	
public abstract java.lang.ObjectgetClass(java.lang.String className, java.lang.ClassLoader classLoader)
Returns the class element with the specified className.

param
className the fully qualified name of the class to be checked
param
classLoader the class loader used to find mapping information
return
the class element for the specified className

public java.util.MapgetClassLoaderCache()
Returns an unmodifiable copy of the ClassLoader cache. This implementation returns null, but subclasses (such as RuntimeModel) can override this method if they support a class loader cache.

return
unmodifiable ClassLoader cache

		return null;
	
public abstract java.lang.ObjectgetConstructor(java.lang.String className, java.lang.String[] argTypeNames)
Returns the constructor element for the specified argument types in the class with the specified name. Types are specified as type names for primitive type such as int, float or as fully qualified class names.

param
className the name of the class which contains the constructor to be checked
param
argTypeNames the fully qualified names of the argument types
return
the constructor element
see
#getClass

public abstract java.lang.StringgetDeclaringClass(java.lang.Object memberElement)
Returns the string representation of declaring class of the specified member element. Note, the member element is either a class element as returned by getClass, a field element as returned by getField, a constructor element as returned by getConstructor, or a method element as returned by getMethod executed on the same model instance.

param
memberElement the member element to be checked
return
the string representation of the declaring class of the specified memberElement
see
#getClass
see
#getField
see
#getConstructor
see
#getMethod

public java.lang.StringgetDefaultCollectionClass(java.lang.String className)
Returns the default collection class for the specified class. If the specified class is an unspecified Collection type, the return will be HashSet.

param
className the fully qualified name of the class to be checked
return
the name of the default supported collection class for the specified class name.
see
#getFieldType
see
#getSupportedCollectionClasses

		String collectionClass = "java.util.HashSet";	// NOI18N

		// for dogwood, only support sets
	/*	if (className.indexOf("List") != -1)			// NOI18N
			collectionClass = "java.util.ArrayList";	// NOI18N
		else if ("java.util.Vector".equals(className))	// NOI18N
			collectionClass = className;
	*/
		return collectionClass;
	
public abstract java.lang.ObjectgetField(java.lang.String className, java.lang.String fieldName)
Returns the field element for the specified fieldName in the class with the specified className.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
the field element for the specified fieldName

public java.lang.StringgetFieldType(java.lang.String className, java.lang.String fieldName)
Returns the field type for the specified fieldName in the class with the specified className.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
the field type for the specified fieldName

		return getType(getField(className, fieldName));
	
public abstract java.util.ListgetFields(java.lang.String className)
Returns a list of names of all the declared field elements in the class with the specified name.

param
className the fully qualified name of the class to be checked
return
the names of the field elements for the specified class

protected java.lang.StringgetFileName(java.lang.String className)
Computes the base file name (without extension) for the supplied class name by converting the package name to a path name.

param
className the fully qualified name of the class
return
the base file name (without extension) for the supplied class name

		return ((className != null) ?
			className.replace('.", File.separatorChar) : null);
	
protected java.lang.StringgetFileNameWithExtension(java.lang.String className)
Computes the mapping file name (with extension) for the supplied class name by converting the package name to a path name.

param
className the fully qualified name of the class
return
the mapping file name (with extension) for the supplied class name
see
#getFileName
see
MappingClassElement#MAPPING_EXTENSION

		return getFileName(className) + "." + 						// NOI18N
			MappingClassElement.MAPPING_EXTENSION;
	
public java.lang.ObjectgetInheritedField(java.lang.String className, java.lang.String fieldName)
Returns the inherited field element for the specified fieldName in the class with the specified className. Note that the class with the specified className is not checked for this field, only superclasses are checked.

param
className the fully qualified name of the class which contains a superclass with the field to be checked
param
fieldName the name of the field to be checked
return
the field element for the specified fieldName

		String superClass = getSuperclass(className);
		Object field = null;

		while ((superClass != null) && 
			((field = getField(superClass, fieldName)) == null))
		{
			superClass = getSuperclass(superClass);
		}

		return field;
	
public java.lang.ObjectgetInheritedMethod(java.lang.String className, java.lang.String methodName, java.lang.String[] argTypeNames)
Returns the inherited method element for the specified method name and argument types in the class with the specified name. Types are specified as type names for primitive type such as int, float or as fully qualified class names. Note that the class with the specified className is not checked for this method, only superclasses are checked.

param
className the name of the class which contains the method to be checked
param
methodName the name of the method to be checked
param
argTypeNames the fully qualified names of the argument types
return
the method element
see
#getClass

		String superClass = getSuperclass(className);
		Object method = null;

		while ((superClass != null) && ((method = 
			getMethod(superClass, methodName, argTypeNames)) == null))
		{
			superClass = getSuperclass(superClass);
		}

		return method;
	
protected abstract java.io.BufferedInputStreamgetInputStreamForResource(java.lang.String className, java.lang.ClassLoader classLoader, java.lang.String resourceName)
Returns the input stream with the supplied resource name found with the supplied class name.

param
className the fully qualified name of the class which will be used as a base to find the resource
param
classLoader the class loader used to find mapping information
param
resourceName the name of the resource to be found
return
the input stream for the specified resource, null if an error occurs or none exists

public java.util.MapgetMappingCache()
Returns an unmodifiable copy of the MappingClassElement cache.

return
unmodifiable MappingClassElement cache

		return Collections.unmodifiableMap(_classes);
	
public com.sun.jdo.api.persistence.model.mapping.MappingClassElementgetMappingClass(java.lang.String className)
Returns the MappingClassElement created for the specified class name. This method looks up the class in the internal cache. If not present it loads the corresponding xml file containing the mapping information.

param
className the fully qualified name of the mapping class
return
the MappingClassElement for class, null if an error occurs or none exists

		return getMappingClass(className, null);
	
public com.sun.jdo.api.persistence.model.mapping.MappingClassElementgetMappingClass(java.lang.String className, java.lang.ClassLoader classLoader)
Returns the MappingClassElement created for the specified class name. This method looks up the class in the internal cache. If not present it loads the corresponding xml file containing the mapping information.

param
className the fully qualified name of the mapping class
param
classLoader the class loader used to find mapping information
return
the MappingClassElement for className, null if an error occurs or none exists
see
MappingClassElementImpl#forName

		// This method synchronizes the access of the _classes cache, 
		// rather than using a synchronized map. This is for optimization only. 
		// Otherwise two parallel calls would read the mapping file twice, 
		// create two MCE instances and the second MCE instance would replace 
		// the first in the cache.
		// Any other access of _classes potentially needs to be synchronized 
		// using the same variable _classes (e.g. updateKeyForClass).
		synchronized (this._classes)
		{
			MappingClassElement mappingClass =
				(MappingClassElement)_classes.get(className);

			if (mappingClass == null)
			{
				// check whether the class is known to be non PC
				if (_nonPCClasses.contains(className))
					return null;

				try
				{
					InputStream stream = getInputStreamForResource(className,
						classLoader, getResourceNameWithExtension(className));

					if (stream != null)
					{
						// if the file is empty, the archiver prints an 
						// exception, so protect against that case and 
						// return null without updating either cache
						if (stream.available() > 0)
						{
							XMLInputStream xmlInput = new XMLInputStream(stream,
								getClass().getClassLoader());

							mappingClass = 
								(MappingClassElement)xmlInput.readObject();
							xmlInput.close();

							// postUnarchive performs version number checking 
							// and possible format conversions
							mappingClass.postUnarchive();

							// can't call updateKeyForClass here there are cases
							// when the mapping class name doesn't match the
							// classname (such as copy/paste, move etc.)
							_classes.put(className, mappingClass);

							// update the modified flags for the mapping and 
							// persistence classes since the xml archiver uses 
							// all the set methods
							mappingClass.setModified(false);
							getPersistenceClass(mappingClass).
								setModified(false);
						}
					}
					else
					{
						// stream is null, mapping file does not exist => 
						// class is not PC, so store the class name in the 
						// set of classes known to be non PC
						_nonPCClasses.add(className);
					}
				}
				catch (ModelException e)
				{
					// MBO: print reason to logger
					LogHelperModel.getLogger().log(Logger.WARNING, 
						e.getMessage());
					return null;
				}
				catch (Exception e)
				{
					// MBO: print reason to logger
					LogHelperModel.getLogger().log(Logger.WARNING, 
						I18NHelper.getMessage(getMessages(),
						"file.cannot_read", className, e.toString())); //NOI18N
				}	// will return null
			}

			return mappingClass;
		}
	
protected static final java.util.ResourceBundlegetMessages()

return
I18N message handler for this element

		return _messages;
	
public abstract java.lang.ObjectgetMethod(java.lang.String className, java.lang.String methodName, java.lang.String[] argTypeNames)
Returns the method element for the specified method name and argument types in the class with the specified name. Types are specified as type names for primitive type such as int, float or as fully qualified class names.

param
className the name of the class which contains the method to be checked
param
methodName the name of the method to be checked
param
argTypeNames the fully qualified names of the argument types
return
the method element
see
#getClass

public abstract intgetModifiers(java.lang.Object memberElement)
Returns the modifier mask for the specified member element. Note, the member element is either a class element as returned by getClass, a field element as returned by getField, a constructor element as returned by getConstructor, or a method element as returned by getMethod executed on the same model instance.

param
memberElement the member element to be checked
return
the modifier mask for the specified memberElement
see
java.lang.reflect.Modifier
see
#getClass
see
#getField
see
#getConstructor
see
#getMethod

protected intgetModifiers(java.lang.String className, java.lang.String fieldName)
Returns the modifier mask for the specified fieldName in the class with the specified className.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
the modifier mask for the specified field
see
java.lang.reflect.Modifier

		return getModifiers(getField(className, fieldName));
	
public intgetModifiersForClass(java.lang.String className)
Returns the modifier mask for the specified className.

param
className the fully qualified name of the class to be checked
return
the modifier mask for the specified class
see
java.lang.reflect.Modifier

		return getModifiers(getClass(className));
	
protected PersistenceClassElementgetPersistenceClass(com.sun.jdo.api.persistence.model.mapping.MappingClassElement mappingClass)
Returns a PersistenceClassElement created from the mapping class.

param
mappingClass the mapping class element to which the persistence class is associated
return
the PersistenceClassElement for mappingClass, null if an error occurs or none exists
see
#getMappingClass

		return ((mappingClass == null) ? null :
			((MappingClassElementImpl)mappingClass).getPersistenceElement());
	
public PersistenceClassElementgetPersistenceClass(java.lang.String className)
Returns a PersistenceClassElement created from the specified class name. Since our implementation of the mapping model class includes the persistence class, this method finds the persistence class by extracting it from the mapping class for the supplied name.

param
className the fully qualified name of the persistence capable class to be returned
return
the PersistenceClassElement for className, null if an error occurs or none exists
see
#getMappingClass

		return getPersistenceClass(className, null);
	
public PersistenceClassElementgetPersistenceClass(java.lang.String className, java.lang.ClassLoader classLoader)
Returns a PersistenceClassElement created from the specified class name. Since our implementation of the mapping model class includes the persistence class, this method finds the persistence class by extracting it from the mapping class for the supplied name.

param
className the fully qualified name of the persistence capable class to be returned
param
classLoader the class loader used to find mapping information
return
the PersistenceClassElement for className, null if an error occurs or none exists
see
#getMappingClass

		return getPersistenceClass(getMappingClass(className, classLoader));
	
public PersistenceFieldElementgetPersistenceField(java.lang.String className, java.lang.String fieldName)
Returns the PersistenceFieldElement with the supplied fieldName found in the supplied className.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
the PersistenceFieldElement for the specified field, null if an error occurs or none exists

		return (hasField(className, fieldName) ? 
			getPersistenceFieldInternal(className, fieldName) : null);
	
protected PersistenceFieldElementgetPersistenceFieldInternal(java.lang.String className, java.lang.String fieldName)
Returns the PersistenceFieldElement with the supplied fieldName found in the supplied className.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
the PersistenceFieldElement for the specified field, null if an error occurs or none exists

		PersistenceClassElement classElement = getPersistenceClass(className);

		return ((classElement != null) ? 
			classElement.getField(fieldName) : null);
	
public java.lang.StringgetRelatedClass(RelationshipElement element)
Gets the name of the related class for a relationship element. This method is added so that there is a common way to do this. It checks if the argument is a collection relationship element (in which case the element class should be returned) or not (in which case the type should be returned). This should really be handled by the jdo model directly, but it doesn't have access to the Model which is necessary for finding the field type and whether it is a collection or not.

param
element the relationship element to be examined
return
the name of the related class

		if (element != null)
		{
			String fieldType = getFieldType(
				element.getDeclaringClass().getName(), element.getName());
			String relatedClass =  (isCollection(fieldType) ?
				element.getElementClass() : fieldType);

			return (StringHelper.isEmpty(relatedClass) ? null : 
				relatedClass.trim());
		}

		return null;
	
protected java.lang.StringgetResourceName(java.lang.String className)
Computes the base resource name (without extension) for the supplied class name by converting the package name to a resource name.

param
className the fully qualified name of the class
return
the base resource name (without extension) for the supplied class name

		return ((className != null) ?
			className.replace('.", '/") : null);
	
protected java.lang.StringgetResourceNameWithExtension(java.lang.String className)
Computes the mapping file resource name (with extension) for the supplied class name by converting the package name to a resource name.

param
className the fully qualified name of the class
return
the mapping file resource name (with extension) for the supplied class name
see
MappingClassElement#MAPPING_EXTENSION

		return getResourceName(className) + "." + 					// NOI18N
			MappingClassElement.MAPPING_EXTENSION;
	
protected abstract java.lang.StringgetSuperclass(java.lang.String className)
Returns the name of the superclass for the given class name.

param
className the fully qualified name of the class to be checked
return
thesuperclass for className, null if an error occurs or none exists

public java.util.ArrayListgetSupportedCollectionClasses(java.lang.String className)
Computes the list of names of the possible collection classes for the specified class.

param
className the fully qualified name of the class to be checked
return
an array of supported collection classes for the specified class name.
see
#getFieldType
see
#getDefaultCollectionClass

		String supportedSet = "java.util.HashSet";		// NOI18N
	//	String supportedList = "java.util.ArrayList";	// NOI18N
	//	String supportedVector = "java.util.Vector";	// NOI18N
		ArrayList returnList = new ArrayList();

		// for dogwood, only support sets
		returnList.add(supportedSet);
	/*	if (className.indexOf("Collection") != -1)	// NOI18N
		{
			returnList.add(supportedSet);
			returnList.add(supportedList);
			returnList.add(supportedVector);
		}
		else if (className.indexOf("List") != -1)	// NOI18N
			returnList.add(supportedList);
		else if (className.indexOf("Set") != -1)	// NOI18N
			returnList.add(supportedSet);
		else if (supportedVector.equals(className))
			returnList.add(supportedVector);
	*/
		return returnList;
	
public abstract java.lang.StringgetType(java.lang.Object element)
Returns the string representation of type of the specified element. If element denotes a field, it returns the type of the field. If element denotes a method, it returns the return type of the method. Note, element is either a field element as returned by getField, or a method element as returned by getMethod executed on the same model instance.

param
element the element to be checked
return
the string representation of the type of the element
see
#getField
see
#getMethod

public booleanhasClass(java.lang.String className)
Determines if a class with the specified className exists.

param
className the fully qualified name of the class to be checked
return
true if this class name represents a valid class; false otherwise.

		return hasClass(className, null);
	
public booleanhasClass(java.lang.String className, java.lang.ClassLoader classLoader)
Determines if a class with the specified className exists.

param
className the fully qualified name of the class to be checked
param
classLoader the class loader used to find mapping information
return
true if this class name represents a valid class; false otherwise.

		return (getClass(className, classLoader) != null);
	
public abstract booleanhasConstructor(java.lang.String className)
Determines if the class with the specified name declares a constructor.

param
className the name of the class to be checked
return
true if the class declares a constructor; false otherwise.
see
#getClass

public booleanhasField(java.lang.String className, java.lang.String fieldName)
Determines if a field with the specified fieldName exists in the class with the specified className.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a valid field; false otherwise.

		return (getField(className, fieldName) != null);
	
public booleanhasPersistentSuperclass(java.lang.String className)
Determines if the specified className has a persistent superclass.

param
className the fully qualified name of the class to be checked
return
true if this class name represents a class which has a persistent superclass (anywhere in the inheritance chain); false otherwise.

		while ((className = getSuperclass(className)) != null)
		{
			if (isPersistent(className))
				return true;
		}

		return false;
	
public abstract booleanimplementsInterface(java.lang.Object classElement, java.lang.String interfaceName)
Determines if the specified class implements the specified interface. Note, class element is a model specific class representation as returned by a getClass call executed on the same model instance.

param
classElement the class element to be checked
param
interfaceName the fully qualified name of the interface to be checked
return
true if the class implements the interface; false otherwise.
see
#getClass

public abstract booleanisArray(java.lang.String className, java.lang.String fieldName)
Determines if a field with the specified fieldName in the class with the specified className is an array.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a java array field; false otherwise.
see
#getFieldType

public booleanisByteArray(java.lang.String className, java.lang.String fieldName)
Determines if a field with the specified fieldName in the class with the specified className is a byte array.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a byte array field; false otherwise.
see
#getFieldType

		return isByteArray(getFieldType(className, fieldName));
	
protected booleanisByteArray(java.lang.String className)
Determines if the specified className represents a byte array.

param
className the fully qualified name of the class or type to be checked
return
true if this class represents a byte array; false otherwise.

		return ("byte[]".equals(className));		// NOI18N
	
public booleanisCollection(java.lang.String className)
Determines if the class name represents a collection.

param
className the fully qualified name of the class to be checked
return
true if this class represents a collection; false otherwise.
see
#getFieldType

		return _collectionClasses.contains(className);
	
public booleanisDefaultFetchGroup(java.lang.String className, java.lang.String fieldName)
Determines if the specified className and fieldName pair represent a field which is part of the default fetch group.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a field in the default fetch group; false otherwise.

		MappingClassElement mappingClass = getMappingClass(className);

		try
		{
			return (MappingFieldElement.GROUP_DEFAULT ==
				mappingClass.getField(fieldName).getFetchGroup());
		}
		catch (Exception e)
		{}	// will return false

		return false;
	
public abstract booleanisInterface(java.lang.String className)
Determines if the specified className represents an interface type.

param
className the fully qualified name of the class to be checked
return
true if this class name represents an interface; false otherwise.

public booleanisKey(java.lang.String className, java.lang.String fieldName)
Determines if the specified className and fieldName pair represent a key field.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a key field; false otherwise.

		if (hasField(className, fieldName))
		{
			PersistenceClassElement classElement =
				getPersistenceClass(className);

			if (classElement != null)
			{
				String keyClass = classElement.getKeyClass();

				if (keyClass != null)
					return hasField(keyClass, fieldName);
			}
		}

		return false;
	
public booleanisMutableSecondClassObject(java.lang.String className)
Determines if the specified className represents a mutable second class object. For this release, the class name is checked against a list of supported mutable second class objects since user-defined second class objects are not supported.

param
className the fully qualified name of the class to be checked
return
true if this class represents a mutable second class object; false otherwise.
see
#isSecondClassObject
see
#isCollection
see
#getFieldType

		return _mutableScoClasses.contains(className);
	
public booleanisPersistenceCapableAllowed(java.lang.String className)
Determines if the specified className represents a legal candidate for becoming a persistence capable class. A class may not become persistence capable if it is declared as static or abstract, an interface, a subclass of another persistence capable class (either direct or indirect), an exception subclass, or a subclass of ejb, swing, awt, or applet classes.

param
className the fully qualified name of the class to be checked
return
true if this class name represents a legal candidate for becoming a persistence capable class; false otherwise.
see
#getModifiersForClass
see
#isInterface
see
#findPenultimateSuperclass

		int modifier = getModifiersForClass(className);

		if (!Modifier.isStatic(modifier) && !Modifier.isAbstract(modifier) &&
			!isInterface(className) && !hasPersistentSuperclass(className))
		{
			String highestSuperclassName = findPenultimateSuperclass(className);
			Iterator iterator = _illegalPrefixes.iterator();

			while (iterator.hasNext())
			{
				String nextPrefix = iterator.next().toString();

				if (highestSuperclassName.startsWith(nextPrefix))
					return false;
			}

			iterator = _illegalClasses.iterator();
			while (iterator.hasNext())
			{
				String nextClass = iterator.next().toString();

				if (highestSuperclassName.equals(nextClass))
					return false;
			}

			return true;
		}

		return false;
	
public booleanisPersistent(java.lang.String className)
Determines if the specified className represents a persistence capable class. A class is persistence capable only if it is directly marked as such -- not by inheritance.

param
className the fully qualified name of the class to be checked
return
true if this class name represents a persistence capable class; false otherwise.

		return isPersistent(className, (ClassLoader)null);
	
public booleanisPersistent(java.lang.String className, java.lang.ClassLoader classLoader)
Determines if the specified className represents a persistence capable class. A class is persistence capable only if it is directly marked as such -- not by inheritance.

param
className the fully qualified name of the class to be checked
param
classLoader the class loader used to find mapping information
return
true if this class name represents a persistence capable class; false otherwise.

		return (getPersistenceClass(className, classLoader) != null);
	
public booleanisPersistent(java.lang.String className, java.lang.String fieldName)
Determines if the specified className and fieldName pair represent a persistent field.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a persistent field; false otherwise.

		PersistenceFieldElement fieldElement =
			getPersistenceField(className, fieldName);

		if (fieldElement != null)
		{
			return (PersistenceFieldElement.PERSISTENT ==
				fieldElement.getPersistenceType());
		}

		return false;
	
public booleanisPersistentAllowed(java.lang.String className, java.lang.String fieldName)
Returns true if the specified field can be made persistent, false otherwise. This computation is based on the modifier and type of the field. Fields which are non-final and non-static and are primitive, persistence capable, or second class objects and not arrays return true.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
whether the specified field can be made persistent
see
#getModifiers(String,String)
see
#isPrimitive
see
#isArray
see
#isPersistent
see
#isSecondClassObject
see
#shouldBePersistent

		return isPersistentAllowed(className, null, fieldName);
	
public booleanisPersistentAllowed(java.lang.String className, java.lang.ClassLoader classLoader, java.lang.String fieldName)
Returns true if the specified field can be made persistent, false otherwise. This computation is based on the modifier and type of the field. Fields which are non-final and non-static and are primitive, persistence capable, byte arrays, or second class objects and not arrays return true.

param
className the fully qualified name of the class which contains the field to be checked
param
classLoader the class loader used to find mapping information
param
fieldName the name of the field to be checked
return
whether the specified field can be made persistent
see
#getModifiers(String,String)
see
#getFieldType
see
#isPersistentTypeAllowed
see
#shouldBePersistent

		int modifier = getModifiers(className, fieldName);

		if (!Modifier.isStatic(modifier) && !Modifier.isFinal(modifier))
		{
			return isPersistentTypeAllowed(
				getFieldType(className, fieldName), classLoader);
		}

		return false;
	
protected booleanisPersistentTypeAllowed(java.lang.String className, java.lang.ClassLoader classLoader)
Returns true if the a field of the specified class or type can be made persistent, false otherwise. Fields which are primitive, persistence capable, byte arrays, or second class objects and not arrays return true.

param
className the fully qualified name of the class or type to be checked
param
classLoader the class loader used to find mapping information
return
true if this class represents a type which can be made persistent; false otherwise.
see
#isPrimitive
see
#isByteArray
see
#isPersistent
see
#isSecondClassObject

		return (isPrimitive(className) || isSecondClassObject(className) || 
			isByteArray(className) || isPersistent(className, classLoader));
	
public booleanisPrimitive(java.lang.String className, java.lang.String fieldName)
Determines if a field with the specified fieldName in the class with the specified className has a primitive type.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a primitive field; false otherwise.
see
#getFieldType

		return isPrimitive(getFieldType(className, fieldName));
	
protected booleanisPrimitive(java.lang.String className)
Determines if the specified className represents a primitive type.

param
className the fully qualified name of the class or type to be checked
return
true if this class represents a primitive; false otherwise.
see
#getFieldType

		return ((className != null) && 
			JavaTypeHelper.getPrimitiveClass(className) != null);
	
public booleanisSecondClassObject(java.lang.String className)
Determines if the specified className represents a second class object. For this release, the class name is checked against a list of supported second class objects since user-defined second class objects are not supported.

param
className the fully qualified name of the class to be checked
return
true if this class represents a second class object; false otherwise.
see
#isMutableSecondClassObject
see
#isCollection
see
#getFieldType

		return _scoClasses.contains(className);
	
public abstract booleanisSerializable(java.lang.Object fieldElement)
Determines if the specified field element has a serializable type. A type is serializable if it is a primitive type, a class that implements java.io.Serializable or an interface that inherits from java.io.Serializable. Note, the field element is a model specific field representation as returned by a getField call executed on the same model instance.

param
fieldElement the field element to be checked
return
true if the field element has a serializable type; false otherwise.
see
#getField

public booleanisValidKeyType(java.lang.String className, java.lang.String fieldName)
Determines if the specified className and fieldName pair represent a field which has a type which is valid for key fields. Valid key field types include non-collection SCOs (wrappers, Date, Time, etc.) and primitives.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
true if this field name represents a field with a valid type for a key field; false otherwise.

		String fieldType = getFieldType(className, fieldName);

		if (fieldType == null)
			fieldType = getType(getInheritedField(className, fieldName));

		return (isPrimitive(fieldType) || 
			(isSecondClassObject(fieldType) && !isCollection(fieldType)));
	
public voidlockFile(java.lang.String className)

public booleanparse(java.lang.String className)
Parses the combination of java (or class) information and mapping/jdo information by running through a subset of the full validation check and aborting (and returning false at the first error or warning.

param
className the fully qualified name of the class to be checked
return
true if no errors or warnings occur, false otherwise.

		return new ModelValidator(this, className, getMessages()).parseCheck();
	
public voidremoveFieldElement(PersistenceFieldElement element)
Removes the specified PersistenceFieldElement from its declaring class. This method is added so that there is a common way to do this which checks if the argument is a relationship element with an inverse (in which case the inverse should first be cleared). This should really be handled by the jdo model directly, but the removeField method doesn't have access to the Model which is necessary for setting (or clearing) inverse relationships.

param
element the persistence field element to be removed
exception
ModelException if there is some error removing the field

		if (element != null)
		{
			if (element instanceof RelationshipElement)
			{
				((RelationshipElement)element).setInverseRelationship(null,
					this);
			}

			element.getDeclaringClass().removeField(element);
		}
	
public voidremoveFromCache(java.lang.String className)
Removes the class with the supplied name from the cache of classes known to be non PC. The next call getMappingClass will determine the status of the class.

param
className the fully qualified name of the class

		synchronized (this._classes)
		{
			// remove the class from the set of classes known to be non PC
			_nonPCClasses.remove(className);
		}
	
public voidremoveResourcesFromCaches(java.lang.ClassLoader classLoader)
Removes the classes cached with the specified class loader from all caches. This implementation does nothing, but subclasses (such as RuntimeModel) can override this method if they support a class loader cache.

param
classLoader used to determine the classes to be removed

		// Do nothing in the top-level model.
	
protected voidremoveResourcesFromCaches(java.util.Collection classNames)
Removes the specified classes from all caches. The specified collection includes the fully qualified class names of the classes to be removed. The method removes each class from the cache of MappingClassElements and the set of classes known to be non PC. Furthermore it removes the SchemaElement associated with this class from the SchemaElement cache. The next call getMappingClass will determine the status of the classes.

param
classNames a collection of fully qualified class names

		if (classNames == null)
			return;

		synchronized (this._classes)
		{
			for (Iterator i = classNames.iterator(); i.hasNext();)
			{
				String className = (String)i.next();
				MappingClassElement mapping = 
					(MappingClassElement)_classes.get(className);

				// If the cache has a MappingClassElement with the specified
				// className, get its databaseRoot and remove the corresonding
				// SchemaElement from the SchemaElement cache. 
				if (mapping != null)
					SchemaElement.removeFromCache(mapping.getDatabaseRoot());
				
				// remove the corresponding MappingClassElement from cache
				_classes.remove(className);
				
				// remove the class from the set of classes known to be non PC
				_nonPCClasses.remove(className);
			}
		}
	
public booleanshouldBePersistent(java.lang.String className, java.lang.String fieldName)
Returns true if the specified field should be made persistent (i.e. does it make sense), false otherwise. This computation is based solely on the modifier: those which are not volatile return true.

param
className the fully qualified name of the class which contains the field to be checked
param
fieldName the name of the field to be checked
return
whether the specified field should be made persistent see #getModifiers(String,String)

		return !Modifier.isVolatile(getModifiers(className, fieldName));
	
public voidstoreMappingClass(com.sun.jdo.api.persistence.model.mapping.MappingClassElement mappingClass)
Stores the supplied MappingClassElement to an xml file, creating the file if necessary. The caller is responsible for updating the cache by calling updateKeyForClass, if necessary.

param
mappingClass the mapping class to be saved
exception
IOException if there is some error saving the class
see
#createFile

		if (mappingClass != null)
		{
			String className = mappingClass.getName();
			OutputStream stream = ((className == null) ? null :
				createFile(className, getFileName(className),
				MappingClassElement.MAPPING_EXTENSION));

			storeMappingClass(mappingClass, stream);
		}
	
public voidstoreMappingClass(com.sun.jdo.api.persistence.model.mapping.MappingClassElement mappingClass, java.io.OutputStream stream)
Stores the supplied MappingClassElement to an xml file in the specified output stream. The caller is responsible for updating the cache by calling updateKeyForClass, if necessary.

param
mappingClass the mapping class to be saved
param
stream the output stream
exception
IOException if there is some error saving the class
see
#createFile

		if (mappingClass != null)
		{
			String className = mappingClass.getName();

			if (stream != null)
			{
				XMLOutputStream xmlOutput = new XMLOutputStream(stream);

				try
				{
					mappingClass.preArchive();		// call pre archive hook
					xmlOutput.writeObject(mappingClass);

					// update modified flags for the mapping and persistence
					// classes after save
					mappingClass.setModified(false);
					getPersistenceClass(mappingClass).setModified(false);
				}
				catch (ModelException e)
				{
					// MBO: print reason to logger
					LogHelperModel.getLogger().log(Logger.WARNING, 
						e.getMessage());
				}
				finally
				{
					if (xmlOutput != null)
						xmlOutput.close();

					unlockFile(stream, className);
				}
				return;
			}

			throw new IOException(I18NHelper.getMessage(getMessages(),
				"file.cannot_save", className));				// NOI18N
		}
	
public voidstoreMappingClass(java.lang.String className)
Stores the MappingClassElement for the specified class name to an xml file, creating the file if necessary. The MappingClassElement must be present in the HashMap of classes known by the Model in order to stored.

param
className the fully qualified name of the mapping class
exception
IOException if there is some error saving the class
see
#storeMappingClass

		MappingClassElement mappingClass = null;

		synchronized (this._classes)
		{
			mappingClass = (MappingClassElement)_classes.get(className);
		}
		storeMappingClass(mappingClass);
	
public voidunlockFile(java.io.OutputStream stream, java.lang.String className)

		unlockFile(className);

		if (stream != null)
			stream.close();
	
public voidunlockFile(java.lang.String className)

public voidupdateKeyForClass(com.sun.jdo.api.persistence.model.mapping.MappingClassElement mappingClass, java.lang.String oldName)
Updates the key in the cache for the supplied MappingClassElement.

param
mappingClass the mapping class to be put in the cache (the new name is extracted from this element). The corresponding handling of the files is automatically handled by the data object. (use null to remove the old key but not replace it)
param
oldName the fully qualified name of the old key for the mapping class (use null to add the new key but not replace it)

		// need to synchronize _classes access here 
		// (for details see getMappingClass)
		synchronized (this._classes)
		{
			// remove the old key from the cache
			if (oldName != null)
				_classes.remove(oldName);

			// store the class under the new key in the cache
			if (mappingClass != null)
			{
				String className = mappingClass.getName();

				_classes.put(className, mappingClass);

				// ensure that the name of the mappingClass does not occur 
				// in the list of classes known to be non PC
				_nonPCClasses.remove(className);
			}
		}
	
public java.util.Collectionvalidate(java.lang.String className, java.util.ResourceBundle bundle)
Validates the combination of java (or class) information and mapping/jdo information by running through the full validation check and returning a collection of ModelValidationExceptions containing any errors or warnings encountered.

param
className the fully qualified name of the class to be checked
param
bundle the overridden resource bundle file - specify null if the default one should be used
return
a collection of ModelValidationExceptions containing any errors or warnings encountered. If no errors or warnings were encountered, the collection will be empty, not null.

		return validate(className, null, bundle);
	
public java.util.Collectionvalidate(java.lang.String className, java.lang.ClassLoader classLoader, java.util.ResourceBundle bundle)
Validates the combination of java (or class) information and mapping/jdo information by running through the full validation check and returning a collection of ModelValidationExceptions containing any errors or warnings encountered.

param
className the fully qualified name of the class to be checked
param
classLoader the class loader used to find mapping information
param
bundle the overridden resource bundle file - specify null if the default one should be used
return
a collection of ModelValidationExceptions containing any errors or warnings encountered. If no errors or warnings were encountered, the collection will be empty, not null.

		return new ModelValidator(this, className, classLoader, 
			((bundle == null) ? getMessages() : bundle)).fullValidationCheck();