From jdo-commits-return-190-apmail-db-jdo-commits-archive=www.apache.org@db.apache.org Sat Mar 19 05:03:34 2005 Return-Path: Delivered-To: apmail-db-jdo-commits-archive@www.apache.org Received: (qmail 84991 invoked from network); 19 Mar 2005 05:03:34 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 19 Mar 2005 05:03:34 -0000 Received: (qmail 86397 invoked by uid 500); 19 Mar 2005 05:03:33 -0000 Mailing-List: contact jdo-commits-help@db.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: jdo-dev@db.apache.org Delivered-To: mailing list jdo-commits@db.apache.org Delivered-To: moderator for jdo-commits@db.apache.org Received: (qmail 34739 invoked by uid 99); 19 Mar 2005 02:06:06 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Message-ID: <20050319010600.28050.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Mailer: svnmailer-1.0.0-dev Date: Sat, 19 Mar 2005 01:06:00 -0000 Subject: svn commit: r158176 [15/79] - in incubator/jdo/trunk/ri11: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ src/java/org/apache/jdo/ejb/ src/java/org/apache/jdo/enhancer/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/enhancer/ src/java/org/apache/jdo/impl/enhancer/classfile/ src/java/org/apache/jdo/impl/enhancer/core/ src/java/org/apache/jdo/impl/enhancer/generator/ src/java/org/apache/jdo/impl/enhancer/meta/ src/java/org/apache/jdo/impl/enhancer/meta/model/ src/java/org/apache/jdo/impl/enhancer/meta/prop/ src/java/org/apache/jdo/impl/enhancer/meta/util/ src/java/org/apache/jdo/impl/enhancer/util/ src/java/org/apache/jdo/impl/fostore/ src/java/org/apache/jdo/impl/jdoql/ src/java/org/apache/jdo/impl/jdoql/jdoqlc/ src/java/org/apache/jdo/impl/jdoql/scope/ src/java/org/apache/jdo/impl/jdoql/tree/ src/java/org/apache/jdo/impl/model/ src/java/org/apache/jdo/impl/model/java/ src/java/org/apache/jdo/impl/model/java/runtime/ src/java/org/apache/jdo/impl/model/jdo/ src/java/org/apache/jdo/impl/model/jdo/caching/ src/java/org/apache/jdo/impl/model/jdo/util/ src/java/org/apache/jdo/impl/model/jdo/xml/ src/java/org/apache/jdo/impl/pm/ src/java/org/apache/jdo/impl/sco/ src/java/org/apache/jdo/impl/state/ src/java/org/apache/jdo/jdoql/ src/java/org/apache/jdo/jdoql/tree/ src/java/org/apache/jdo/model/ src/java/org/apache/jdo/model/java/ src/java/org/apache/jdo/model/jdo/ src/java/org/apache/jdo/pm/ src/java/org/apache/jdo/sco/ src/java/org/apache/jdo/state/ src/java/org/apache/jdo/store/ src/java/org/apache/jdo/util/ test/ test/conf/ test/enhancer/ test/enhancer/sempdept/ test/enhancer/sempdept/src/ test/enhancer/sempdept/src/empdept/ test/fsuid2/ test/fsuid2/org/ test/fsuid2/org/apache/ test/fsuid2/org/apache/jdo/ test/fsuid2/org/apache/jdo/pc/ test/java/ test/java/org/ test/java/org/apache/ test/java/org/apache/jdo/ test/java/org/apache/jdo/impl/ test/java/org/apache/jdo/impl/fostore/ test/java/org/apache/jdo/pc/ test/java/org/apache/jdo/pc/appid/ test/java/org/apache/jdo/pc/empdept/ test/java/org/apache/jdo/pc/serializable/ test/java/org/apache/jdo/pc/xempdept/ test/java/org/apache/jdo/test/ test/java/org/apache/jdo/test/query/ test/java/org/apache/jdo/test/util/ test/jdo/ test/jdo/org/ test/jdo/org/apache/ test/jdo/org/apache/jdo/ test/jdo/org/apache/jdo/pc/ test/jdo/org/apache/jdo/pc/appid/ test/jdo/org/apache/jdo/pc/empdept/ test/jdo/org/apache/jdo/pc/serializable/ test/jdo/org/apache/jdo/pc/xempdept/ xdocs/ To: jdo-commits@db.apache.org From: mbo@apache.org X-Virus-Checked: Checked X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/= prop/JDOField.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/meta/prop/JDOField.java?view=3Dauto&rev=3D158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/pro= p/JDOField.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/pro= p/JDOField.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,231 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.prop; + +import java.lang.reflect.Modifier; + + +/** + * A class to hold the properties of a field. + */ +final class JDOField +{ + /** + * The name of the field. + */ + final private String name; + =20 + /** + * The type of the field. + */ + private String type =3D null; + =20 + /** + * The access modifier of the field. + */ + private int modifiers =3D Modifier.PRIVATE; + =20 + /** + * The JDO modifier of the field. + */ + private String jdoModifier =3D null; + =20 + /** + * The annotation type. + */ + private String annotationType =3D null; + =20 + /** + * Creates a new object with the given name. + * + * @param name The name of the field. + */ + JDOField(String name) + { + this.name =3D name; + } + =20 + /** + * Returns the name of the field. + * + * @return The name of the field. + */ + public String getName() + { + return name; + } + =20 + /** + * Sets the type of the field. The given classname should have a + * natural form(with dots) and is converted to a VM-similar + * notation(with slashes). + * + * @param type The natural classname. + */ + public void setType(String type) + { + this.type =3D NameHelper.fromCanonicalClassName(type); + } + =20 + /** + * Returns the type of the field. + * + * @return The type of the field. + */ + public String getType() + { + return type; + } + =20 + /** + * Returns the modifiers of the field. + * + * @param modifiers The modifiers of the field. + */ + public void setModifiers(int modifiers) + { + this.modifiers =3D modifiers; + } + =20 + /** + * Returns the modifiers of the field. + * + * @return The modifiers of the field. + */ + public int getModifiers() + { + return modifiers; + } + =20 + /** + * Sets the annotation type of the field. + * + * @param annotationType annotation type + */ + public void setAnnotationType(String annotationType) + { + this.annotationType =3D annotationType; + } + =20 + /** + * Returns whether the field is annotated. + * + * @return true if annotated field + */ + public boolean isAnnotated() + { + return annotationType !=3D null; + } + =20 + /** + * Returns whether the field is a key primary. + * + * @return true if primary key. + */ + public boolean isKey() + { + return (annotationType !=3D null + && annotationType.equals( + MetaDataProperties.ANNOTATION_TYPE_KEY)); + } + =20 + /** + * Is the field in the default fetch group? + * + * @return Is the field in the default fetch group? + */ + public boolean isInDefaultFetchGroup() + { + return (annotationType !=3D null + && annotationType.equals( + MetaDataProperties.ANNOTATION_TYPE_DFG)); + } + =20 + /** + * Sets the modifiers of the field. + * + * @param jdoModifier the persistence modifier of the field + */ + public void setJdoModifier(String jdoModifier) + { + this.jdoModifier =3D jdoModifier; + } + =20 + /** + * Returns whether the field is declared transient. + * + * @return true if declared transient field. + * @see #setJdoModifier + */ + public boolean isKnownTransient() + { + return (jdoModifier !=3D null + && jdoModifier.equals(MetaDataProperties.JDO_TRANSIENT)); + } + =20 + /** + * Returns whether the field is persistent. + * + * @return true if persistent field. + * @see #setJdoModifier + */ + public boolean isPersistent() + { + return (jdoModifier !=3D null + && jdoModifier.equals(MetaDataProperties.JDO_PERSISTENT)); + } + =20 + /** + * Returns whether the field is transactional. + * + * @return true if transactional field + * @see #setJdoModifier + */ + public boolean isTransactional() + { + return (jdoModifier !=3D null + && jdoModifier.equals(MetaDataProperties.JDO_TRANSACTIONAL= )); + } + =20 + /** + * Returns whether the field is managed. + * + * @return true if managed field + */ + public boolean isManaged() + { + return (isPersistent() || isTransactional()); + } + =20 + /** + * Creates a string-representation of the object. + * + * @return The string-representation of the object. + */ + public String toString() + { + return ('<' + "name:" + name + + ',' + MetaDataProperties.PROPERTY_TYPE + + ':' + type + + ',' + MetaDataProperties.PROPERTY_ACCESS_MODIFIER + + ':' + Modifier.toString(modifiers) + + ',' + MetaDataProperties.PROPERTY_JDO_MODIFIER + + ':' + jdoModifier + + ',' + MetaDataProperties.PROPERTY_ANNOTATION_TYPE + + ':' + annotationType + '>'); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/= prop/MetaDataProperties.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/meta/prop/MetaDataProperties.java?view=3Dauto&rev=3D= 158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/pro= p/MetaDataProperties.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/pro= p/MetaDataProperties.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,859 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.prop; + +import java.lang.reflect.Modifier; + +import java.util.Iterator; +import java.util.Enumeration; +import java.util.Map; +import java.util.List; +import java.util.Collection; +import java.util.HashSet; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Properties; +import java.util.StringTokenizer; + +import java.text.MessageFormat; + +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataFatalError; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataUserException; + + + +/** + * 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=3D...", "test.Test#field1=3D...")
  • + *
  • Classnames can have the following attributes: + *
      + *
    • jdo:{persistent|transactional}
    • + *
    • super: <classname>
    • + *
    • oid: <classname>
    • + *
    • access: {public|protected|package|private}
    • + *
  • + *
  • Fieldnames can have the following attributes: + *
      + *
    • type:<type>
    • + *
    • access: {public|protected|package|private}
    • + *
    • jdo:{persistent|transactional|transient}
    • + *
    • annotation:{key|dfg|mediated}
    • + *
  • + *
  • the names of the attributes can be ommitted: you can say
    + * test.Test1#field1=3Djdo:persistent,type:java.lang.String,key,...=
    + * or
    + * test.Test1#field1=3Dpersistent,java.lang.String,key,...
    + * or
    + * test.Test1#field1=3Djdo:persistent,java.lang.String,key,...
    =
  • + *
  • 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. + */ +final class MetaDataProperties +{ + /** + * The delimiter of a property key between the class- and fieldname. + */ + static final char FIELD_DELIMITER =3D '#'; + + /** + * A string of delimiter characters between attributes. + */ + static final String PROPERTY_DELIMITERS =3D " \t,;"; + + /** + * A delimiter character between attribute name and attribute value + */ + static final char PROPERTY_ASSIGNER =3D ':'; + + // attribute names for classes and fields + static final String PROPERTY_ACCESS_MODIFIER =3D "access"; + static final String PROPERTY_JDO_MODIFIER =3D "jdo"; + static final String PROPERTY_SUPER_CLASSNAME =3D "super"; + static final String PROPERTY_OID_CLASSNAME =3D "oid"; + static final String PROPERTY_TYPE =3D "type"; + static final String PROPERTY_ANNOTATION_TYPE =3D "annotation"; + + // values of the access attribute of classes and fields. + static final String ACCESS_PRIVATE =3D "private"; + static final String ACCESS_PACKAGE_LOCAL =3D "package"; + static final String ACCESS_PROTECTED =3D "protected"; + static final String ACCESS_PUBLIC =3D "public"; + + // values of the jdo attribute of classes and fields. + static final String JDO_TRANSIENT =3D "transient"; + static final String JDO_PERSISTENT =3D "persistent"; + static final String JDO_TRANSACTIONAL =3D "transactional"; + + // values of the annotation type attribute of fields. + static final String ANNOTATION_TYPE_KEY =3D "key"; + static final String ANNOTATION_TYPE_DFG =3D "dfg"; + static final String ANNOTATION_TYPE_MEDIATED =3D "mediated"; + + /** + * The properties to parse. + */ + private Properties properties; + + /** + * A map of already read class properties. The keys are the + * classnames, the values are the appropriate + * JDOClass-object. + */ + private final Map cachedJDOClasses =3D new HashMap(); + + /** + * A constant for the cache indicating that a given classname + * if not specified in the properties. + */ + static private final JDOClass NULL =3D new JDOClass(null); + + /** + * A temporary vector (this is the reason why the implementation is n= ot + * thread safe). + */ + private final List tmpTokens =3D new ArrayList(); + + /** + * Creates a new object with the given properties. + * + * @param props The properties. + */ + public MetaDataProperties(Properties props) + { + this.properties =3D props; + } + + /** + * Get the information about the class with the given name. + * + * @param classname The classname. + * @return The information about the class or null if no + * information is given. + * @throws EnhancerMetaDataUserException If something went wrong pa= rsing + * the properties. + */ + public final JDOClass getJDOClass(String classname) + throws EnhancerMetaDataUserException + { + classname =3D NameHelper.toCanonicalClassName(classname); + JDOClass clazz =3D (JDOClass)cachedJDOClasses.get(classname); + if (clazz =3D=3D NULL) { //already searched but not found + return null; + } + if (clazz !=3D null) { + return clazz; + } + + //load it from the properties file + String s =3D properties.getProperty(classname); + if (s =3D=3D null) { //class not defined + cachedJDOClasses.put(classname, NULL); + return null; + } + + //the class could be found in the properties + clazz =3D parseJDOClass(classname, s); //parse the class attribut= es + parseJDOFields(clazz); //parse all fields + validateDependencies(clazz); //check dependencies + cachedJDOClasses.put(clazz.getName(), clazz); + + return clazz; + } + + /** + * Gets the information about the specified field. + * + * @param classname The name of the class. + * @param fieldname The name of the field of the class. + * @return The information about the field or null if + * no information could be found. + * @throws EnhancerMetaDataUserException If something went wrong pa= rsing + * the properties. + */ + public final JDOField getJDOField(String fieldname, + String classname) + throws EnhancerMetaDataUserException + { + JDOClass clazz =3D getJDOClass(classname); + return (clazz !=3D null ? clazz.getField(fieldname) : null); + } + + /** + * Gets all classnames in the properties. + * + * @return All classnames in the properties. + */ + public final String[] getKnownClassNames() + { + Collection classnames =3D new HashSet(); + for (Enumeration names =3D properties.propertyNames(); + names.hasMoreElements();) { + String name =3D (String)names.nextElement(); + if (name.indexOf(FIELD_DELIMITER) < 0) { + classnames.add(NameHelper.fromCanonicalClassName(name)); + } + } + + return (String[])classnames.toArray(new String[classnames.size()]); + } + + /** + * Parses the attributes-string of a class and puts them into a + * JDOClass-object. + * + * @param classname The name of the class. + * @param attributes The attribute-string as specified in the prope= rties. + * @return The create JDOClass-object. + * @throws EnhancerMetaDataUserException If something went wrong pa= rsing + * the attributes. + */ + private final JDOClass parseJDOClass(String classname, + String attributes) + throws EnhancerMetaDataUserException + { + List props =3D parseProperties(attributes); + + // check each property + for (int i =3D 0; i < props.size(); i++) { + final Property prop =3D (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 =3D new JDOClass(classname); + for (int i =3D 0; i < props.size(); i++) { + Property prop =3D (Property)props.get(i); + if (prop.name.equals(PROPERTY_ACCESS_MODIFIER)) { + clazz.setModifiers(getModifiers(prop.value)); + } else if (prop.name.equals(PROPERTY_JDO_MODIFIER)) { + clazz.setPersistent(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; + } + + /** + * Checks if the given attribute-property of a class is valid. + * + * @param prop The attribute-property. + * @param classname The classname. + * @throws EnhancerMetaDataUserException If the validation failed. + */ + static private void validateClassProperty(Property prop, + String classname) + throws EnhancerMetaDataUserException + { + String value =3D prop.value; + if (prop.name =3D=3D null) { + // try to guess the property name + if (value.equals(ACCESS_PUBLIC) + || value.equals(ACCESS_PROTECTED) + || value.equals(ACCESS_PACKAGE_LOCAL) + || value.equals(ACCESS_PRIVATE)) { + // assume access modifier + prop.name =3D PROPERTY_ACCESS_MODIFIER; + } else if (value.equals(JDO_PERSISTENT) + || value.equals(JDO_TRANSIENT)) { + // assume persistence modifier + prop.name =3D PROPERTY_JDO_MODIFIER; + } + //@olsen: not unique anymore, could also be oid class name + // else { + // //assume the the given value is the superclassname + // prop.name =3D PROPERTY_SUPER_CLASSNAME; + // } + } else { + // do we have a valid property name? + String name =3D prop.name; + checkPropertyName(prop.name, + new String[]{ + PROPERTY_ACCESS_MODIFIER, + PROPERTY_JDO_MODIFIER, + PROPERTY_SUPER_CLASSNAME, + PROPERTY_OID_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); + } + } + + /** + * Parses all fields of a given class. + * + * @param clazz the representation of the class + * @throws EnhancerMetaDataUserException on parse errors + */ + private final void parseJDOFields(JDOClass clazz) + throws EnhancerMetaDataUserException + { + //search for fields of the class + for (Enumeration names =3D properties.propertyNames(); + names.hasMoreElements();) { + String name =3D (String)names.nextElement(); + if (name.startsWith(clazz.getName() + FIELD_DELIMITER)) { + //field found + String fieldname + =3D name.substring(name.indexOf(FIELD_DELIMITER) + 1, + name.length()); + validateFieldName(fieldname, clazz.getName()); + clazz.addField(parseJDOField(properties.getProperty(name), + fieldname, clazz)); + } + } + clazz.sortFields(); + } + + /** + * Parses the attribute-string of a field. + * + * @param attributes The attribute-string. + * @param fieldname The fieldname. + * @param clazz The class to field belongs to. + * @throws EnhancerMetaDataUserException on parse errors + */ + private final JDOField parseJDOField(String attributes, + String fieldname, + JDOClass clazz) + throws EnhancerMetaDataUserException + { + List props =3D parseProperties(attributes); + + //check each property + for (int i =3D 0; i < props.size(); i++) { + Property prop =3D (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 =3D new JDOField(fieldname); + for (int i =3D 0; i < props.size(); i++) { + Property prop =3D (Property)props.get(i); + if (prop.name.equals(PROPERTY_ACCESS_MODIFIER)) { + field.setModifiers(getModifiers(prop.value)); + } else if (prop.name.equals(PROPERTY_JDO_MODIFIER)) { + field.setJdoModifier(prop.value); + } else if (prop.name.equals(PROPERTY_TYPE)) { + field.setType(prop.value); + } else if (prop.name.equals(PROPERTY_ANNOTATION_TYPE)) { + field.setAnnotationType(prop.value); + } + } + + return field; + } + + /** + * Checks if the given attribute-property if valid for a field. + * + * @param prop The attribute-property. + * @param fieldname The fieldname. + * @param classname The classname. + * @throws EnhancerMetaDataUserException If the check fails. + */ + private final void validateFieldProperty(Property prop, + String fieldname, + String classname) + throws EnhancerMetaDataUserException + { + //try to guess the property name + String value =3D prop.value; + if (prop.name =3D=3D null) { + if (value.equals(ACCESS_PUBLIC) || + value.equals(ACCESS_PROTECTED) || + value.equals(ACCESS_PACKAGE_LOCAL) || + value.equals(ACCESS_PRIVATE)) { + // access modifier + prop.name =3D PROPERTY_ACCESS_MODIFIER; + } else if (value.equals(JDO_PERSISTENT) || + value.equals(JDO_TRANSIENT) || + value.equals(JDO_TRANSACTIONAL)) { + // persistence modifier + prop.name =3D PROPERTY_JDO_MODIFIER; + } else if (value.equals(ANNOTATION_TYPE_KEY) || + value.equals(ANNOTATION_TYPE_DFG) || + value.equals(ANNOTATION_TYPE_MEDIATED)) { + // annotation type + prop.name =3D PROPERTY_ANNOTATION_TYPE; + } else { + //assume the the given value is the type + prop.name =3D PROPERTY_TYPE; + } + } else { + String entry =3D 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_KEY, + ANNOTATION_TYPE_DFG, + ANNOTATION_TYPE_MEDIATED + }, + PROPERTY_ANNOTATION_TYPE, + entry); + } + } + + /** + * Validates dependencies between a class and its fields and between. + * + * @param clazz the class + * @throws EnhancerMetaDataUserException if the validation fails + */ + private final void validateDependencies(JDOClass clazz) + throws EnhancerMetaDataUserException + { + final List fields =3D clazz.getFields(); + for (Iterator i =3D fields.iterator(); i.hasNext();) { + JDOField field =3D (JDOField)i.next(); + + // check the jdo field modifier + if (field.isPersistent() && clazz.isTransient()) { + // non-persistent classes cannot have persistent fields + final String msg + =3D getMsg(Msg.ERR_TRANSIENT_CLASS_WITH_PERSISTENT_FIE= LD, + new String[]{ + clazz.getName(), + field.getName() }); + throw new EnhancerMetaDataUserException(msg); + } + if (field.isTransactional() && clazz.isTransient()) { + // non-persistent classes cannot have transactional fields + final String msg + =3D getMsg(Msg.ERR_TRANSIENT_CLASS_WITH_TRANSACTIONAL_= FIELD, + new String[]{ + clazz.getName(), + field.getName() }); + throw new EnhancerMetaDataUserException(msg); + } + if (!field.isKnownTransient() && !field.isManaged()) { + // unspecified persistence modifier + final String msg + =3D getMsg(Msg.ERR_UNSPECIFIED_FIELD_PERSISTENCE_MODIF= IER, + new String[]{ + clazz.getName(), + field.getName() }); + throw new EnhancerMetaDataUserException(msg); + } + + // check annotation type + if (!field.isAnnotated() && field.isManaged()) { + // unspecified annotation type + final String msg + =3D getMsg(Msg.ERR_UNSPECIFIED_FIELD_ANNOTATION_TYPE, + new String[]{ + clazz.getName(), + field.getName() }); + throw new EnhancerMetaDataUserException(msg); + } + if (field.isAnnotated() && !field.isManaged()) { + // non managed field with annotation type + final String msg + =3D getMsg(Msg.ERR_NON_MANAGED_ANNOTATED_FIELD, + new String[]{ + clazz.getName(), + field.getName() }); + throw new EnhancerMetaDataUserException(msg); + } + if (field.isAnnotated() && clazz.isTransient()) { + // a non-persistent class cannot have an annotated field + final String msg + =3D getMsg(Msg.ERR_TRANSIENT_CLASS_WITH_ANNOTATED_FIEL= D, + new String[]{ + clazz.getName(), + field.getName() }); + throw new EnhancerMetaDataUserException(msg); + } + } + } + + /** + * Checks if a given fieldname is a valid Java identifier. + * + * @param fieldname The fieldname. + * @param classname The corresponding classname. + * @throws EnhancerMetaDataUserException If the check fails. + */ + static private void validateFieldName(String fieldname, + String classname) + throws EnhancerMetaDataUserException + { + if (fieldname.length() =3D=3D 0) { + final String msg + =3D getMsg(Msg.ERR_EMPTY_FIELDNAME, + new String[]{ classname }); + throw new EnhancerMetaDataUserException(msg); + } + + if (!Character.isJavaIdentifierStart(fieldname.charAt(0))) { + final String msg + =3D getMsg(Msg.ERR_INVALID_FIELDNAME, + new String[]{ classname, fieldname }); + throw new EnhancerMetaDataUserException(msg); + } + + for (int i =3D fieldname.length() - 1; i >=3D 0; i--) { + final char c =3D fieldname.charAt(i); + if (!Character.isJavaIdentifierPart(c)) { + final String msg + =3D getMsg(Msg.ERR_INVALID_FIELDNAME, + new String[]{ classname, fieldname }); + throw new EnhancerMetaDataUserException(msg); + } + } + } + + /** + * Checks if an attribute-property was entered twice for a class or f= ield. + * + * @param props The properties. + * @param entry The class- or fieldname. + * @throws EnhancerMetaDataUserException If the check fails. + */ + static private void checkForDuplicateProperties(List props, + String entry) + throws EnhancerMetaDataUserException + { + for (int i =3D 0; i < props.size(); i++) { + for (int j =3D i + 1; j < props.size(); j++) { + Property p1 =3D (Property)props.get(i); + Property p2 =3D (Property)props.get(j); + if (p1.name.equals(p2.name) && !p1.value.equals(p2.value))= { + final String msg + =3D getMsg(Msg.ERR_DUPLICATE_PROPERTY_NAME, + new String[]{ + entry, + p1.name, + p1.value, + p2.value }); + throw new EnhancerMetaDataUserException(msg); + } + } + } + } + + /** + * Checks if an attribute name is recognized by the parser. + * + * @param name The name of the attribute. + * @param validnames A list of valid names(the attribute name has to + * be in this list). + * @param entry The class- or fieldname. + * @throws EnhancerMetaDataUserException If the check fails. + */ + static private void checkPropertyName(String name, + String[] validnames, + String entry) + throws EnhancerMetaDataUserException + { + for (int i =3D 0; i < validnames.length; i++) { + if (name.equals(validnames[i])) { + return; + } + } + + final String msg + =3D getMsg(Msg.ERR_INVALID_PROPERTY_NAME, + new String[]{ entry, name }); + throw new EnhancerMetaDataUserException(msg); + } + + /** + * Checks if the given value of an attribute-property is recognized by + * by the parser if that value belongs to a given attribute name. + * + * @param prop The attribute-property(with name and value). + * @param validvalues A list of valid values. + * @param name The name of the attribute-property to check. + * @param entry The class- or fieldname. + * @throws EnhancerMetaDataUserException If the check fails. + */ + static private void checkPropertyValue(Property prop, + String[] validvalues, + String name, + String entry) + throws EnhancerMetaDataUserException + { + if ( !prop.name.equals(name)) { + return; + } + + for (int i =3D 0; i < validvalues.length; i++) { + if (prop.value.equals(validvalues[i])) { + return; + } + } + + final String msg + =3D getMsg(Msg.ERR_INVALID_PROPERTY_VALUE, + new String[]{ entry, name, prop.value }); + throw new EnhancerMetaDataUserException(msg); + } + + /** + * Formats an error message with the given parameters. + * + * @param msg The message with format strings. + * @param params The params to format the message with. + * @return The formatted error message. + */ + static final String getMsg(String msg, + String[] params) + { + return MessageFormat.format(msg, params); + } + + /** + * Parses the attribute-string of a class- or fieldname. + * + * @param attributes The attribute-string. + * @return A list of Propert<-objects for the attribute= s=2E + * @exception EnhancerMetaDataUserException If the parsing fails. + */ + final List parseProperties(String attributes) + throws EnhancerMetaDataUserException + { + tmpTokens.clear(); + for (StringTokenizer t + =3D new StringTokenizer(attributes, PROPERTY_DELIMITERS); + t.hasMoreTokens();) { + tmpTokens.add(parseProperty(t.nextToken())); + } + + return tmpTokens; + } + + /** + * Parses the given attribute and splits it into name and value. + * + * @param attribute The attribute-string. + * @return The Propert-object. + * @exception EnhancerMetaDataUserException If the parsing fails. + */ + private final Property parseProperty(String attribute) + throws EnhancerMetaDataUserException + { + Property prop =3D new Property(); + int idx =3D attribute.indexOf(PROPERTY_ASSIGNER); + if (idx < 0) { + prop.value =3D attribute; + } else { + prop.name =3D attribute.substring(0, idx); + prop.value =3D attribute.substring(idx + 1, attribute.length()= ); + if (prop.name.length() =3D=3D 0 || prop.value.length() =3D=3D = 0) { + final String msg + =3D getMsg(Msg.ERR_EMPTY_PROPERTY_NAME_OR_VALUE, + new String[]{ attribute }); + throw new EnhancerMetaDataUserException(msg); + } + } + + return prop; + } + + /** + * Returns the modifier value for a Java modifier name. + */ + static private int getModifiers(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; + } + + /** + * A simple test to run from the command line. + * + * @param argv The command line arguments. + */ + public static void main(String[] argv) + { + if (argv.length !=3D 1) { + System.err.println("Error: no property filename specified"); + return; + } + final Properties p =3D new Properties(); + try { + java.io.InputStream in + =3D new java.io.FileInputStream(new java.io.File(argv[0])); + p.load(in); + in.close(); + System.out.println("PROPERTIES: " + p); + System.out.println("############"); + final MetaDataProperties props =3D new MetaDataProperties(p); + String[] classnames =3D props.getKnownClassNames(); + for (int i =3D 0; i < classnames.length; i++) { + String classname =3D classnames[i]; + System.out.println(classname + ": " + + props.getJDOClass(classname)); + } + } catch(Throwable ex) { + ex.printStackTrace(System.err); + } + } + + /** + * The holder-class for the name and the value of a property. + */ + static private final class Property + { + /** + * The name of the property. + */ + String name =3D null; + + /** + * The value of the property. + */ + String value =3D null; + + /** + * Creates a string-representation of this object. + * + * @return The string-representation of this object. + */ + public final String toString() + { + return '<' + name + ':' + value + '>'; + } + } + + //^olsen: -> Bundle.properties + + /** + * Holds all unformatted error messages. + */ + static private interface Msg + { + // the unformatted error messages + static final String PREFIX =3D "Error Parsing meta data properties= : "; + + static final String ERR_EMPTY_FIELDNAME =3D + PREFIX + "The class ''{0}'' may not have an empty fieldname."; + + static final String ERR_INVALID_FIELDNAME =3D + PREFIX + "The field name ''{1}'' of class ''{0}'' is not valid."; + + static final String ERR_EMPTY_PROPERTY_NAME_OR_VALUE =3D + PREFIX + "The property name and value may not be empty if a ''" +=20 + PROPERTY_ASSIGNER + "'' is specified: ''{0}''."; + + static final String ERR_INVALID_PROPERTY_NAME =3D + PREFIX + "Invalid property name for entry ''{0}'': ''{1}''."; + + static final String ERR_INVALID_PROPERTY_VALUE =3D + PREFIX + "Invalid value for property ''{1}'' of entry ''{0}'': ''{= 2}''."; + + static final String ERR_DUPLICATE_PROPERTY_NAME =3D + PREFIX + "The property ''{1}'' for the entry ''{0}'' entered twice= with values: ''{2}'' and ''{3}''."; + + static final String ERR_UNSPECIFIED_FIELD_PERSISTENCE_MODIFIER =3D + PREFIX + "No persistence modifier specified for field: ''{0}.{1}''= ."; + + static final String ERR_TRANSIENT_CLASS_WITH_PERSISTENT_FIELD =3D + PREFIX + "A non-persistent class cannot have a persistent field(cl= ass ''{0}'' with field ''{1})''."; + + static final String ERR_TRANSIENT_CLASS_WITH_TRANSACTIONAL_FIELD = =3D + PREFIX + "A non-persistent class cannot have a transactional field= (class ''{0}'' with field ''{1})''."; + + static final String ERR_UNSPECIFIED_FIELD_ANNOTATION_TYPE =3D + PREFIX + "No annotation type specified for field: ''{0}.{1}''."; + + static final String ERR_TRANSIENT_CLASS_WITH_ANNOTATED_FIELD =3D + PREFIX + "A non-persistent class cannot have an annotated field(''= {1}'' of class ''{0}'') can''t have a fetch group."; + + static final String ERR_NON_MANAGED_ANNOTATED_FIELD =3D + PREFIX + "A non-managed field(''{1}'' of class ''{0}'') can''t be = a annotated."; + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/= prop/NameHelper.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/meta/prop/NameHelper.java?view=3Dauto&rev=3D158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/pro= p/NameHelper.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/pro= p/NameHelper.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,50 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.prop; + + +/** + * Some utility methods for classname conversion. + */ +final class NameHelper +{ + /** + * Converts a classname given in a given VM-similar notation(with sla= shes) + * into a canonical notation (with dots). + * + * @param classname The VM-similar notation of the classname. + * @return The canonical classname. + * @see #fromCanonicalClassName + */ + static String toCanonicalClassName(String classname) + { + return classname.replace('/', '.'); + } + + /** + * Converts a classname given in a canonical form(with dots) into + * a VM-similar notation (with slashes) + * + * @param classname The canonical classname. + * @return The VM-similar classname notation. + * @see #toCanonicalClassName + */ + static String fromCanonicalClassName(String classname) + { + return classname.replace('.', '/'); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/= util/EnhancerMetaDataBaseModel.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/meta/util/EnhancerMetaDataBaseModel.java?view=3Dauto= &rev=3D158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/uti= l/EnhancerMetaDataBaseModel.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/uti= l/EnhancerMetaDataBaseModel.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,262 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + + +package org.apache.jdo.impl.enhancer.meta.util; + +import java.io.PrintWriter; + +import java.util.Iterator; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; + +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaData; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataFatalError; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataUserException; +import org.apache.jdo.impl.enhancer.util.Support; + + + +/** + * Provides the JDO meta information based on a JDO meta model. + */ +public abstract class EnhancerMetaDataBaseModel + extends Support + implements EnhancerMetaData +{ + // misc + protected boolean verbose =3D true; + protected final PrintWriter out; + + // default settings + static protected final HashSet unenhancableTypePrefixes =3D new HashSe= t(); + static + { + unenhancableTypePrefixes.add("java/"); + unenhancableTypePrefixes.add("javax/"); + } + + /** + * Creates an instance. + */ + public EnhancerMetaDataBaseModel(PrintWriter out, + boolean verbose) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(out !=3D null); + this.out =3D out; + } + + /** + * Prints out a warning message. + * + * @param msg the message + */ + public void printWarning(String msg) + { + out.println(getI18N("enhancer.metadata.warning", msg)); + } + + /** + * Prints out a verbose message. + * + * @param msg the message + */ + public void printMessage(String msg) + { + if (verbose) { + out.println(getI18N("enhancer.metadata.message", msg)); + } + } + + /** + * Returns whether a class is not to be modified by the enhancer. + * + * @see EnhancerMetaData#isKnownUnenhancableClass(String) + */ + public boolean isKnownUnenhancableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + //check the transient prefixes + for (Iterator i =3D unenhancableTypePrefixes.iterator(); i.hasNext= ();) { + final String typePrefix =3D (String)i.next(); + if (classPath.startsWith(typePrefix)) + return true; + } + return false; + } + + /** + * Returns whether a class is persistence-capable root class. + * + * @see EnhancerMetaData#isPersistenceCapableRootClass(String) + */ + public boolean isPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + return (isPersistenceCapableClass(classPath) + && (getPersistenceCapableSuperClass(classPath) =3D=3D null= )); + } + + /** + * Returns the name of the persistence-capable root class of a class. + * + * @see EnhancerMetaData#getPersistenceCapableRootClass(String) + */ + public String getPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + if (!isPersistenceCapableClass(classPath)) { + return null; + } + + String pcRootClass; + String clazz =3D classPath; + do { + pcRootClass =3D clazz; + clazz =3D getPersistenceCapableSuperClass(clazz); + } while (clazz !=3D null); + return pcRootClass; + } + + /** + * Returns the name of the key class of the next persistence-capable + * superclass that defines one. + * + * @see EnhancerMetaData#getSuperKeyClass(String) + */ + public String getSuperKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + for (String superClass =3D getPersistenceCapableSuperClass(classPa= th); + superClass !=3D null; + superClass =3D getPersistenceCapableSuperClass(superClass)) { + final String superKeyClass =3D getKeyClass(superClass); + if (superKeyClass !=3D null) { + return superKeyClass; + } + } + return null; + } + + /** + * Returns whether a field of a class is known to be either transient + * transactional or persistent. + * + * @see EnhancerMetaData#isManagedField(String, String) + */ + public boolean isManagedField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + return (isPersistentField(classPath, fieldName) + || isTransactionalField(classPath, fieldName)); + } + + /** + * Returns the field flags of a declared, managed field of a class. + * + * @see EnhancerMetaData#getFieldFlags(String, String) + */ + public int getFieldFlags(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + if (!isManagedField(classPath, fieldName)) { + affirm(!isTransactionalField(classPath, fieldName)); + affirm(!isPersistentField(classPath, fieldName)); + affirm(!isKeyField(classPath, fieldName)); + affirm(!isDefaultFetchGroupField(classPath, fieldName)); + return 0; + } + //affirm(isManagedField(classPath, fieldName)); + + if (isTransactionalField(classPath, fieldName)) { + affirm(!isPersistentField(classPath, fieldName)); + affirm(!isKeyField(classPath, fieldName)); + // ignore any dfg membership of transactional fields + //affirm(!isDefaultFetchGroupField(classPath, fieldName)); + return CHECK_WRITE; + } + //affirm(!isTransactionalField(classPath, fieldName)); + affirm(isPersistentField(classPath, fieldName)); + + if (isKeyField(classPath, fieldName)) { + // ignore any dfg membership of key fields + //affirm(!isDefaultFetchGroupField(classPath, fieldName)); + return MEDIATE_WRITE; + } + //affirm(!isKeyField(classPath, fieldName)); + =20 + if (isDefaultFetchGroupField(classPath, fieldName)) { + return CHECK_READ | CHECK_WRITE; + } + //affirm(!isDefaultFetchGroupField(classPath, fieldName)); + + return MEDIATE_READ | MEDIATE_WRITE; + } + + /** + * Returns an array of field names of all key fields of a class. + * + * @see EnhancerMetaData#getKeyFields(String) + */ + public String[] getKeyFields(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final List keys =3D new ArrayList(); + final String[] fieldNames =3D getManagedFields(classPath); + final int n =3D fieldNames.length; + for (int i =3D 0; i < n; i++) { + if (isKeyField(classPath, fieldNames[i])) { + keys.add(fieldNames[i]); + } + } + return (String[])keys.toArray(new String[keys.size()]); + } + + /** + * Returns the field flags for some declared, managed fields of a clas= s=2E + * + * @see EnhancerMetaData#getFieldFlags(String, String[]) + */ + public int[] getFieldFlags(String classPath, String[] fieldNames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final int n =3D (fieldNames !=3D null ? fieldNames.length : 0); + final int[] flags =3D new int[n]; + for (int i =3D 0; i < n; i++) { + flags[i] =3D getFieldFlags(classPath, fieldNames[i]); + } + return flags; + } + + /** + * Returns the unique field index of some declared, managed fields of a + * class. + * + * @see EnhancerMetaData#getFieldNumber(String, String[]) + */ + public int[] getFieldNumber(String classPath, String[] fieldNames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final int n =3D (fieldNames !=3D null ? fieldNames.length : 0); + final int[] flags =3D new int[n]; + for (int i =3D 0; i < n; i++) { + flags[i] =3D getFieldNumber(classPath, fieldNames[i]); + } + return flags; + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/= util/EnhancerMetaDataTimer.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/meta/util/EnhancerMetaDataTimer.java?view=3Dauto&rev= =3D158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/uti= l/EnhancerMetaDataTimer.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/uti= l/EnhancerMetaDataTimer.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,325 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + + +package org.apache.jdo.impl.enhancer.meta.util; + +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaData; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataFatalError; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataUserException; +import org.apache.jdo.impl.enhancer.util.Support; + + + + +public final class EnhancerMetaDataTimer + extends Support + implements EnhancerMetaData +{ + // delegate + final protected EnhancerMetaData delegate; + + /** + * Creates an instance. + */ + public EnhancerMetaDataTimer(EnhancerMetaData delegate) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(delegate); + this.delegate =3D delegate; + } + + public String getDeclaringClass(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getDeclaringClass(String,String)", + "EnhancerMetaData.getDeclaringClass(" + classPath=20 + + ", " + fieldName + ")"); + return delegate.getDeclaringClass(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public void declareField(String classPath, + String fieldName, + String signature) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.declareField(String,String,String= )", + "EnhancerMetaData.declareField(" + classPath + + ", " + fieldName + ", " + signature + ")"); + delegate.declareField(classPath, fieldName, signature); + } finally { + timer.pop(); + } + } + =20 + public boolean isPersistenceCapableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isPersistenceCapableClass(String)= ", + "EnhancerMetaData.isPersistenceCapableClass(" + cla= ssPath + ")"); + return delegate.isPersistenceCapableClass(classPath); + } finally { + timer.pop(); + } + } + + public boolean isSerializableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isSerializableClass(String)", + "EnhancerMetaData.isSerializableClass(" + classPath= + ")"); + return delegate.isSerializableClass(classPath); + } finally { + timer.pop(); + } + } + + public boolean isKnownUnenhancableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isKnownUnenhancableClass(String)", + "EnhancerMetaData.isKnownUnenhancableClass(" + clas= sPath + ")"); + return delegate.isKnownUnenhancableClass(classPath); + } finally { + timer.pop(); + } + } + + public boolean isPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isPersistenceCapableRootClass(Str= ing)", + "EnhancerMetaData.isPersistenceCapableRootClass(" += classPath + ")"); + return delegate.isPersistenceCapableRootClass(classPath); + } finally { + timer.pop(); + } + } + + public String getPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getPersistenceCapableRootClass(St= ring)", + "EnhancerMetaData.getPersistenceCapableRootClass(" = + classPath + ")"); + return delegate.getPersistenceCapableRootClass(classPath); + } finally { + timer.pop(); + } + } + + public String getPersistenceCapableSuperClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getPersistenceCapableSuperClass(S= tring)", + "EnhancerMetaData.getPersistenceCapableSuperClass("= + classPath + ")"); + return delegate.getPersistenceCapableSuperClass(classPath); + } finally { + timer.pop(); + } + } + + public String getKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getKeyClass(String)", + "EnhancerMetaData.getKeyClass(" + classPath + ")"); + return delegate.getKeyClass(classPath); + } finally { + timer.pop(); + } + } + + public String getSuperKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getSuperKeyClass(String)", + "EnhancerMetaData.getSuperKeyClass(" + classPath + = ")"); + return delegate.getSuperKeyClass(classPath); + } finally { + timer.pop(); + } + } + + public boolean isKnownNonManagedField(String classPath, + String fieldName, + String fieldSig) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isKnownNonManagedField(String,Str= ing,String)", + "EnhancerMetaData.isKnownNonManagedField(" + classP= ath + + ", " + fieldName + ", " + fieldSig + ")"); + return delegate.isKnownNonManagedField(classPath, + fieldName, fieldSig); + } finally { + timer.pop(); + } + } + + public boolean isManagedField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isManagedField(String,String)", + "EnhancerMetaData.isManagedField(" + classPath + + ", " + fieldName + ")"); + return delegate.isManagedField(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public boolean isPersistentField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isPersistentField(String,String)", + "EnhancerMetaData.isPersistentField(" + classPath + + ", " + fieldName + ")"); + return delegate.isPersistentField(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public boolean isTransactionalField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isTransactionalField(String,Strin= g)", + "EnhancerMetaData.isTransactionalField(" + classPath + + ", " + fieldName + ")"); + return delegate.isTransactionalField(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public boolean isKeyField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isKeyField(String,String)", + "EnhancerMetaData.isKeyField(" + classPath + + ", " + fieldName + ")"); + return delegate.isKeyField(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public boolean isDefaultFetchGroupField(String classPath, String field= Name) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.isDefaultFetchGroupField(String,f= ieldName)", + "EnhancerMetaData.isDefaultFetchGroupField(" + clas= sPath + + ", " + fieldName + ")"); + return delegate.isDefaultFetchGroupField(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public int getFieldFlags(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getFieldFlags(String, String)", + "EnhancerMetaData.getFieldFlags(" + classPath + + ", " + fieldName + ")"); + return delegate.getFieldFlags(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public int getFieldNumber(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getFieldNumber(String, String)", + "EnhancerMetaData.getFieldNumber(" + classPath + + ", " + fieldName + ")"); + return delegate.getFieldNumber(classPath, fieldName); + } finally { + timer.pop(); + } + } + + public String[] getManagedFields(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getManagedFields(String)", + "EnhancerMetaData.getmanagedFields(" + classPath + = ")"); + return delegate.getManagedFields(classPath); + } finally { + timer.pop(); + } + } + + public String[] getKeyFields(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getKeyFields(String)", + "EnhancerMetaData.getKeyFields(" + classPath + ")"); + return delegate.getKeyFields(classPath); + } finally { + timer.pop(); + } + } + + + public int[] getFieldFlags(String classPath, String[] fieldNames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getFieldFlags(String, String[])", + "EnhancerMetaData.getFieldFlags(" + classPath + ")"= ); + return delegate.getFieldFlags(classPath, fieldNames); + } finally { + timer.pop(); + } + } + + + public int[] getFieldNumber(String classPath, String[] fieldNames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + try { + timer.push("EnhancerMetaData.getFieldNumber(String, String[])", + "EnhancerMetaData.getFieldNumber(" + classPath + ")= "); + return delegate.getFieldNumber(classPath, fieldNames); + } finally { + timer.pop(); + } + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/= AnnotationTest.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/util/AnnotationTest.java?view=3Dauto&rev=3D158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Ann= otationTest.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Ann= otationTest.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,418 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.util; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.List; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.IOException; +import java.io.DataInputStream; + +import org.apache.jdo.impl.enhancer.EnhancerFatalError; +import org.apache.jdo.impl.enhancer.JdoMetaMain; +import org.apache.jdo.impl.enhancer.classfile.ClassFile; +import org.apache.jdo.impl.enhancer.classfile.ClassMethod; +import org.apache.jdo.impl.enhancer.classfile.CodeAttribute; +import org.apache.jdo.impl.enhancer.classfile.ConstClass; +import org.apache.jdo.impl.enhancer.classfile.ConstFieldRef; +import org.apache.jdo.impl.enhancer.classfile.ConstMethodRef; +import org.apache.jdo.impl.enhancer.classfile.ConstNameAndType; +import org.apache.jdo.impl.enhancer.classfile.Descriptor; +import org.apache.jdo.impl.enhancer.classfile.Insn; +import org.apache.jdo.impl.enhancer.classfile.InsnConstOp; +import org.apache.jdo.impl.enhancer.classfile.VMConstants; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaData; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataFatalError; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataUserException; + + + + + +/** + * Utility class for testing a class file for correct annotation. + * + * @author Martin Zaun + */ +public class AnnotationTest + extends JdoMetaMain +{ + // return values of internal test methods + static public final int AFFIRMATIVE =3D 1; + static public final int NEGATIVE =3D 0; + static public final int ERROR =3D -1; + + // -------------------------------------------------------------------= --- + + private boolean verbose; + private String className; + private String classFileName; + private ClassFile classFile; + + public AnnotationTest(PrintWriter out, + PrintWriter err) + { + super(out, err); + } + + private int checkGetPutField(PrintWriter out, + Insn insn, + boolean jdoMethod)=20 + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + // get the instruction arguments + final InsnConstOp fieldInsn =3D (InsnConstOp)insn; + final ConstFieldRef fieldRef =3D (ConstFieldRef)fieldInsn.value(); + final ConstClass declClass =3D fieldRef.className(); + final String declClassName =3D declClass.asString(); + final ConstNameAndType fieldNameAndType =3D fieldRef.nameAndType(); + final String fieldName =3D fieldNameAndType.name().asString(); + final String fieldType =3D fieldNameAndType.signature().asString(); + + // check if field is known to be non-managed or not annotatable + final int res; + if (jdoMeta.isKnownNonManagedField(declClassName, + fieldName, fieldType)) { + if (false) { // verbose + out.println(" --- unannotated field access: " + + declClassName + "." + fieldName); + } + res =3D NEGATIVE; + } else if (jdoMethod) { + if (false) { // verbose + out.println(" --- unannotated field access: " + + declClassName + "." + fieldName); + }=20 + res =3D NEGATIVE; + } else if (jdoMeta.isPersistenceCapableClass(declClassName) + && (fieldName.equals("jdoStateManager") + || fieldName.equals("jdoFlags"))) { + if (false) { // verbose + out.println(" --- unannotated field access: " + + declClassName + "." + fieldName); + }=20 + res =3D NEGATIVE; + } else { + out.println(" !!! ERROR: missing annotation of field ac= cess: " + + declClassName + "." + fieldName); + res =3D ERROR; + } + return res; + } + =20 + private int checkInvokeStatic(PrintWriter out, + Insn insn, + boolean jdoMethod)=20 + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + // get the instruction arguments + final InsnConstOp methodInsn =3D (InsnConstOp)insn; + final ConstMethodRef methodRef =3D (ConstMethodRef)methodInsn.valu= e(); + final ConstClass declClass =3D methodRef.className(); + final String declClassName =3D declClass.asString(); + final ConstNameAndType methodNameAndType =3D methodRef.nameAndType= (); + final String methodName =3D methodNameAndType.name().asString(); + final String methodType =3D methodNameAndType.signature().asString= (); + + if (!methodName.startsWith("jdoSet") + && (!methodName.startsWith("jdoGet") + || methodName.equals("jdoGetManagedFieldCount"))) { + return NEGATIVE; + } + final String fieldName =3D methodName.substring(6); + + final int res; + final String fieldType; + if (methodName.startsWith("jdoGet")) { + fieldType =3D Descriptor.extractResultSig(methodType); + } else { + final String argSig =3D Descriptor.extractArgSig(methodType); + final int idx =3D Descriptor.nextSigElement(argSig, 0); + fieldType =3D argSig.substring(idx); + } + affirm(fieldType !=3D null); + =20 + // check if field is known to be non-managed or non-annotable + if (jdoMeta.isKnownNonManagedField(declClassName, + fieldName, fieldType)) { + out.println(" !!! ERROR: annotated access to non-manage= d field: " + + declClassName + "." + fieldName); + res =3D ERROR; + } else if (jdoMethod) { + out.println(" !!! ERROR: annotated field access in JDO = method: " + + declClassName + "." + fieldName); + res =3D ERROR; + } else { + if (verbose) { + out.println(" +++ annotated field access: " + + declClassName + "." + fieldName); + } + res =3D AFFIRMATIVE; + } + + return res; + } + =20 + private int hasAnnotation(PrintWriter out, + ClassMethod method, + String methodName)=20 + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final CodeAttribute codeAttr =3D method.codeAttribute(); + + // return if method is abstract or native + if (codeAttr =3D=3D null) + return NEGATIVE; + + int res =3D NEGATIVE; + // don't annotate readObject(ObjectInputStream) or any jdo* methods + // except for jdoPreStore() and jdoPreDelete(). + final boolean jdoMethod + =3D ((methodName.startsWith("jdo")=20 + && !(methodName.equals("jdoPreStore()") + || methodName.equals("jdoPreDelete()"))) + || methodName.equals("readObject(java.io.ObjectInputStream)= ")); + + // first instruction is a target + final Insn firstInsn =3D codeAttr.theCode(); + Insn insn =3D firstInsn.next(); + while (insn !=3D null) { + switch(insn.opcode()) { + case VMConstants.opc_getfield: + case VMConstants.opc_putfield: { + final int r =3D checkGetPutField(out, insn, jdoMethod); + if (r < NEGATIVE) { + res =3D ERROR; + } + break; + } + case VMConstants.opc_invokestatic: { + final int r =3D checkInvokeStatic(out, insn, jdoMethod); + if (r < NEGATIVE) { + res =3D ERROR; + } else if (r > NEGATIVE) { + if (res =3D=3D NEGATIVE) { + res =3D AFFIRMATIVE; + } + } + break; + } + default: + } + + insn =3D insn.next(); + } + + return res; + } + + private int testAnnotation(PrintWriter out) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(ERROR < NEGATIVE && NEGATIVE < AFFIRMATIVE); + affirm(classFile); + + int res =3D NEGATIVE; + =20 + Enumeration e =3D classFile.methods().elements(); + while (e.hasMoreElements()) { + final ClassMethod method =3D (ClassMethod)e.nextElement(); + final String methodSig =3D method.signature().asString(); + final String methodArgs =3D Descriptor.userMethodArgs(methodSi= g); + final String methodName =3D method.name().asString() + methodA= rgs; + =20 + // check class-specific enhancement + final StringWriter s =3D new StringWriter(); + int r =3D hasAnnotation(new PrintWriter(s), method, methodName= ); + if (r < NEGATIVE) { + out.println(" !!! ERROR: incorrect annotation in: " + + methodName); + out.println(s.toString()); + res =3D ERROR; + } else if (r =3D=3D NEGATIVE) { + if (verbose) { + out.println(" --- not annotated: " + + methodName); + out.println(s.toString()); + } + } else { + affirm(r > NEGATIVE); + if (verbose) { + out.println(" +++ has correct annotation: " + + methodName); + out.println(s.toString()); + } + if (res =3D=3D NEGATIVE) { + res =3D AFFIRMATIVE; + } + } + } + =20 + return res; + } + + private int parseClass(PrintWriter out) + { + DataInputStream dis =3D null; + try { + affirm(className =3D=3D null ^ classFileName =3D=3D null); + if (className !=3D null) { + dis =3D new DataInputStream(openClassInputStream(className= )); + } else { + dis =3D new DataInputStream(openFileInputStream(classFileN= ame)); + } + final boolean allowJDK12ClassFiles =3D true; + classFile =3D new ClassFile(dis, allowJDK12ClassFiles); + + // check user class name from ClassFile + final String userClassName + =3D classFile.className().asString().replace('/', '.'); + //^olsen: better throw user exception or error + affirm(className =3D=3D null || className.equals(userClassName= )); + out.println(" +++ parsed classfile"); + } catch (ClassFormatError ex) { + out.println(" !!! ERROR: format error when parsing class: " + + className); + out.println(" error: " + err); + return ERROR; + } catch (IOException ex) { + out.println(" !!! ERROR: exception while reading class: " + + className); + out.println(" exception: " + ex); + return ERROR; + } finally { + closeInputStream(dis); + } + + affirm(classFile); + return AFFIRMATIVE; + } + + private int test(PrintWriter out, + String className, + String classFileName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + this.className =3D className; + this.classFileName =3D classFileName; + affirm(className =3D=3D null ^ classFileName =3D=3D null); + final String name =3D (className !=3D null ? className : classFile= Name); + + if (verbose) { + out.println("-------------------------------------------------= ------------------------------"); + out.println(); + out.println("Test class for correct annotation: " + + name + " ..."); + } + =20 + // check parsing class + StringWriter s =3D new StringWriter(); + if (parseClass(new PrintWriter(s)) <=3D NEGATIVE) { + out.println(); + out.println("!!! ERROR: failed parsing class: " + name); + out.println(s.toString()); + return ERROR; + } + + if (verbose) { + out.println(); + out.println("+++ parsed class: " + name); + out.println(s.toString()); + } + =20 + // check annotation + s =3D new StringWriter(); + final int r =3D testAnnotation(new PrintWriter(s)); + if (r < NEGATIVE) { + out.println(); + out.println("!!! ERROR: incorrect annotation: " + name); + out.println(s.toString()); + return ERROR; + } + =20 + if (r =3D=3D NEGATIVE) { + out.println(); + out.println("--- class not annotated: " + name); + } else { + out.println(); + out.println("+++ class annotated: " + name); + } + if (verbose) { + out.println(s.toString()); + } + + return r; + } + + protected int test(PrintWriter out, + boolean verbose, + List classNames, + List classFileNames) + { + affirm(classNames); + this.verbose =3D verbose; + + out.println(); + out.println("AnnotationTest: Testing Classes for JDO Persistence-C= apability Enhancement"); + + int nofFailed =3D 0; + final int all =3D classNames.size() + classFileNames.size(); + for (int i =3D 0; i < classNames.size(); i++) { + if (test(out, (String)classNames.get(i), null) < NEGATIVE) { + nofFailed++; + } + } + for (int i =3D 0; i < classFileNames.size(); i++) { + if (test(out, null, (String)classFileNames.get(i)) < NEGATIVE)= { + nofFailed++; + } + } + final int nofPassed =3D all - nofFailed; + + out.println(); + out.println("AnnotationTest: Summary: TESTED: " + all + + " PASSED: " + nofPassed + + " FAILED: " + nofFailed); + return nofFailed; + } + =20 + // -------------------------------------------------------------------= --- + + /** + * Run the annotation test. + */ + protected int process() + { + //^olsen: to be extended for zip/jar file arguments + return test(out, options.verbose.value, + options.classNames, options.classFileNames); + } + + static public void main(String[] args) + { + final PrintWriter out =3D new PrintWriter(System.out, true); + out.println("--> AnnotationTest.main()"); + final AnnotationTest main =3D new AnnotationTest(out, out); + int res =3D main.run(args); + out.println("<-- AnnotationTest.main(): exit =3D " + res); + System.exit(res); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/= Assertion.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/ap= ache/jdo/impl/enhancer/util/Assertion.java?view=3Dauto&rev=3D158176 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Ass= ertion.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/util/Ass= ertion.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,45 @@ +/* + * Copyright 2005 The Apache Software Foundation. + *=20 + * Licensed 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=20 + *=20 + * http://www.apache.org/licenses/LICENSE-2.0 + *=20 + * Unless required by applicable law or agreed to in writing, software=20 + * distributed under the License is distributed on an "AS IS" BASIS,=20 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied= .=20 + * See the License for the specific language governing permissions and=20 + * limitations under the License. + */ + + +package org.apache.jdo.impl.enhancer.util; + + +/** + * Support for signalling internal implementation errors. + */ +public class Assertion { + + static protected final void affirm(boolean condition) { + if (!condition) + throw new InternalError("assertion failed."); + } + + static protected final void affirm(boolean condition, String msg) { + if (!condition) + throw new InternalError("assertion failed: " + msg); + } + + static protected final void affirm(Object object) { + if (object =3D=3D null) + throw new InternalError("assertion failed."); + } + + static protected final void affirm(Object object, String msg) { + if (object =3D=3D null) + throw new InternalError("assertion failed: " + msg); + } +}