Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaData.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaData.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaData.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaData.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,434 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta; + + +/** + * Provides the JDO meta information neccessary for byte-code enhancement. + * <p> + * <b>Please note: This interface deals with fully qualified names in the + * JVM notation, that is, with '/' as package separator character + * (instead of '.').</b> + */ +public interface EnhancerMetaData +{ + /** + * The JDO field flags. + */ + int CHECK_READ = 0x01; + int MEDIATE_READ = 0x02; + int CHECK_WRITE = 0x04; + int MEDIATE_WRITE = 0x08; + int SERIALIZABLE = 0x10; + + // ---------------------------------------------------------------------- + // Class Metadata + // ---------------------------------------------------------------------- + + /** + * Returns whether a class is not to be modified by the enhancer. + * <P> + * It is an error if an unenhanceable class is persistence-capable + * (or persistence-aware). The following holds: + * isKnownUnenhancableClass(classPath) + * ==> !isPersistenceCapableClass(classPath) + * @param classPath the non-null JVM-qualified name of the class + * @return true if this class is known to be unmodifiable; otherwise false + * @see #isPersistenceCapableClass(String) + */ + boolean isKnownUnenhancableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a class is persistence-capable. + * <P> + * If a persistence-capable class is also known to be unenhancable, + * an exception is thrown. + * The following holds: + * isPersistenceCapableClass(classPath) + * ==> !isKnownUnenhancableClass(classPath) + * @param classPath the non-null JVM-qualified name of the class + * @return true if this class is persistence-capable; otherwise false + * @see #isKnownUnenhancableClass(String) + */ + boolean isPersistenceCapableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a class implements java.io.Serializable. + * @param classPath the non-null JVM-qualified name of the class + * @return true if this class is serializable; otherwise false + */ + boolean isSerializableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the name of the persistence-capable superclass of a class. + * <P> + * The following holds: + * (String s = getPersistenceCapableSuperClass(classPath)) != null + * ==> isPersistenceCapableClass(classPath) + * && !isPersistenceCapableRootClass(classPath) + * @param classPath the non-null JVM-qualified name of the class + * @return the name of the PC superclass or null if there is none + * @see #isPersistenceCapableClass(String) + * @see #getPersistenceCapableRootClass(String) + */ + String getPersistenceCapableSuperClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the name of the key class of a class. + * <P> + * The following holds: + * (String s = getKeyClass(classPath)) != null + * ==> !isPersistenceCapableClass(s) + * && isPersistenceCapableClass(classPath) + * @param classPath the non-null JVM-qualified name of the class + * @return the name of the key class or null if there is none + * @see #isPersistenceCapableClass(String) + */ + String getKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns an array of field names of all declared persistent and + * transactional fields of a class. + * <P> + * The position of the field names in the result array corresponds + * to their unique field index as returned by getFieldNumber such that + * these equations hold: + * <P> getFieldNumber(getManagedFields(classPath)[i]) == i + * <P> getManagedFields(classPath)[getFieldNumber(fieldName)] == fieldName + * <P> + * This method requires all fields having been declared by + * declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @return an array of all declared persistent and transactional + * fields of a class + * @see #getFieldNumber(String, String) + * @see #declareField(String, String, String) + */ + String[] getManagedFields(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + // ---------------------------------------------------------------------- + // Field Metadata + // ---------------------------------------------------------------------- + + /** + * Returns the JVM-qualified name of the specified field's declaring + * class. The method first checks whether the class of the specified + * classPath (the JVM-qualified name) declares such a field. If yes, + * classPath is returned. Otherwise, it checks its superclasses. The + * method returns <code>null</code> for an unkown field. + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return the JVM-qualified name of the declararing class of the + * field, or <code>null</code> if there is no such field. + */ + String getDeclaringClass(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Declares a field to the JDO model passing its type information. + * <P> + * By the new JDO model, it's a requirement to declare fields to + * the model for their type information before any field information + * based on persistence-modifiers can be retrieved. This method + * passes a field's type information to the underlying JDO model. + * <P> + * There's one important exception: The method isKnownNonManagedField() + * may be called at any time. + * <P> + * The class must be persistence-capable, otherwise an exception + * is thrown. + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @param fieldSig the non-null JVM signature of the field + * @see #isPersistenceCapableClass(String) + */ + void declareField(String classPath, String fieldName, String fieldSig) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a field of a class is known to be non-managed. + * <P> + * This method differs from isManagedField() in that a field may or + * may not be managed if its not known as non-managed. + * The following holds (not vice versa!): + * isKnownNonManagedField(classPath, fieldName, fieldSig) + * ==> !isManagedField(classPath, fieldName) + * <P> + * This method doesn't require the field having been declared by + * declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @param fieldSig the non-null type signature of the field + * @return true if this field is known to be non-managed; otherwise false + * @see #isManagedField(String, String) + * @see #declareField(String, String, String) + */ + boolean isKnownNonManagedField(String classPath, + String fieldName, + String fieldSig) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a field of a class is transient transactional + * or persistent. + * <P> + * A managed field must not be known as non-managed and must be either + * transient transactional or persistent. The following holds: + * isManagedField(classPath, fieldName) + * ==> !isKnownNonManagedField(classPath, fieldName, fieldSig) + * && (isPersistentField(classPath, fieldName) + * ^ isTransactionalField(classPath, fieldName)) + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return true if this field is managed; otherwise false + * @see #isKnownNonManagedField(String, String, String) + * @see #isPersistentField(String, String) + * @see #isTransactionalField(String, String) + * @see #isPersistenceCapableClass(String) + */ + boolean isManagedField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a field of a class is transient + * transactional. + * <P> + * A transient transactional field cannot be persistent. + * The following holds: + * isTransactionalField(classPath, fieldName) + * ==> isManagedField(classPath, fieldName) + * && !isPersistentField(classPath, fieldName) + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return true if this field is transactional; otherwise false + * @see #isManagedField(String, String) + * @see #declareField(String, String, String) + */ + boolean isTransactionalField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a field of a class is persistent. + * <P> + * A persistent field cannot be transient transactional. + * The following holds: + * isPersistentField(classPath, fieldName) + * ==> isManagedField(classPath, fieldName) + * && !isTransactionalField(classPath, fieldName) + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return true if this field is persistent; otherwise false + * @see #isManagedField(String, String) + * @see #declareField(String, String, String) + */ + boolean isPersistentField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a field of a class is key. + * <P> + * A key field must be persistent. + * The following holds: + * isKeyField(classPath, fieldName) + * ==> isPersistentField(classPath, fieldName) + * && !isDefaultFetchGroupField(classPath, fieldName) + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return true if this field is key; otherwise false + * @see #isPersistentField(String, String) + * @see #declareField(String, String, String) + */ + boolean isKeyField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns whether a field of a class is part of the + * default fetch group. + * <P> + * A field in the default fetch group must be persistent. + * The following holds: + * isDefaultFetchGroupField(classPath, fieldName) + * ==> isPersistentField(classPath, fieldName) + * && !isKeyField(classPath, fieldName) + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return true if this field is part of the + * default fetch group; otherwise false + * @see #isPersistentField(String, String) + * @see #declareField(String, String, String) + */ + boolean isDefaultFetchGroupField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the unique field index of a declared, managed field of a + * class. + * <P> + * The following holds: + * int i = getFieldFlags(classPath, fieldName); + * i > 0 ==> getManagedFields(classPath)[i] == fieldName + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return the non-negative, unique field index or -1 if the field + * is non-managed + * @see #getManagedFields(String) + * @see #declareField(String, String, String) + */ + int getFieldNumber(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the field flags for a declared field of a class. + * <P> + * The following holds for the field flags: + * int f = getFieldFlags(classPath, fieldName); + * + * !isManagedField(classPath, fieldName) + * ==> (f & CHECK_READ == 0) && (f & MEDIATE_READ == 0) && + * (f & CHECK_WRITE == 0) && (f & MEDIATE_WRITE == 0) + * + * isTransactionalField(classPath, fieldName) + * ==> (f & CHECK_READ == 0) && (f & MEDIATE_READ == 0) && + * (f & CHECK_WRITE != 0) && (f & MEDIATE_WRITE == 0) + * + * isKeyField(classPath, fieldName) + * ==> (f & CHECK_READ == 0) && (f & MEDIATE_READ == 0) && + * (f & CHECK_WRITE == 0) && (f & MEDIATE_WRITE != 0) + * + * isDefaultFetchGroupField(classPath, fieldName) + * ==> (f & CHECK_READ != 0) && (f & MEDIATE_READ != 0) && + * (f & CHECK_WRITE == 0) && (f & MEDIATE_WRITE == 0) + * + * isPersistentField(classPath, fieldName) + * && isKeyField(classPath, fieldName) + * && isDefaultFetchGroupField(classPath, fieldName) + * ==> (f & CHECK_READ == 0) && (f & MEDIATE_READ == 0) && + * (f & CHECK_WRITE != 0) && (f & MEDIATE_WRITE != 0) + * <P> + * This method requires the field having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return the field flags for this field + * @see #declareField(String, String, String) + */ + int getFieldFlags(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + // ---------------------------------------------------------------------- + // Convenience Methods + // ---------------------------------------------------------------------- + + /** + * Returns whether a class is persistence-capable root class. + * <P> + * The following holds: + * isPersistenceCapableRootClass(classPath) + * <==> isPersistenceCapableClass(classPath) + * && getPersistenceCapableSuperClass(classPath) == null + * @param classPath the non-null JVM-qualified name of the class + * @return true if this class is persistence-capable and does not + * derive from another persistence-capable class; otherwise false + */ + boolean isPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the name of the persistence-capable root class of a class. + * <P> + * The following holds: + * (String s = getPersistenceCapableRootClass(classPath)) != null + * ==> isPersistenceCapableClass(classPath) + * && getPersistenceCapableSuperClass(classPath) == null + * @param classPath the non-null JVM-qualified name of the class + * @return the name of the least-derived persistence-capable class that + * is equal to or a super class of the argument class; if the + * argument class is not persistence-capable, null is returned. + */ + String getPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the name of the key class of the next persistence-capable + * superclass that defines one. + * <P> + * The following holds: + * (String s = getSuperKeyClass(classPath)) != null + * ==> !isPersistenceCapableClass(s) + * && isPersistenceCapableClass(classPath) + * && !isPersistenceCapableRootClass(classPath) + * @param classPath the non-null JVM-qualified name of the class + * @return the name of the key class or null if there is none + * @see #getKeyClass(String) + * @see #getPersistenceCapableSuperClass(String) + */ + String getSuperKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns an array of field names of all key fields of a class. + * <P> + * This method requires all fields having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @return an array of all declared key fields of a class + * @see #declareField(String, String, String) + */ + String[] getKeyFields(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the unique field index of some declared, managed fields of a + * class. + * <P> + * This method requires all fields having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldNames the non-null array of names of the declared fields + * @return the non-negative, unique field indices + * @see #declareField(String, String, String) + */ + int[] getFieldNumber(String classPath, String[] fieldNames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the field flags for some declared, managed fields of a class. + * <P> + * This method requires all fields having been declared by declareField(). + * @param classPath the non-null JVM-qualified name of the class + * @param fieldNames the non-null array of names of the declared fields + * @return the field flags for the fields + * @see #declareField(String, String, String) + */ + int[] getFieldFlags(String classPath, String[] fieldNames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; +}
Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataFatalError.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataFatalError.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataFatalError.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataFatalError.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,72 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.jdo.impl.enhancer.meta; + + +/** + * Thrown to indicate that an access to JDO meta-data failed due to a + * serious error, which might have left the meta-data component in an + * inconsistent state. + */ +public class EnhancerMetaDataFatalError + //^olsen: provisional, convert to a checked exception + extends RuntimeException +{ + /** + * An optional nested exception. + */ + public final Throwable nested; + + /** + * Constructs an <code>EnhancerMetaDataFatalError</code> with no detail message. + */ + public EnhancerMetaDataFatalError() + { + this.nested = null; + } + + /** + * Constructs an <code>EnhancerMetaDataFatalError</code> with the specified + * detail message. + */ + public EnhancerMetaDataFatalError(String msg) + { + super(msg); + this.nested = null; + } + + /** + * Constructs an <code>EnhancerMetaDataFatalError</code> with an optional + * nested exception. + */ + public EnhancerMetaDataFatalError(Throwable nested) + { + super(nested.toString()); + this.nested = nested; + } + + /** + * Constructs an <code>EnhancerMetaDataFatalError</code> with the specified + * detail message and an optional nested exception. + */ + public EnhancerMetaDataFatalError(String msg, Throwable nested) + { + super(msg); + this.nested = nested; + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataUserException.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataUserException.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataUserException.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/EnhancerMetaDataUserException.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,72 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.jdo.impl.enhancer.meta; + + +/** + * Thrown to indicate that an access to JDO meta-data failed; the + * meta-data component is assured to remain in consistent state. + */ +public class EnhancerMetaDataUserException + //^olsen: provisional, convert to a checked exception + extends RuntimeException +{ + /** + * An optional nested exception. + */ + public final Throwable nested; + + /** + * Constructs an <code>EnhancerMetaDataUserException</code> with no detail + * message. + */ + public EnhancerMetaDataUserException() + { + this.nested = null; + } + + /** + * Constructs an <code>EnhancerMetaDataUserException</code> with the specified + * detail message. + */ + public EnhancerMetaDataUserException(String msg) + { + super(msg); + this.nested = null; + } + + /** + * Constructs an <code>EnhancerMetaDataUserException</code> with an optional + * nested exception. + */ + public EnhancerMetaDataUserException(Throwable nested) + { + super("nested exception: " + nested); + this.nested = nested; + } + + /** + * Constructs an <code>EnhancerMetaDataUserException</code> with the specified + * detail message and an optional nested exception. + */ + public EnhancerMetaDataUserException(String msg, Throwable nested) + { + super(msg); + this.nested = nested; + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/ExtendedMetaData.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/ExtendedMetaData.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/ExtendedMetaData.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/ExtendedMetaData.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,111 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta; + + +/** + * Provides extended JDO meta information for byte-code enhancement. + */ +public interface ExtendedMetaData + extends EnhancerMetaData +{ + /** + * Gets all known classnames. + * + * @return All known classnames. + */ + String[] getKnownClasses() + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Gets the modifiers of a class. The return value is a constant of the + * <code>java.lang.reflect.Modifier</code> class. + * + * @param classname The classname. + * @return The modifiers. + * @see java.lang.reflect.Modifier + */ + int getClassModifiers(String classname) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Returns the name of the superclass of a class. + * <P> + * @param classPath the JVM-qualified name of the class + * @return the name of the superclass or null if there is none + */ + String getSuperClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Gets all known fieldnames of a class. + * + * @param classname The classname. + * @return All known fieldnames. + */ + String[] getKnownFields(String classname) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Gets the type of a field. + * + * @param classname The classname. + * @param fieldname The fieldname. + * @return The type of the field. + */ + String getFieldType(String classname, + String fieldname) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Gets the modifiers of a field. The return value is a constant of the + * <code>java.lang.reflect.Modifier</code> class. + * + * @param classname The classname. + * @param fieldname The fieldname. + * @return The modifiers. + * @see java.lang.reflect.Modifier + */ + int getFieldModifiers(String classname, + String fieldname) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + // convenience methods + + /** + * Gets the type of some fields. + * + * @param classname The classname. + * @param fieldnames The fieldnames. + * @return The type of the fields. + */ + String[] getFieldType(String classname, + String[] fieldnames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; + + /** + * Gets the modifiers of some fields. + * + * @param classname The classname. + * @param fieldnames The fieldnames. + * @return The modifiers. + * @see java.lang.reflect.Modifier + */ + int[] getFieldModifiers(String classname, + String[] fieldnames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError; +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaModel.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaModel.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaModel.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaModel.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,158 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.model; + +import java.io.InputStream; + +import org.apache.jdo.impl.enhancer.util.ResourceLocator; +import org.apache.jdo.impl.model.java.runtime.RuntimeJavaModel; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOModel; + +/** + * Provides some basic Java type information based on JVM descriptors. + * + * @author Michael Bouschen + * @author Martin Zaun + */ +public class EnhancerJavaModel + extends RuntimeJavaModel +{ + /** + * The "package" jdo file. + */ + final private ResourceLocator locator; + + /** + * Creates an instance. + */ + public EnhancerJavaModel(ClassLoader classLoader, + ResourceLocator locator) + { + super(classLoader, false); + this.locator = locator; + } + + /** + * Finds a resource with a given name. This method returns + * <code>null</code> if no resource with this name is found. + * The name of a resource is a "/"-separated path name. + */ + public InputStream getInputStreamForResource(String resourceName) + { + // first try the locator + InputStream stream = locator.getInputStreamForResource(resourceName); + if (stream == null) + // if the locator cannot find the resource try the class loader + stream = super.getInputStreamForResource(resourceName); + return stream; + } + + // ===== Methods not defined in JavaModel ===== + + /** + * Creates a new JavaType instance for the specified Class object. + * <p> + * This implementation returns a EnhancerJavaType instance. + * @param clazz the Class instance representing the type + * @return a new JavaType instance + */ + protected JavaType createJavaType(Class clazz, JDOModel jdoModel) + { + return new EnhancerJavaType(clazz, getJDOModel(), this); + } + + /** + * Returns the fully qualified name of the specified type representation. + */ + public String getTypeName(String sig) + { + // translates a VM type field signature into Java-format signature + final int n = sig.length(); + affirm(n > 0, "invalid field signature: \"\""); + + // handle arrays + if (sig.startsWith("[")) + return sig.replace('/','.'); + + // parse rest of signature + final String name; + final char c = sig.charAt(0); + switch (c) { + case 'Z': + name = "boolean"; + break; + case 'C': + name = "char"; + break; + case 'B': + name = "byte"; + break; + case 'S': + name = "short"; + break; + case 'I': + name = "int"; + break; + case 'F': + name = "float"; + break; + case 'J': + name = "long"; + break; + case 'D': + name = "double"; + break; + case 'L': + // return reference type with array dimensions + affirm(sig.indexOf(';') == n - 1, + "invalid field signature: " + sig); + name = sig.substring(1, n - 1); + affirm(isValidName(name, '/'), + "invalid field signature: " + sig); + return name.replace('/','.'); + default: + name = ""; + affirm(false, "invalid field signature: " + sig); + } + return name; + } + + static private boolean isValidName(String name, char separator) + { + final int n = name.length(); + if (n == 0) { + return false; + } + if (!Character.isJavaIdentifierStart(name.charAt(0))) { + return false; + } + for (int i = 1; i < n; i++) { + final char c = name.charAt(i); + if (!Character.isJavaIdentifierPart(c) && c != separator) { + return false; + } + } + return true; + } + + static protected final void affirm(boolean condition, String msg) { + if (!condition) + throw new InternalError("assertion failed: " + msg); + } + +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaType.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaType.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaType.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerJavaType.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,64 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.model; + +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataFatalError; +import org.apache.jdo.impl.model.java.runtime.RuntimeJavaType; +import org.apache.jdo.model.java.JavaModel; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOModel; + + + +/** + * Provides some basic Java type information based on JVM descriptors. + * + * @author Michael Bouschen + * @since JDO 1.0.1 + */ +public class EnhancerJavaType + extends RuntimeJavaType +{ + /** The declaring EnhancerJavaModel instance. */ + private JavaModel javaModel = null; + + /** + * Creates an instance. + */ + public EnhancerJavaType(Class clazz, JDOModel jdoModel, JavaModel javaModel) + { + super(clazz, jdoModel); + this.javaModel = javaModel; + } + + // ===== Methods not defined in JavaType ===== + + /** + * Returns a JavaType instance for the specified Class object. + * <p> + * This implementation delegates the call to the javaModel. + * @param clazz the Class instance representing the type + * @return a JavaType instance for the name of the specified class + * object or <code>null</code> if not present in this model instance. + */ + protected JavaType getJavaTypeInternal(Class clazz) + { + return javaModel.getJavaType(clazz); + } + + +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerMetaDataJDOModelImpl.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerMetaDataJDOModelImpl.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerMetaDataJDOModelImpl.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/model/EnhancerMetaDataJDOModelImpl.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,555 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.model; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.File; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +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.meta.util.EnhancerMetaDataBaseModel; +import org.apache.jdo.impl.enhancer.util.CombinedResourceLocator; +import org.apache.jdo.impl.enhancer.util.ListResourceLocator; +import org.apache.jdo.impl.enhancer.util.PathResourceLocator; +import org.apache.jdo.impl.enhancer.util.ResourceLocator; +import org.apache.jdo.impl.model.jdo.caching.JDOModelFactoryImplCaching; +import org.apache.jdo.impl.model.jdo.util.TypeSupport; +import org.apache.jdo.model.ModelException; +import org.apache.jdo.model.ModelFatalException; +import org.apache.jdo.model.java.JavaField; +import org.apache.jdo.model.java.JavaModel; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOClass; +import org.apache.jdo.model.jdo.JDOField; +import org.apache.jdo.model.jdo.JDOModel; +import org.apache.jdo.model.jdo.JDOModelFactory; +import org.apache.jdo.model.jdo.PersistenceModifier; + +/** + * Provides the JDO meta information based on a JDO meta model. + */ +public class EnhancerMetaDataJDOModelImpl + extends EnhancerMetaDataBaseModel + implements EnhancerMetaData +{ + /** + * The jdoModel instance. + */ + private final JDOModel jdoModel; + + /** + * The model instance. + */ + private final EnhancerJavaModel javaModel; + + /** + * The JavaType representation for java.io.Serializable. + */ + private final JavaType serializableJavaType; + + /** + * Creates an instance. + */ + public EnhancerMetaDataJDOModelImpl(PrintWriter out, + boolean verbose, + List jdoFileNames, + List jarFileNames, + String sourcePath) + throws EnhancerMetaDataFatalError + { + super(out, verbose); + + try { + final List locators = new ArrayList(); + ClassLoader classLoader = null; + + // create resource locator for specified jdo files + if (jdoFileNames != null && !jdoFileNames.isEmpty()) { + final StringBuffer s = new StringBuffer(); + for (Iterator i = jdoFileNames.iterator(); i.hasNext();) { + s.append(" " + i.next()); + } + final ResourceLocator jdos + = new ListResourceLocator(out, verbose, jdoFileNames); + //printMessage(getI18N("enhancer.metadata.using_jdo_files", + // s.toString())); + locators.add(jdos); + } + + // create resource locator for specified jar files + if (jarFileNames != null && !jarFileNames.isEmpty()) { + final StringBuffer s = new StringBuffer(); + final Iterator i = jarFileNames.iterator(); + s.append(i.next()); + while (i.hasNext()) { + s.append(File.pathSeparator + i.next()); + } + final PathResourceLocator jars + = new PathResourceLocator(out, verbose, s.toString()); + //printMessage(getI18N("enhancer.metadata.using_jar_files", + // s.toString())); + locators.add(jars); + classLoader = jars.getClassLoader(); + } + + // create resource locator for specified source path + if (sourcePath != null && sourcePath.length() > 0) { + final PathResourceLocator path + = new PathResourceLocator(out, verbose, sourcePath); + //printMessage(getI18N("enhancer.metadata.using_source_path", + // sourcePath)); + locators.add(path); + classLoader = path.getClassLoader(); + } + + if (classLoader == null) { + // use the current class loader as the default, if there is + // no -s option and no archives specified. + classLoader = EnhancerMetaDataJDOModelImpl.class.getClassLoader(); + } + + // print warning if no meta-data source specified + if (locators.isEmpty()) { + printWarning(getI18N("enhancer.metadata.using_no_metadata")); + } + + // create JavaModel with combined resource locators + final ResourceLocator locator + = new CombinedResourceLocator(out, verbose, locators); + //^olsen: wrap with timing jdo file locator + //if (options.doTiming.value) { + // classLocator = new ResourceLocatorTimer(classLocator); + //} + javaModel = new EnhancerJavaModel(classLoader, locator); + final JDOModelFactory factory = JDOModelFactoryImplCaching.getInstance(); + affirm(factory != null); + jdoModel = factory.createJDOModel(javaModel); + affirm(jdoModel != null); + javaModel.setJDOModel(jdoModel); + serializableJavaType = javaModel.getJavaType("java.io.Serializable"); + } catch (IOException ex) { + final String msg + = getI18N("enhancer.metadata.io_error", ex.getMessage()); + throw new EnhancerMetaDataFatalError(msg, ex); + } catch (ModelFatalException ex) { + final String msg + = getI18N("enhancer.metadata.jdomodel_error", ex.getMessage()); + throw new EnhancerMetaDataFatalError(msg, ex); + } catch (ModelException ex) { + final String msg + = getI18N("enhancer.metadata.jdomodel_error", ex.getMessage()); + throw new EnhancerMetaDataFatalError(msg, ex); + } + } + + // ---------------------------------------------------------------------- + + private JDOClass getJDOClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final String className = classPath.replace('/', '.'); + final JDOClass clazz = jdoModel.getJDOClass(className); + return clazz; + } + + private JDOField getJDOField(String classPath, + String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + return null; + } + final JDOField field = clazz.getDeclaredField(fieldName); + affirm(field == null || field.getDeclaringClass() == clazz, + "field not declared in class: " + classPath + "." + fieldName); + return field; + } + + private boolean hasFieldModifier(String classPath, + String fieldName, + int fieldModifier) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + if (field == null) { + return false; + } + final int pm = field.getPersistenceModifier(); + affirm(pm != PersistenceModifier.UNSPECIFIED, + "field modifier 'UNSPECIFIED': " + classPath + "." + fieldName); + return (pm & fieldModifier) != 0; + } + + // ---------------------------------------------------------------------- + + + /** + * Returns the JVM-qualified name of the specified field's declaring + * class. The method first checks whether the class of the specified + * classPath (the JVM-qualified name) declares such a field. If yes, + * classPath is returned. Otherwise, it checks its superclasses. The + * method returns <code>null</code> for an unkown field. + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return the JVM-qualified name of the declararing class of the + * field, or <code>null</code> if there is no such field. + */ + public String getDeclaringClass(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(classPath); + affirm(fieldName); + final String className = classPath.replace('/', '.'); + try { + final JavaType javaType = javaModel.getJavaType(className); + final JavaField javaField = javaType.getJavaField(fieldName); + final JavaType declaringClass = javaField.getDeclaringClass(); + return declaringClass.getName().replace('.', '/'); + } catch (ModelFatalException ex) { + throw new EnhancerMetaDataUserException(ex); + } + } + + /** + * Declares a field to the JDO model passing its type information. + * @see declareField(String, String, String) + */ +/* + public void declareField(String classPath, + String fieldName, + String fieldSig) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(classPath); + affirm(fieldName); + affirm(fieldSig); + final JDOClass clazz = getJDOClass(classPath); + affirm(clazz != null, + "class is not persistence-capable: " + classPath); + try { + final JDOField field = clazz.createJDOField(fieldName); + affirm(field != null, + "cannot create JDO field: " + classPath + "." + fieldName); + field.setType(fieldSig); + affirm(fieldSig == field.getType()); + + //^olsen: cleanup debugging code + String s0 = model.getJavaModel().getTypeName(fieldSig); + String s1 = (String)model.getJavaModel().getTypeForName(s0); + //out.println("s0 = " + s0); + //out.println("s1 = " + s1); + affirm(fieldSig.equals(s1)); + } catch (JDOModelException ex) { + throw new EnhancerMetaDataUserException(ex); + } + } +*/ + + /** + * Declares a field to the JDO model passing its type information. + */ + public void declareField(String classPath, + String fieldName, + String fieldSig) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(classPath); + affirm(fieldName); + try { + final JDOClass clazz = getJDOClass(classPath); + JavaType javaClass = clazz.getJavaType(); + affirm(javaClass != null, + "cannot find class file for class: " + classPath); + JavaField javaField = javaClass.getJavaField(fieldName); + affirm(javaField != null, + "cannot find java field " + classPath + "." + fieldName); + JavaType fieldType = javaField.getType(); + JDOField field = clazz.getField(fieldName); + // if field not known by JDOClass (not specified in JDO XML), + // create the field only if the model's method of default + // calculation would yield a persistent field. We must not + // change the models state by newly created fields with + // a persistence-modifier "none", because this would lead to + // in a different annotation by isKnownNonManagedField(). + if (field == null + && TypeSupport.isPersistenceFieldType(fieldType)) { + field = clazz.createJDOField(fieldName); + affirm(field != null, + "cannot create JDO field: " + + classPath + "." + fieldName); + affirm(field.getPersistenceModifier() + == PersistenceModifier.UNSPECIFIED, + "unknown, specified JDO field: " + + classPath + "." + fieldName); + } + field.setJavaField(javaField); + affirm(fieldType == field.getType()); + affirm(field.getPersistenceModifier() + != PersistenceModifier.UNSPECIFIED, + "known, unspecified JDO field: " + classPath + "." + fieldName); + } catch (ModelFatalException ex) { + throw new EnhancerMetaDataUserException(ex); + } catch (ModelException ex) { + throw new EnhancerMetaDataUserException(ex); + } + } + + /** + * Tests whether a class is known to be persistence-capable. + */ + public boolean isPersistenceCapableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + return (clazz != null); + } + + /** + * Returns whether a class implements java.io.Serializable + * @param classPath the non-null JVM-qualified name of the class + * @return true if this class is serializable; otherwise false + */ + public boolean isSerializableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final String className = classPath.replace('/', '.'); + final JavaType javaType = javaModel.getJavaType(className); + return javaType.isCompatibleWith(serializableJavaType); + } + + /** + * Returns the name of the persistence-capable root class of a class. + */ +/* + public String getPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + return null; + } + final JDOClass root = clazz.getPersistenceCapableRootClass(); + if (root == null) { + return null; + } + final String name = root.getName(); + affirm(name != null); + return name.replace('.', '/'); + } +*/ + + /** + * Returns the name of the persistence-capable superclass of a class. + */ + public String getPersistenceCapableSuperClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + return null; + } + final String name = clazz.getPersistenceCapableSuperclassName(); + return (name != null ? name.replace('.', '/') : null); + } + + /** + * Returns the name of the key class of a persistence-capable class. + */ + public String getKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + return null; + } + final String name = clazz.getDeclaredObjectIdClassName(); + return (name != null ? name.replace('.', '/') : null); + } + + /** + * Returns an array of field names of all declared persistent and + * transactional fields of a class. + */ + public String[] getManagedFields(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + return new String[]{}; + } + + final JDOField[] fields = clazz.getDeclaredManagedFields(); + if (fields == null) { + return new String[]{}; + } + affirm(fields.length == clazz.getDeclaredManagedFieldCount()); + + final int n = fields.length; + final String[] names = new String[n]; + for (int i = 0; i < n; i++) { + affirm(fields[i] != null); + affirm(fields[i].getRelativeFieldNumber() == i); + affirm(fields[i].isManaged()); + names[i] = fields[i].getName(); + affirm(names[i] != null); + } + return names; + } + + /** + * Returns whether a field of a class is known to be non-managed. + */ + //^olsen: cleanup old code +/* + public boolean isKnownNonManagedField(String classPath, String fieldName) + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + // class not known to be persistence-capable + return true; + } + final JDOField field = clazz.getField(fieldName); + if (field == null) { + // field not known by JDOClass (thus, not specified in JDO XML) + return false; + } + return field.isKnownNonManaged(); + } +*/ + + /** + * Returns whether a field of a class is known to be non-managed. + */ + public boolean isKnownNonManagedField(String classPath, + String fieldName, + String fieldSig) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(classPath); + affirm(fieldName); + affirm(fieldSig); + try { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + // class not known to be persistence-capable + return true; + } + + // check whether field is managed only if field's + // persistence-modifier is known by the JDO model + final JDOField field = clazz.getField(fieldName); + if (field != null && (field.getPersistenceModifier() + != PersistenceModifier.UNSPECIFIED)) { + // only field's persistence-modifier known by model + return !field.isManaged(); + } + + // field not known by JDOClass (not specified in JDO XML) + // apply model's method of default calculation without + // changing the model's state + JavaType fieldType = javaModel.getJavaType(javaModel.getTypeName(fieldSig)); + affirm(fieldType != null, + "cannot get java type for: " + fieldSig); + return !TypeSupport.isPersistenceFieldType(fieldType); + } catch (ModelFatalException ex) { + throw new EnhancerMetaDataUserException(ex); + } + } + + /** + * Tests whether a field of a class is transient transactional or + * persistent. + */ + public boolean isManagedField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + return hasFieldModifier(classPath, fieldName, + (PersistenceModifier.PERSISTENT + | PersistenceModifier.POSSIBLY_PERSISTENT + | PersistenceModifier.TRANSACTIONAL)); + } + + /** + * Tests whether a field of a class is persistent. + */ + public boolean isPersistentField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + return hasFieldModifier(classPath, fieldName, + (PersistenceModifier.PERSISTENT + | PersistenceModifier.POSSIBLY_PERSISTENT)); + } + + /** + * Tests whether a field of a class is transient transactional. + */ + public boolean isTransactionalField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + return hasFieldModifier(classPath, fieldName, + PersistenceModifier.TRANSACTIONAL); + } + + /** + * Tests whether a field of a class is known to be Key. + */ + public boolean isKeyField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + if (field == null) { + return false; + } + return field.isPrimaryKey(); + } + + /** + * Tests whether a field of a class is known to be part of the + * Default Fetch Group. + */ + public boolean isDefaultFetchGroupField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + if (field == null) { + return false; + } + return field.isDefaultFetchGroup(); + } + + /** + * Returns the unique field index of a declared, persistent field of a + * class. + */ + public int getFieldNumber(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + if (field == null) { + return -1; + } + return field.getRelativeFieldNumber(); + } + +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/EnhancerMetaDataPropertyImpl.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/EnhancerMetaDataPropertyImpl.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/EnhancerMetaDataPropertyImpl.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/EnhancerMetaDataPropertyImpl.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,482 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.jdo.impl.enhancer.meta.prop; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.InputStream; +import java.io.FileInputStream; + +import java.util.Iterator; +import java.util.Properties; + +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataFatalError; +import org.apache.jdo.impl.enhancer.meta.EnhancerMetaDataUserException; +import org.apache.jdo.impl.enhancer.meta.ExtendedMetaData; +import org.apache.jdo.impl.enhancer.meta.util.EnhancerMetaDataBaseModel; + + + + +/** + * Provides the JDO meta information based on properties. + */ +public class EnhancerMetaDataPropertyImpl + extends EnhancerMetaDataBaseModel + implements ExtendedMetaData +{ + /** + * The model instance. + */ + final private MetaDataProperties model; + + /** + * Creates an instance. + */ + public EnhancerMetaDataPropertyImpl(PrintWriter out, + boolean verbose, + Properties properties) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + super(out, verbose); + affirm(properties != null); + model = new MetaDataProperties(properties); + initModel(); + affirm(model != null); + printMessage(getI18N("enhancer.metadata.using_properties", + "<unnamed>")); + } + + /** + * Creates an instance. + */ + public EnhancerMetaDataPropertyImpl(PrintWriter out, + boolean verbose, + String fileName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + super(out, verbose); + affirm(fileName != null); + + InputStream stream = null; + try { + stream = new FileInputStream(fileName); + final Properties properties = new Properties(); + properties.load(stream); + model = new MetaDataProperties(properties); + initModel(); + } catch (IOException ex) { + final String msg + = getI18N("enhancer.metadata.io_error", ex.getMessage()); + throw new EnhancerMetaDataFatalError(msg, ex); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException ex) { + final String msg + = getI18N("enhancer.metadata.io_error", + ex.getMessage()); + throw new EnhancerMetaDataFatalError(msg, ex); + } + } + } + affirm(model != null); + printMessage(getI18N("enhancer.metadata.using_properties", fileName)); + } + + // ---------------------------------------------------------------------- + + /** + * Initializes the model. + */ + private void initModel() + { + // we'd like to have all classes (and fields) parsed and + // cached in order to early report errors with the properties + final String[] classNames = model.getKnownClassNames(); + affirm(classNames != null); + for (int i = classNames.length - 1; i >= 0; i--) { + final JDOClass clazz = getJDOClass(classNames[i]); + affirm(clazz != null); + } + } + + /** + * Returns the JVM-qualified name of the specified field's declaring + * class. The method first checks whether the class of the specified + * classPath (the JVM-qualified name) declares such a field. If yes, + * classPath is returned. Otherwise, it checks its superclasses. The + * method returns <code>null</code> for an unkown field. + * @param classPath the non-null JVM-qualified name of the class + * @param fieldName the non-null name of the field + * @return the JVM-qualified name of the declararing class of the + * field, or <code>null</code> if there is no such field. + */ + public String getDeclaringClass(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + String declaringClass = null; + JDOField field = getJDOField(classPath, fieldName); + if (field != null) { + // this class declares the filed => return classPath + declaringClass = classPath; + } else { + String superclass = getSuperClass(classPath); + if (superclass != null) { + declaringClass = getDeclaringClass(superclass, fieldName); + } + } + return declaringClass; + } + + /** + * Declares a field to the JDO model passing its type information. + */ + public void declareField(String classPath, + String fieldName, + String signature) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + affirm(isPersistenceCapableClass(classPath)); + // nothing to be done: the properties-based model doesn't + // support default calculation of persistence modifiers + } + + /** + * Returns whether a class is known to be persistence-capable. + */ + public boolean isPersistenceCapableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + return (clazz != null ? clazz.isPersistent() : false); + } + + /** + * Returns whether a class implements java.io.Serializable. + * @param classPath the non-null JVM-qualified name of the class + * @return true if this class is serializable; otherwise false + */ + public boolean isSerializableClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + return (clazz != null ? clazz.isSerializable() : false); + } + + /** + * Returns the name of the persistence-capable root class of a class. + */ +//@olsen: use the inherited method +/* + public String getPersistenceCapableRootClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + String pcRootClass = null; + for (String clazz = classPath; + clazz != null; + clazz = getSuperClass(clazz)) { + if (isPersistenceCapableClass(clazz)) { + pcRootClass = clazz; + } + } + return pcRootClass; + } +*/ + + /** + * Returns the name of the persistence-capable superclass of a class. + */ + public String getPersistenceCapableSuperClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + for (String clazz = getSuperClass(classPath); + clazz != null; + clazz = getSuperClass(clazz)) { + if (isPersistenceCapableClass(clazz)) { + return clazz; + } + } + return null; + } + + /** + * Returns the superclass of a class. + */ + public final String getSuperClass(String classname) + { + final JDOClass clazz = getJDOClass(classname); + return (clazz != null ? clazz.getSuperClassName() : null); + } + + /** + * Returns the name of the key class of a persistence-capable class. + */ + public String getKeyClass(String classPath) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + return (clazz != null ? clazz.getOidClassName() : null); + } + + /** + * Returns whether a field of a class is known to be non-managed. + */ + public boolean isKnownNonManagedField(String classPath, + String fieldName, + String fieldSig) + { + final JDOClass clazz = getJDOClass(classPath); + if (clazz == null) { + return true; + } + final JDOField field = getJDOField(clazz, fieldName); + return (field != null ? field.isKnownTransient() : false); + } + + /** + * Returns whether a field of a class is transient transactional + * or persistent. + */ + public boolean isManagedField(String classPath, String fieldName) + { + final JDOField field = getJDOField(classPath, fieldName); + return (field != null + ? (field.isPersistent() | field.isTransactional()) : false); + } + + /** + * Returns whether a field of a class is known to be persistent. + */ + public boolean isPersistentField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + return (field != null ? field.isPersistent() : false); + } + + /** + * Returns whether a field of a class is known to be transactional. + */ + public boolean isTransactionalField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + return (field != null ? field.isTransactional() : false); + } + + /** + * Returns whether a field of a class is known to be Primary Key. + */ + public boolean isKeyField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + return (field != null ? field.isKey() : false); + } + + /** + * Returns whether a field of a class is known to be part of the + * Default Fetch Group. + */ + public boolean isDefaultFetchGroupField(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOField field = getJDOField(classPath, fieldName); + return (field != null ? field.isInDefaultFetchGroup() : false); + } + + /** + * Returns the unique field index of a declared, persistent field of a + * class. + */ + public int getFieldNumber(String classPath, String fieldName) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final JDOClass clazz = getJDOClass(classPath); + return (clazz != null ? clazz.getIndexOfField(fieldName) : -1); + } + + /** + * Returns an array of field names of all declared, persistent fields + * of a class. + */ + public String[] getManagedFields(String classname) + { + final JDOClass clazz = getJDOClass(classname); + return (clazz != null ? clazz.getManagedFieldNames() : new String[]{}); + } + + /** + * Not member of EnhancerMetaData Interface. + */ + public final String[] getKnownClasses() + { + return model.getKnownClassNames(); + } + + /** + * Gets all known fields of a class. + */ + public final String[] getKnownFields(String classname) + { + final JDOClass clazz = getJDOClass(classname); + return (clazz != null ? clazz.getFieldNames() : new String[]{}); + } + + + /** + * Gets the access modifier of a class. + */ + public final int getClassModifiers(String classname) + { + final JDOClass clazz = getJDOClass(classname); + return (clazz != null ? clazz.getModifiers() : 0); + } + + /** + * Gets the access modifier of a field. + */ + public final int getFieldModifiers(String classname, + String fieldname) + { + final JDOField field = getJDOField(classname, fieldname); + return (field != null ? field.getModifiers() : 0); + } + + public final String getFieldType(String classname, + String fieldname) + { + final JDOField field = getJDOField(classname, fieldname); + return (field != null ? field.getType() : null); + } + + public final String[] getFieldType(String classname, + String[] fieldnames) + { + final int n = (fieldnames != null ? fieldnames.length : 0); + final String[] types = new String[n]; + for (int i = 0; i < n; i++) { + types[i] = getFieldType(classname, fieldnames[i]); + } + return types; + } + + public final int[] getFieldModifiers(String classname, + String[] fieldnames) + throws EnhancerMetaDataUserException, EnhancerMetaDataFatalError + { + final int n = (fieldnames != null ? fieldnames.length : 0); + final int[] mods = new int[n]; + for (int i = 0; i < n; i++) { + mods[i] = getFieldModifiers(classname, fieldnames[i]); + } + return mods; + } + + private final JDOClass getJDOClass(String classname) + throws EnhancerMetaDataUserException + { + return model.getJDOClass(classname); + } + + private final JDOField getJDOField(JDOClass clazz, + String fieldname) + { + return (clazz != null ? clazz.getField(fieldname) : null); + } + + private final JDOField getJDOField(String classname, + String fieldname) + { + final JDOClass clazz = getJDOClass(classname); + return getJDOField(clazz, fieldname); + } + + // ---------------------------------------------------------------------- + + public static void main(String[] argv) + { + final PrintWriter out = new PrintWriter(System.out, true); + + if (argv.length != 1) { + System.err.println("No property file specified."); + return; + } + + final Properties p = new Properties(); + try { + java.io.InputStream in = + new java.io.FileInputStream(new java.io.File(argv[0])); + p.load(in); + in.close(); + out.println("PROPERTIES: " + p); + out.println("############"); + MetaDataProperties props = new MetaDataProperties(p); + } catch (Throwable ex) { + ex.printStackTrace(System.err); + } + + final EnhancerMetaDataPropertyImpl jdo + = new EnhancerMetaDataPropertyImpl(out, true, p); + final String[] classes = jdo.getKnownClasses(); + for (int k = 0; k < classes.length; k++) { + final String clazz = classes[k]; + out.println("CLAZZ: " + clazz); + out.println("\tpersistent: " + + jdo.isPersistenceCapableClass(clazz)); + out.println("\tpersistent root: " + + jdo.isPersistenceCapableRootClass(clazz)); + out.println("\tpersistent root class: " + + jdo.getPersistenceCapableRootClass(clazz)); + out.println("\tpersistent super class: " + + jdo.getPersistenceCapableSuperClass(clazz)); + out.println("\tkey class: " + + jdo.getKeyClass(clazz)); + + final String[] fields = jdo.getKnownFields(clazz); + for (int j = 0; j < fields.length; j++) { + final String field = fields[j]; + out.println("FIELD: " + field); + out.println("\tpersistent field: " + + jdo.isPersistentField(clazz, field)); + out.println("\tpk field: " + + jdo.isKeyField(clazz, field)); + out.println("\tdfg field: " + + jdo.isDefaultFetchGroupField(clazz, field)); + out.println("\tnumber: " + + jdo.getFieldNumber(clazz, field)); + + final String[] names = jdo.getManagedFields(clazz); + final int n = (fields != null ? names.length : 0); + out.println("managed fields: number: " + n); + for (int i = 0; i < n; i++) { + final String name = names[i]; + out.println(i + ": " + name + + " number: " + + jdo.getFieldNumber(clazz, name) + + " pk: " + + jdo.isKeyField(clazz, name) + + " dfg: " + + jdo.isDefaultFetchGroupField(clazz, name)); + } + } + } + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/JDOClass.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/JDOClass.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/JDOClass.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/meta/prop/JDOClass.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,349 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.enhancer.meta.prop; + +import java.lang.reflect.Modifier; + +import java.util.Comparator; +import java.util.List; +import java.util.Collections; +import java.util.ArrayList; + + +/** + * A class to hold all parsed attributes of a class. + */ +final class JDOClass +{ + /** + * The name of the class. + */ + private final String name; + + /** + * The name of the superclass. + */ + private String superClassName = null; + + /** + * The name of the oid class. + */ + private String oidClassName = null; + + /** + * The access modifier of the class. + */ + private int modifiers = Modifier.PUBLIC; + + /** + * The persistence modifier of the class. + */ + private boolean isPersistent = true; + + /** + * Flag indicating whether this class is serializable. + */ + private boolean isSerializable = true; + + /** + * A list of all parsed fields. + */ + private final List fields = new ArrayList(); + + /** + * The names of all managed fields this class. + */ + private String[] managedFieldNames = null; + + /** + * The names of all fields this class. + */ + private String[] fieldNames = null; + + /** + * Constructs a new object with the given name. + * + * @param name The name of the class. + */ + JDOClass(String name) + { + this.name = name; + } + + /** + * Returns the name of the class. + * + * @return The name of the class. + */ + public String getName() + { + return name; + } + + /** + * Returns the modifiers of the class. + * + * @param modifiers The modifiers of the class. + */ + public void setModifiers(int modifiers) + { + this.modifiers = modifiers; + } + + /** + * Returns the modifiers of the class. + * + * @return The modifiers of the class. + */ + public int getModifiers() + { + return modifiers; + } + + /** + * Sets the superclassname. The given classname should have a canonical + * form (with dots). It is converted to the CM-similar notation + * (with slashes). + * + * @param classname The superclassname. + */ + public void setSuperClassName(String classname) + { + superClassName = NameHelper.fromCanonicalClassName(classname); + } + + /** + * Returns the superclassname. + * + * @return The superclassname. + */ + public String getSuperClassName() + { + return superClassName; + } + + /** + * Sets the oid classname. The given classname should have a canonical + * form (with dots). It is converted to the CM-similar notation + * (with slashes). + * + * @param classname The oid classname + */ + public void setOidClassName(String classname) + { + oidClassName = NameHelper.fromCanonicalClassName(classname); + } + + /** + * Returns the oid classname. + * + * @return The oid classname + */ + public String getOidClassName() + { + return oidClassName; + } + + /** + * Sets the persistence modifier of the class. + * + * @param persistent the persistence modifer + * @see #isPersistent + */ + public void setPersistent(boolean persistent) + { + this.isPersistent = persistent; + } + + /** + * Returns whether the class is persistent. + * + * @return true if persistent class. + * @see #isPersistent + */ + public boolean isPersistent() + { + return isPersistent; + } + + /** + * Returns whether the class is transient. + * + * @return true if transient class. + * @see #isPersistent + */ + public boolean isTransient() + { + return !isPersistent(); + } + + /** + * Returns whether the class is serializable. + * + * @return true if serializable class. + * @see #isSerializable + */ + public boolean isSerializable() + { + return isSerializable; + } + + /** + * Sets the serializable flag of the class. + * + * @param serializable the serializable flag + * @see #isSerializable + */ + public void setSerializable(boolean serializable) + { + this.isSerializable = serializable; + } + /** + * Adds a new field. + * + * @param field The new field. + */ + public void addField(JDOField field) + { + fields.add(field); + } + + /** + * Returns the field with the given name. + * + * @param name The name of the requested field. + * @return The field or <code>null</code> if not found. + */ + public JDOField getField(String name) + { + int idx = getIndexOfField(name); + return (idx > -1 ? (JDOField) fields.get(idx) : null); + } + + /** + * Returns the index of the field with the given name. + * + * @param name The name of the field. + * @return The index or <code>-1</code> if the field was not found. + */ + public int getIndexOfField(String name) + { + for (int i = 0; i < fields.size(); i++) { + JDOField field = (JDOField)fields.get(i); + if (field.getName().equals(name)) { + return i; + } + } + + return -1; + } + + /** + * Returns all fields of the class. + * + * @return The fields + */ + public List getFields() + { + return fields; + } + + /** + * Returns the names of all fields of the class. + * + * @return The field names + */ + public String[] getFieldNames() + { + if (fieldNames == null) { + final int n = fields.size(); + String[] fields = new String[n]; + for (int i = 0; i < n; i++) { + fields[i] = ((JDOField)this.fields.get(i)).getName(); + } + fieldNames = fields; + } + + return fieldNames; + } + + /** + * Sorts the fields of this class according to the names. This method + * should be called if all fields are added. It is necessary to + * establish an order on the fields. + * + */ + final void sortFields() + { + Collections.sort( + fields, + new Comparator() { + public int compare(Object f1, Object f2) + { + JDOField field1 = (JDOField)f1; + JDOField field2 = (JDOField)f2; + //if we dont have managed fields we dont care + if (!(field1.isManaged() && field2.isManaged())) + { + return (field1.isManaged() ? -1 : 1); + } + return field1.getName().compareTo(field2.getName()); + } + }); + } + + /** + * Returns the names of all managed fields this class. + * + * @return The persistent fieldnames. + */ + public String[] getManagedFieldNames() + { + if (managedFieldNames == null) { + final int n = fields.size(); + List tmp = new ArrayList(n); + for (int i = 0; i < n; i++) { + JDOField field = (JDOField)fields.get(i); + if (field.isManaged()) { + tmp.add(field.getName()); + } + } + managedFieldNames + = (String[])tmp.toArray(new String[tmp.size()]); + } + + return managedFieldNames; + } + + /** + * Creates a string-representation for this object. + * + * @return The string-representation of this object. + */ + public String toString() + { + return ('<' + MetaDataProperties.PROPERTY_SUPER_CLASSNAME + + ':' + superClassName + + MetaDataProperties.PROPERTY_OID_CLASSNAME + + ':' + oidClassName + + ',' + MetaDataProperties.PROPERTY_ACCESS_MODIFIER + + ':' + Modifier.toString(modifiers) + + ',' + MetaDataProperties.PROPERTY_JDO_MODIFIER + + ':' + isPersistent + + ',' + "fields:" + fields + '>'); + } +}