JDOMetaDataPropertiespublic final class JDOMetaDataProperties extends Object This class parses properties containing meta data information
about classes. The syntax of the properties is the following:
-
the keys in the properties file are fully qualified classnames or
fully qualified fieldnames
-
a fields is separated by a classname with a hash mark ('#')
(e.g. "test.Test#test1")
-
all classnames are given in a natural form (e.g. "java.lang.Integer",
"java.lang.Integer[][]", "int", "test.Test$Test1")
-
property keys are classnames and fieldnames
(e.g. "test.Test=...", "test.Test#field1=...")
-
Classnames can have the following attributes:
-
jdo:{persistent|transactional}
-
super: <classname>
-
access: {public|protected|package|private}
-
Fieldnames can have the following attributes:
-
type:<type>
-
access: {public|protected|package|private}
-
jdo:{persistent|transactional|transient}
-
annotation:{pk|dfg|mediated}
-
the names of the attributes can be ommitted: you can say
test.Test1#field1=jdo:persistent,type:java.lang.String,pk,...
or
test.Test1#field1=persistent,java.lang.String,pk,...
or
test.Test1#field1=jdo:persistent,java.lang.String,pk,...
-
in order to find fields of a class, a line for the class has to be
specified in the properties: To find the field
test.Test1#field , the keys test.Test1 and
test.Test1#Field have to be present.
This class is not thread safe. |
Fields Summary |
---|
private static final char | FIELD_DELIMITERThe delimiter of a property key between the class- and fieldname. | private static final String | PROPERTY_DELIMITERSA string of delimiter characters between attributes. | private static final char | PROPERTY_ASSIGNERA delimiter character between attribute name and attribute value | private static final String | PROPERTY_ACCESS_MODIFIER | private static final String | PROPERTY_JDO_MODIFIER | private static final String | PROPERTY_SUPER_CLASSNAME | private static final String | PROPERTY_OID_CLASSNAME | private static final String | PROPERTY_TYPE | private static final String | PROPERTY_ANNOTATION_TYPE | private static final String | ACCESS_PRIVATE | private static final String | ACCESS_PACKAGE_LOCAL | private static final String | ACCESS_PROTECTED | private static final String | ACCESS_PUBLIC | private static final String | JDO_TRANSIENT | private static final String | JDO_PERSISTENT | private static final String | JDO_TRANSACTIONAL | private static final String | ANNOTATION_TYPE_PK | private static final String | ANNOTATION_TYPE_DFG | private static final String | ANNOTATION_TYPE_MEDIATED | private Properties | propertiesThe properties to parse. | private final Map | cachedJDOClassesA map of already read class properties. The keys are the
classnames, the values are the appropriate
JDOClass -object. | private static final JDOClass | NULLA constant for the cache indicating that a given classname
if not specified in the properties. | private final List | tmpTokensA temporary vector (this is the reason why the implementation is not
thread safe). |
Constructors Summary |
---|
public JDOMetaDataProperties(Properties props)Creates a new object with the given properties.
this.properties = props;
|
Methods Summary |
---|
private static final void | checkForDuplicateProperties(java.util.List props, java.lang.String entry)Checks if an attribute-property was entered twice for a class or field.
for (int i = 0; i < props.size (); i++)
{
for (int j = i + 1; j < props.size (); j++)
{
Property p1 = (Property) props.get (i);
Property p2 = (Property) props.get (j);
if (p1.name.equals (p2.name) && ! p1.value.equals (p2.value))
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_DUPLICATE_PROPERTY_NAME,
new String [] { entry, p1.name, p1.value, p2.value }));
}
}
}
| private static final void | checkPropertyName(java.lang.String name, java.lang.String[] validnames, java.lang.String entry)Checks if an attribute name is recognized by the parser.
for (int i = 0; i < validnames.length; i++)
{
if (name.equals (validnames [i]))
{
return;
}
}
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_INVALID_PROPERTY_NAME,
new String [] { entry, name }));
| private static final void | checkPropertyValue(com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$Property prop, java.lang.String[] validvalues, java.lang.String name, java.lang.String entry)Checks if the given value of an attribute-property is recognized by
by the parser if that value belongs to a given attribute name.
if ( ! prop.name.equals (name))
{
return;
}
for (int i = 0; i < validvalues.length; i++)
{
if (prop.value.equals (validvalues [i]))
{
return;
}
}
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_INVALID_PROPERTY_VALUE,
new String [] { entry, name, prop.value }));
| private static final java.lang.String | fromCanonicalClassName(java.lang.String classname)Converts a classname given in a canonical form (with dots) into
a VM-similar notation (with slashes)
return classname.replace ('.", '/");
| static final java.lang.String | getErrorMsg(java.lang.String msg, java.lang.String[] params)Formats an error message with the given parameters.
return MessageFormat.format (msg, (Object []) params);
| public final com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOClass | getJDOClass(java.lang.String classname)Get the information about the class with the given name.
classname = toCanonicalClassName (classname);
JDOClass clazz = (JDOClass) this.cachedJDOClasses.get (classname);
if (clazz == NULL) //already searched but not found
{
return null;
}
if (clazz != null)
{
return clazz;
}
//load it from the properties file
String s = this.properties.getProperty (classname);
if (s == null) //class not defined
{
this.cachedJDOClasses.put (classname, NULL);
return null;
}
//the class could be found in the properties
clazz = parseJDOClass (classname, s); //parse the class attributes
parseJDOFields (clazz); //parse all fields
validateDependencies (clazz); //check dependencies
this.cachedJDOClasses.put (clazz.getName (), clazz);
return clazz;
| public final com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOField | getJDOField(java.lang.String fieldname, java.lang.String classname)Gets the information about the specified field.
JDOClass clazz = getJDOClass (classname);
return (clazz != null ? clazz.getField (fieldname) : null);
| public final java.lang.String[] | getKnownClassNames()Gets all classnames in the properties.
Collection classnames = new HashSet ();
for (Enumeration names = this.properties.propertyNames (); names.hasMoreElements ();)
{
String name = (String) names.nextElement ();
if (name.indexOf (FIELD_DELIMITER) < 0)
{
classnames.add (fromCanonicalClassName (name));
}
}
return (String []) classnames.toArray (new String [classnames.size ()]);
| private static final int | getModifiers(java.lang.String modifier)
if (modifier.equals (ACCESS_PUBLIC))
{
return Modifier.PUBLIC;
}
if (modifier.equals (ACCESS_PRIVATE))
{
return Modifier.PRIVATE;
}
if (modifier.equals (ACCESS_PROTECTED))
{
return Modifier.PROTECTED;
}
return 0;
| private final com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOClass | parseJDOClass(java.lang.String classname, java.lang.String attributes)Parses the attributes-string of a class and puts them into a
JDOClass -object.
List props = parseProperties (attributes);
//check each property
for (int i = 0; i < props.size (); i++)
{
Property prop = (Property) props.get (i);
validateClassProperty (prop, classname);
}
//check dependencies of all properties
checkForDuplicateProperties (props, classname);
//properties are OK - assign them to the JDOClass object
JDOClass clazz = new JDOClass (classname);
for (int i = 0; i < props.size (); i++)
{
Property prop = (Property) props.get (i);
if (prop.name.equals (PROPERTY_ACCESS_MODIFIER))
{
clazz.modifiers = getModifiers (prop.value);
}
else if (prop.name.equals (PROPERTY_JDO_MODIFIER))
{
clazz.isPersistent = prop.value.equals (JDO_PERSISTENT);
}
else if (prop.name.equals (PROPERTY_SUPER_CLASSNAME))
{
clazz.setSuperClassName (prop.value);
}
else if (prop.name.equals(PROPERTY_OID_CLASSNAME)) {
clazz.setOidClassName(prop.value);
}
}
return clazz;
| private final com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOField | parseJDOField(java.lang.String attributes, java.lang.String fieldname, com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOClass clazz)Parses the attribute-string of a field.
List props = parseProperties (attributes);
//check each property
for (int i = 0; i < props.size (); i++)
{
Property prop = (Property) props.get (i);
validateFieldProperty (prop, fieldname, clazz.getName ());
}
//check dependencies of all properties
checkForDuplicateProperties (props, clazz.getName () + FIELD_DELIMITER + fieldname);
//properties are OK - assign them to the JDOField object
JDOField field = new JDOField (fieldname);
for (int i = 0; i < props.size (); i++)
{
Property prop = (Property) props.get (i);
if (prop.name.equals (PROPERTY_ACCESS_MODIFIER))
{
field.modifiers = getModifiers (prop.value);
}
else if (prop.name.equals (PROPERTY_JDO_MODIFIER))
{
field.jdoModifier = prop.value;
}
else if (prop.name.equals (PROPERTY_TYPE))
{
field.setType (prop.value);
}
else if (prop.name.equals (PROPERTY_ANNOTATION_TYPE))
{
field.annotationType = prop.value;
}
}
return field;
| private final void | parseJDOFields(com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOClass clazz)Parses all fields of a given class.
//search for fields of the class
for (Enumeration names = this.properties.propertyNames (); names.hasMoreElements ();)
{
String name = (String) names.nextElement ();
if (name.startsWith (clazz.getName () + FIELD_DELIMITER)) //field found
{
String fieldname = name.substring (name.indexOf (FIELD_DELIMITER) + 1, name.length ());
validateFieldName (fieldname, clazz.getName ());
clazz.addField (parseJDOField (this.properties.getProperty (name), fieldname, clazz));
}
}
clazz.sortFields ();
| final java.util.List | parseProperties(java.lang.String attributes)Parses the attribute-string of a class- or fieldname.
this.tmpTokens.clear ();
StringTokenizer t = new StringTokenizer (attributes, PROPERTY_DELIMITERS);
while (t.hasMoreTokens ())
{
this.tmpTokens.add (parseProperty (t.nextToken ()));
}
return this.tmpTokens;
| private final com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$Property | parseProperty(java.lang.String attribute)Parses the given attribute and splits it into name and value.
Property prop = new Property ();
int idx = attribute.indexOf (PROPERTY_ASSIGNER);
if (idx < 0)
{
prop.value = attribute;
}
else
{
prop.name = attribute.substring (0, idx);
prop.value = attribute.substring (idx + 1, attribute.length ());
if (prop.name.length () == 0 || prop.value.length () == 0)
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_EMPTY_PROPERTY_NAME_OR_VALUE,
new String [] { attribute }));
}
}
return prop;
| private static final java.lang.String | toCanonicalClassName(java.lang.String classname)Converts a classname given in a given VM-similar notation (with slashes)
into a canonical notation (with dots).
return classname.replace ('/", '.");
| private static final void | validateClassProperty(com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$Property prop, java.lang.String classname)Checks if the given attribute-property of a class is valid.
String value = prop.value;
if (prop.name == null) //try to guess the property name
{
//check access modifier
if (value.equals (ACCESS_PUBLIC) ||
value.equals (ACCESS_PROTECTED) ||
value.equals (ACCESS_PACKAGE_LOCAL) ||
value.equals (ACCESS_PRIVATE))
{
prop.name = PROPERTY_ACCESS_MODIFIER;
}
//check persistence
else if (value.equals (JDO_PERSISTENT) ||
value.equals (JDO_TRANSIENT))
{
prop.name = PROPERTY_JDO_MODIFIER;
}
//assume the the given value is the superclassname
else
{
prop.name = PROPERTY_SUPER_CLASSNAME;
}
}
else
{
//do we have a valid property name?
String name = prop.name;
checkPropertyName (prop.name, new String []
{
PROPERTY_OID_CLASSNAME,
PROPERTY_ACCESS_MODIFIER,
PROPERTY_JDO_MODIFIER,
PROPERTY_SUPER_CLASSNAME
}, classname);
//do we have a valid property value?
checkPropertyValue (prop,
new String []
{
ACCESS_PUBLIC,
ACCESS_PROTECTED,
ACCESS_PACKAGE_LOCAL,
ACCESS_PRIVATE
},
PROPERTY_ACCESS_MODIFIER,
classname);
checkPropertyValue (prop,
new String [] { JDO_TRANSIENT, JDO_PERSISTENT },
PROPERTY_JDO_MODIFIER,
classname);
}
| private final void | validateDependencies(com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$JDOClass clazz)Validates dependencies between a class and its fields and between.
for (int i = clazz.fields.size () - 1; i >= 0; i--)
{
JDOField field = (JDOField) clazz.fields.get (i);
//set the jdo field modifier according to the jdo class modifier (if jdo field not set yet)
if (field.jdoModifier == null)
{
field.jdoModifier = (clazz.isPersistent () ? JDO_PERSISTENT : JDO_TRANSIENT);
}
//if we have a non-persistent class
else if (clazz.isTransient ())
{
//non-persistent classes cannot have persistent fields
if (field.isPersistent ())
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_TRANSIENT_CLASS_WITH_PERSISTENT_FIELD,
new String [] { clazz.getName (), field.getName () }));
}
//non-persistent classes cannot have transactional fields
if (field.isTransactional ())
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_TRANSIENT_CLASS_WITH_TRANSACTIONAL_FIELD,
new String [] { clazz.getName (), field.getName () }));
}
}
//a non-persistent class cannot have an annotated field
if (field.isAnnotated () && clazz.isTransient ())
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_TRANSIENT_CLASS_WITH_ANNOTATED_FIELD,
new String [] { clazz.getName (), field.getName () }));
}
//a non-persistent field cannot have an annotation type
if ( ! field.isPersistent () && field.isAnnotated ())
{
field.annotationType = ANNOTATION_TYPE_MEDIATED;
}
//set the annotation type if not done yet
if ( ! field.isAnnotated () && clazz.isPersistent ())
{
field.annotationType = ANNOTATION_TYPE_MEDIATED;
}
}
| private static final void | validateFieldName(java.lang.String fieldname, java.lang.String classname)Checks if a given fieldname is a valid Java identifier.
if (fieldname.length () == 0)
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_EMPTY_FIELDNAME,
new String [] { classname }));
}
if ( ! Character.isJavaIdentifierStart (fieldname.charAt (0)))
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_INVALID_FIELDNAME,
new String [] { classname, fieldname }));
}
for (int i = fieldname.length () - 1; i >= 0; i--)
{
final char c = fieldname.charAt (i);
if ( ! Character.isJavaIdentifierPart (c))
{
throw new JDOMetaDataUserException (getErrorMsg (IErrorMessages.ERR_INVALID_FIELDNAME,
new String [] { classname, fieldname }));
}
}
| private final void | validateFieldProperty(com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataProperties$Property prop, java.lang.String fieldname, java.lang.String classname)Checks if the given attribute-property if valid for a field.
String value = prop.value;
if (prop.name == null) //try to guess the property name
{
//check access modifier
if (value.equals (ACCESS_PUBLIC) ||
value.equals (ACCESS_PROTECTED) ||
value.equals (ACCESS_PACKAGE_LOCAL) ||
value.equals (ACCESS_PRIVATE))
{
prop.name = PROPERTY_ACCESS_MODIFIER;
}
//check persistence
else if (value.equals (JDO_PERSISTENT) ||
value.equals (JDO_TRANSIENT) ||
value.equals (JDO_TRANSACTIONAL))
{
prop.name = PROPERTY_JDO_MODIFIER;
}
//annotation type?
else if (value.equals (ANNOTATION_TYPE_PK) ||
value.equals (ANNOTATION_TYPE_DFG) ||
value.equals (ANNOTATION_TYPE_MEDIATED))
{
prop.name = PROPERTY_ANNOTATION_TYPE;
}
else
{
//assume the the given value is the type
prop.name = PROPERTY_TYPE;
}
}
else
{
String entry = classname + FIELD_DELIMITER + fieldname;
//do we have a valid property name?
checkPropertyName (prop.name,
new String []
{
PROPERTY_ACCESS_MODIFIER,
PROPERTY_JDO_MODIFIER,
PROPERTY_TYPE,
PROPERTY_ANNOTATION_TYPE
},
entry);
//do we have a valid property value
checkPropertyValue (prop,
new String []
{
ACCESS_PUBLIC,
ACCESS_PROTECTED,
ACCESS_PACKAGE_LOCAL,
ACCESS_PRIVATE
},
PROPERTY_ACCESS_MODIFIER,
entry);
checkPropertyValue (prop,
new String []
{
JDO_PERSISTENT,
JDO_TRANSIENT,
JDO_TRANSACTIONAL
},
PROPERTY_JDO_MODIFIER,
entry);
checkPropertyValue (prop,
new String []
{
ANNOTATION_TYPE_PK,
ANNOTATION_TYPE_DFG,
ANNOTATION_TYPE_MEDIATED
},
PROPERTY_ANNOTATION_TYPE,
entry);
}
|
|