Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/ImplHelper.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/ImplHelper.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/ImplHelper.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/ImplHelper.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,950 @@ +/* + * 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.generator; + +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + + +/** + * + */ +final class ImplHelper + extends NameHelper +{ + // string constants + static final String[] COMMENT_ENHANCER_ADDED + = null; //{ "added by enhancer" }; + static final String[] COMMENT_NOT_ENHANCER_ADDED + = null; //{ "not added by enhancer" }; + + static final String CLASSNAME_JDO_PERSISTENCE_CAPABLE + = "javax.jdo.spi.PersistenceCapable"; + static final String CLASSNAME_JDO_PERSISTENCE_MANAGER + = "javax.jdo.PersistenceManager"; + static final String CLASSNAME_JDO_IMPL_HELPER + = "javax.jdo.spi.JDOImplHelper"; + static final String CLASSNAME_JDO_STATE_MANAGER + = "javax.jdo.spi.StateManager"; + static final String CLASSNAME_JDO_PERMISSION + = "javax.jdo.spi.JDOPermission"; + static final String CLASSNAME_JDO_USER_EXCEPTION + = "javax.jdo.JDOUserException"; + //static final String CLASSNAME_JDO_FATAL_INTERNAL_EXCEPTION + //= "javax.jdo.JDOFatalInternalException"; + static final String CLASSNAME_JDO_OBJECT_ID_FIELD_SUPPLIER + = CLASSNAME_JDO_PERSISTENCE_CAPABLE + "." + "ObjectIdFieldSupplier"; + static final String CLASSNAME_JDO_OBJECT_ID_FIELD_CONSUMER + = CLASSNAME_JDO_PERSISTENCE_CAPABLE + "." + "ObjectIdFieldConsumer"; + + static final String FIELDNAME_JDO_FLAGS + = "jdoFlags"; + static final String FIELDNAME_JDO_STATE_MANAGER + = "jdoStateManager"; + static final String FIELDNAME_JDO_INHERITED_FIELD_COUNT + = "jdoInheritedFieldCount"; + static final String FIELDNAME_JDO_FIELD_NAMES + = "jdoFieldNames"; + static final String FIELDNAME_JDO_FIELD_TYPES + = "jdoFieldTypes"; + static final String FIELDNAME_JDO_FIELD_FLAGS + = "jdoFieldFlags"; + static final String FIELDNAME_JDO_PC_SUPERCLASS + = "jdoPersistenceCapableSuperclass"; + static final String FIELDNAME_SERIAL_VERSION_UID + = "serialVersionUID"; + + static final String METHODNAME_WRITE_OBJECT + = "writeObject"; + + static final String METHODNAME_JDO_GET_MANAGED_FIELD_COUNT + = "jdoGetManagedFieldCount"; + static final String METHODNAME_JDO_NEW_INSTANCE + = "jdoNewInstance"; + static final String METHODNAME_JDO_NEW_OID_INSTANCE + = "jdoNewObjectIdInstance"; + static final String METHODNAME_JDO_REPLACE_STATE_MANAGER + = "jdoReplaceStateManager"; + static final String METHODNAME_JDO_REPLACE_FLAGS + = "jdoReplaceFlags"; + static final String METHODNAME_JDO_REPLACE_FIELD + = "jdoReplaceField"; + static final String METHODNAME_JDO_REPLACE_FIELDS + = "jdoReplaceFields"; + static final String METHODNAME_JDO_PROVIDE_FIELD + = "jdoProvideField"; + static final String METHODNAME_JDO_PROVIDE_FIELDS + = "jdoProvideFields"; + static final String METHODNAME_JDO_COPY_FIELDS + = "jdoCopyFields"; + static final String METHODNAME_JDO_COPY_FIELD + = "jdoCopyField"; + static final String METHODNAME_JDO_PRE_SERIALIZE + = "jdoPreSerialize"; + static final String METHODNAME_JDO_GET_PERSISTENCE_MANAGER + = "jdoGetPersistenceManager"; + static final String METHODNAME_JDO_MAKE_DIRTY + = "jdoMakeDirty"; + static final String METHODNAME_JDO_GET_OBJECT_ID + = "jdoGetObjectId"; + static final String METHODNAME_JDO_GET_TRANSACTIONAL_OBJECT_ID + = "jdoGetTransactionalObjectId"; + static final String METHODNAME_JDO_IS_PERSISTENT + = "jdoIsPersistent"; + static final String METHODNAME_JDO_IS_TRANSACTIONAL + = "jdoIsTransactional"; + static final String METHODNAME_JDO_IS_NEW + = "jdoIsNew"; + static final String METHODNAME_JDO_IS_DIRTY + = "jdoIsDirty"; + static final String METHODNAME_JDO_IS_DELETED + = "jdoIsDeleted"; + static final String METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID + = "jdoCopyKeyFieldsToObjectId"; + static final String METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID + = "jdoCopyKeyFieldsFromObjectId"; + + static private final HashMap typeNameConversion = new HashMap(); + static + { + typeNameConversion.put(int.class.getName(), "Int"); + typeNameConversion.put(long.class.getName(), "Long"); + typeNameConversion.put(byte.class.getName(), "Byte"); + typeNameConversion.put(char.class.getName(), "Char"); + typeNameConversion.put(boolean.class.getName(), "Boolean"); + typeNameConversion.put(short.class.getName(), "Short"); + typeNameConversion.put(float.class.getName(), "Float"); + typeNameConversion.put(double.class.getName(), "Double"); + typeNameConversion.put("String", "String"); + } + + static private String getConvertedTypeName(String fieldtype) + { + final String name = (String)typeNameConversion.get(fieldtype); + return (name != null ? name : "Object"); + } + + static private String getMethodNameGetField(String fieldtype) + { + return "get" + getConvertedTypeName(fieldtype) + "Field"; + } + + static private String getMethodNameSetField(String fieldtype) + { + return "set" + getConvertedTypeName(fieldtype) + "Field"; + } + + static private String getMethodNameReplacingField(String fieldtype) + { + return "replacing" + getConvertedTypeName(fieldtype) + "Field"; + } + + static private String getMethodNameProvidedField(String fieldtype) + { + return "provided" + getConvertedTypeName(fieldtype) + "Field"; + } + + static private String getMethodNameFetchField(String fieldtype) + { + return "fetch" + getConvertedTypeName(fieldtype) + "Field"; + } + + static private String getMethodNameStoreField(String fieldtype) + { + return "store" + getConvertedTypeName(fieldtype) + "Field"; + } + + // ---------------------------------------------------------------------- + + static String createJDOFieldAccessorName(String classname, + String fieldname) + { + return "jdoGet" + fieldname; + } + + static String createJDOFieldMutatorName(String classname, + String fieldname) + { + return "jdoSet" + fieldname; + } + + // Create initial values of fields. + + static String getJDOInheritedFieldCountInitValue(String superclassname) + { + return(superclassname == null ? + "0" : + (normalizeClassName(superclassname) + + '.' + METHODNAME_JDO_GET_MANAGED_FIELD_COUNT + "()")); + } + + static String getJDOFieldNamesInitValue(String[] fieldnames) + { + String value = "new String[]{ "; + final int n = fieldnames.length; + for (int i = 0; i < n; i++) { + value += "\"" + fieldnames[i] + "\""; + if (i < n - 1) { + value += ", "; + } + } + return value + " }"; + } + + static String getJDOFieldTypesInitValue(String[] fieldtypes) + { + String value = "new Class[]{ "; + final int n = fieldtypes.length; + for (int i = 0; i < n; i++) { + value += normalizeClassName(fieldtypes[i]) + ".class"; + if (i < n - 1) { + value += ", "; + } + } + return value + " }"; + } + + static String getJDOFieldFlagsInitValue(int[] fieldflags) + { + String value = "new byte[]{ "; + final int n = fieldflags.length; + for (int i = 0; i < n; i++) { + value += "0x" + Integer.toHexString(fieldflags[i]); + if (i < n - 1) { + value += ", "; + } + } + return value + " }"; + } + + static String getJDOPCSuperclassInitValue(String superclass) + { + return (superclass == null + ? "null" + : normalizeClassName(superclass) + ".class"); + } + + static String getSerialVersionUIDInitValue(long uid) + { + return uid + "L"; + } + + // Create bodies of methods. + + static List getJDOManagedFieldCountImpl(int fieldcount) + { + final List impl = new ArrayList(3); + impl.add(FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " + " + fieldcount + ';'); + return impl; + } + + static List getStaticInitializerImpl(String classname, + String superPC, + String[] managedFieldNames, + String[] managedFieldTypes, + int[] managedFieldFlags) + { + classname = normalizeClassName(classname); + final List impl = new ArrayList(20); + + impl.add(ImplHelper.FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " = "+ getJDOInheritedFieldCountInitValue(superPC) + ";"); + impl.add(ImplHelper.FIELDNAME_JDO_FIELD_NAMES + + " = " + getJDOFieldNamesInitValue(managedFieldNames) + ";"); + impl.add(ImplHelper.FIELDNAME_JDO_FIELD_TYPES + + " = " + getJDOFieldTypesInitValue(managedFieldTypes) + ";"); + impl.add(ImplHelper.FIELDNAME_JDO_FIELD_FLAGS + + " = " + getJDOFieldFlagsInitValue(managedFieldFlags) + ";"); + impl.add(ImplHelper.FIELDNAME_JDO_PC_SUPERCLASS + + " = " + getJDOPCSuperclassInitValue(superPC) + ";"); + + impl.add(CLASSNAME_JDO_IMPL_HELPER + + ".registerClass("); + impl.add(" " + classname + ".class" + ", "); + impl.add(" " + FIELDNAME_JDO_FIELD_NAMES + ", "); + impl.add(" " + FIELDNAME_JDO_FIELD_TYPES + ", "); + impl.add(" " + FIELDNAME_JDO_FIELD_FLAGS + ", "); + impl.add(" " + FIELDNAME_JDO_PC_SUPERCLASS + ", "); + impl.add(" " + "new " + classname + "()"); + impl.add(");"); + return impl; + } + + static List getJDOGetManagedFieldCountImpl(boolean isRoot, + String superPC, + int fieldcount) + { + superPC = normalizeClassName(superPC); + final List impl = new ArrayList(5); + if (isRoot) { + impl.add("return " + fieldcount + ';'); + } + else { + impl.add("return " + superPC + "." + + METHODNAME_JDO_GET_MANAGED_FIELD_COUNT + + "() + " + fieldcount + ';'); + } + return impl; + } + + static List getDefaultConstructorImpl() + { + final List impl = new ArrayList(5); + impl.add("super();"); + return impl; + } + + static List getDummyConstructorImpl() + { + final List impl = new ArrayList(5); + impl.add("super();"); + return impl; + } + + static List getOidStringArgConstructorImpl(String superoidclassname, + String str) + { + final List impl = new ArrayList(5); + if (superoidclassname != null) { + impl.add("super(" + str + ");"); + } + //^olsen: todo + impl.add("// not implemented yet"); + impl.add("throw new UnsupportedOperationException();"); + return impl; + } + + static List getCloneImpl(String classname) + { + classname = normalizeClassName(classname); + final List impl = new ArrayList(5); + impl.add("final " + classname + + " pc = (" + classname + ")super.clone();"); + impl.add("pc." + FIELDNAME_JDO_FLAGS + " = 0; // == READ_OK"); + impl.add("pc." + FIELDNAME_JDO_STATE_MANAGER + " = null;"); + impl.add("return pc;"); + return impl; + } + + static List getJDONewInstanceImpl(String classname, + String statemanager) + { + final List impl = new ArrayList(5); + classname = getClassName(classname); + impl.add("final " + classname + + " pc = new " + classname + "();"); + impl.add("pc." + FIELDNAME_JDO_FLAGS + " = 1; // == LOAD_REQUIRED"); + impl.add("pc." + FIELDNAME_JDO_STATE_MANAGER + + " = " + statemanager + ';'); + impl.add("return pc;"); + return impl; + } + + static List getJDONewInstanceKeyImpl(String classname, + String statemanager, + String oid) + { + final List impl = new ArrayList(5); + classname = getClassName(classname); + impl.add("final " + classname + + " pc = new " + classname + "();"); + impl.add("pc." + METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID + + "(" + oid + ");"); + impl.add("pc." + FIELDNAME_JDO_FLAGS + " = 1; // == LOAD_REQUIRED"); + impl.add("pc." + FIELDNAME_JDO_STATE_MANAGER + + " = " + statemanager + ';'); + impl.add("return pc;"); + return impl; + } + + static List getJDONewOidInstanceImpl(String oidclassname) + { + final List impl = new ArrayList(5); + if (oidclassname == null) { + impl.add("return null;"); + } else { + impl.add("return new " + oidclassname + "();"); + } + return impl; + } + + static List getJDONewOidInstanceImpl(String oidclassname, + String str) + { + final List impl = new ArrayList(5); + if (oidclassname == null) { + impl.add("return null;"); + } else { + impl.add("return new " + oidclassname + "(" + str + ");"); + } + return impl; + } + + static List getJDOCopyKeyFieldsToOid(String oidclassname, + String superoidclassname, + String oid, + String[] fieldnames) + { + final List impl = new ArrayList(5); + if (oidclassname == null) { + impl.add("return;"); + } else { + impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add("}"); + final String _oid = "_" + oid; + impl.add("final " + oidclassname + + " " + _oid + " = (" + oidclassname + ")" + oid + ";"); + if (superoidclassname != null) { + impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID + + "(" + _oid + ");"); + } + for (int i = 0; i < fieldnames.length; i++) { + final String fname = fieldnames[i]; + impl.add(_oid + "." + fname + " = " + "this." + fname + ";"); + } + } + return impl; + } + + static List getJDOCopyKeyFieldsFromOid(String oidclassname, + String superoidclassname, + String oid, + String[] fieldnames) + { + final List impl = new ArrayList(5); + if (oidclassname == null) { + impl.add("return;"); + } else { + impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add("}"); + final String _oid = "_" + oid; + impl.add("final " + oidclassname + + " " + _oid + " = (" + oidclassname + ")" + oid + ";"); + if (superoidclassname != null) { + impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID + + "(" + _oid + ");"); + } + for (int i = 0; i < fieldnames.length; i++) { + final String fname = fieldnames[i]; + impl.add("this." + fname + " = " + _oid + "." + fname + ";"); + } + } + return impl; + } + + static List getJDOCopyKeyFieldsToOid(String oidclassname, + String superoidclassname, + String fm, + String oid, + String[] fieldnames, + String[] fieldtypes, + int[] fieldnumbers) + { + final List impl = new ArrayList(5); + if (oidclassname == null) { + impl.add("return;"); + } else { + impl.add("if (" + fm + " == null) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add("}"); + impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {"); + impl.add(" throw new IllegalArgumentException(\"arg2\");"); + impl.add("}"); + final String _oid = "_" + oid; + impl.add("final " + oidclassname + + " " + _oid + " = (" + oidclassname + ")" + oid + ";"); + if (superoidclassname != null) { + impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID + + "(" + fm + ", " + _oid + ");"); + } + for (int i = 0; i < fieldnames.length; i++) { + impl.add(_oid + "." + fieldnames[i] + " = " + fm + "." + + getMethodNameFetchField(fieldtypes[i]) + + "(" + FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " + " + fieldnumbers[i] + ");"); + } + } + return impl; + } + + static List getJDOCopyKeyFieldsFromOid(String oidclassname, + String superoidclassname, + String fm, + String oid, + String[] fieldnames, + String[] fieldtypes, + int[] fieldnumbers) + { + final List impl = new ArrayList(5); + if (oidclassname == null) { + impl.add("return;"); + } else { + impl.add("if (" + fm + " == null) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add("}"); + impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {"); + impl.add(" throw new IllegalArgumentException(\"arg2\");"); + impl.add("}"); + final String _oid = "_" + oid; + impl.add("final " + oidclassname + + " " + _oid + " = (" + oidclassname + ")" + oid + ";"); + if (superoidclassname != null) { + impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID + + "(" + fm + ", " + _oid + ");"); + } + for (int i = 0; i < fieldnames.length; i++) { + impl.add(fm + "." + getMethodNameStoreField(fieldtypes[i]) + + "(" + FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " + " + fieldnumbers[i] + ", " + + _oid + "." + fieldnames[i] + ");"); + } + } + return impl; + } + + static List getJDOReplaceStateManagerImpl(String statemanager) + { + final List impl = new ArrayList(8); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + + " s = this." + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (s != null) {"); + impl.add(" this." + FIELDNAME_JDO_STATE_MANAGER + + " = s.replacingStateManager(this, " + statemanager + ");"); + impl.add(" return;"); + impl.add("}"); + impl.add(CLASSNAME_JDO_IMPL_HELPER + + ".checkAuthorizedStateManager(" + statemanager + ");"); + impl.add("this." + FIELDNAME_JDO_STATE_MANAGER + + " = " + statemanager + ';'); + impl.add("this." + FIELDNAME_JDO_FLAGS + + " = LOAD_REQUIRED;"); + return impl; + } + + static List getJDOReplaceFlagsImpl() + { + final List impl = new ArrayList(5); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (sm != null) {"); + impl.add(" this." + FIELDNAME_JDO_FLAGS + + " = sm.replacingFlags(this);"); + impl.add("}"); + return impl; + } + + static List getJDOFieldDirectReadImpl(String fieldname, + String fieldtype, + int fieldnumber, + String instancename) + { + fieldtype = normalizeClassName(fieldtype); + final List impl = new ArrayList(20); + impl.add("// augmentation: grant direct read access"); + impl.add("return " + instancename + '.' + fieldname + ';'); + return impl; + } + + static private void addFieldMediateReadImpl(List impl, + String fieldname, + String fieldtype, + int fieldnumber, + String instancename) + { + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = " + + instancename + '.' + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (sm == null) {"); + impl.add(" return " + instancename + '.' + fieldname + ';'); + impl.add("}"); + impl.add("if (sm.isLoaded(" + instancename + ", " + + FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " + " + fieldnumber + ")) {"); + impl.add(" return " + instancename + '.' + fieldname + ';'); + impl.add("}"); + impl.add("return (" + fieldtype + ")" + + "sm." + getMethodNameGetField(fieldtype) + + "(" + instancename + ", " + + FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " + " + fieldnumber + ", " + + instancename + '.' + fieldname + ");"); + } + + static List getJDOFieldMediateReadImpl(String fieldname, + String fieldtype, + int fieldnumber, + String instancename) + { + fieldtype = normalizeClassName(fieldtype); + final List impl = new ArrayList(20); + impl.add("// augmentation: mediate read access"); + addFieldMediateReadImpl(impl, fieldname, fieldtype, + fieldnumber, instancename); + return impl; + } + + static List getJDOFieldCheckReadImpl(String fieldname, + String fieldtype, + int fieldnumber, + String instancename) + { + fieldtype = normalizeClassName(fieldtype); + final List impl = new ArrayList(20); + impl.add("// augmentation: check read access"); + impl.add("if (" + instancename + '.' + FIELDNAME_JDO_FLAGS + + " <= 0) {"); + impl.add(" return " + instancename + '.' + fieldname + ';'); + impl.add("}"); + addFieldMediateReadImpl(impl, fieldname, fieldtype, + fieldnumber, instancename); + return impl; + } + + static List getJDOFieldDirectWriteImpl(String fieldname, + String fieldtype, + int fieldnumber, + String instancename, + String newvalue) + { + fieldtype = normalizeClassName(fieldtype); + final List impl = new ArrayList(20); + impl.add("// augmentation: grant direct write access"); + impl.add(instancename + '.' + fieldname + + " = " + newvalue + ';'); + return impl; + } + + static private void addFieldMediateWriteImpl(List impl, + String fieldname, + String fieldtype, + int fieldnumber, + String instancename, + String newvalue) + { + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = " + + instancename + '.' + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (sm == null) {"); + impl.add(" " + instancename + '.' + fieldname + + " = " + newvalue + ';'); + impl.add(" return;"); + impl.add("}"); + impl.add("sm." + + getMethodNameSetField(fieldtype) + + "(" + instancename + ", " + + FIELDNAME_JDO_INHERITED_FIELD_COUNT + + " + " + fieldnumber + ", " + + instancename + + '.' + fieldname + ", " + + newvalue + ");"); + } + + static List getJDOFieldMediateWriteImpl(String fieldname, + String fieldtype, + int fieldnumber, + String instancename, + String newvalue) + { + fieldtype = normalizeClassName(fieldtype); + final List impl = new ArrayList(20); + impl.add("// augmentation: mediate write access"); + addFieldMediateWriteImpl(impl, fieldname, fieldtype, + fieldnumber, instancename, newvalue); + return impl; + } + + static List getJDOFieldCheckWriteImpl(String fieldname, + String fieldtype, + int fieldnumber, + String instancename, + String newvalue) + { + fieldtype = normalizeClassName(fieldtype); + final List impl = new ArrayList(20); + impl.add("// augmentation: check write access"); + impl.add("if (" + instancename + + '.' + FIELDNAME_JDO_FLAGS + " == 0) {"); + impl.add(" " + instancename + '.' + fieldname + + " = " + newvalue + ';'); + impl.add(" return;"); + impl.add("}"); + addFieldMediateWriteImpl(impl, fieldname, fieldtype, + fieldnumber, instancename, newvalue); + return impl; + } + + static List getJDOReplaceFieldImpl(String fieldnumber, + boolean isRoot, + String[] fieldnames, + String[] fieldtypes) + { + final List impl = new ArrayList(20); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = this." + + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("switch (" + fieldnumber + + " - " + FIELDNAME_JDO_INHERITED_FIELD_COUNT + ") {"); + for (int i = 0; i < fieldnames.length; i++) { + String fieldtype = normalizeClassName(fieldtypes[i]); + impl.add("case " + i + ':'); + impl.add(" if (sm == null) {"); + impl.add(" throw new IllegalStateException(\"arg0." + + FIELDNAME_JDO_STATE_MANAGER + "\");"); + impl.add(" }"); + impl.add(" this." + fieldnames[i] + + " = (" + fieldtype + ")sm." + + getMethodNameReplacingField(fieldtype) + + "(this, " + fieldnumber + ");"); + impl.add(" return;"); + } + impl.add("default:"); + if (isRoot) { + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + } else { + impl.add(" super." + METHODNAME_JDO_REPLACE_FIELD + + "(" + fieldnumber + ");"); + } + impl.add("}"); + return impl; + } + + static List getJDOProvideFieldImpl(String fieldnumber, + boolean isRoot, + String[] fieldnames, + String[] fieldtypes) + { + final List impl = new ArrayList(20); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = this." + + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("switch (" + fieldnumber + + " - " + FIELDNAME_JDO_INHERITED_FIELD_COUNT + ") {"); + for (int i = 0; i < fieldnames.length; i++) { + String fieldtype = normalizeClassName(fieldtypes[i]); + impl.add("case " + i + ':'); + impl.add(" if (sm == null) {"); + impl.add(" throw new IllegalStateException(\"arg0." + + FIELDNAME_JDO_STATE_MANAGER + "\");"); + impl.add(" }"); + impl.add(" sm." + getMethodNameProvidedField(fieldtype) + + "(this, " + fieldnumber + ", " + + "this." + fieldnames[i] + ");"); + impl.add(" return;"); + } + impl.add("default:"); + if (isRoot) { + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + } else { + impl.add(" super." + METHODNAME_JDO_PROVIDE_FIELD + + "(" + fieldnumber + ");"); + } + impl.add("}"); + return impl; + } + + static List getJDOCopyFieldsImpl(String classname, + String copy, + String fieldnumbers) + { + classname = normalizeClassName(classname); + final List impl = new ArrayList(50); + impl.add("if (this." + FIELDNAME_JDO_STATE_MANAGER + " == null) {"); + impl.add(" throw new IllegalStateException(\"arg0." + + FIELDNAME_JDO_STATE_MANAGER + "\");"); + impl.add("}"); + impl.add("if (!(" + copy + " instanceof " + classname + ")) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add("}"); + impl.add("if (" + fieldnumbers + " == null) {"); + impl.add(" throw new IllegalArgumentException(\"arg2\");"); + impl.add("}"); + impl.add("final " + classname + + " other = (" + classname + ")" + copy + ';'); + impl.add("if (other." + FIELDNAME_JDO_STATE_MANAGER + + " != this." + FIELDNAME_JDO_STATE_MANAGER + ") {"); + impl.add(" throw new IllegalArgumentException(\"" + + "arg1." + FIELDNAME_JDO_STATE_MANAGER + "\");"); + impl.add("}"); + impl.add("final int n = " + fieldnumbers + ".length;"); + impl.add("for (int i = 0; i < n; i++) {"); + impl.add(" this." + METHODNAME_JDO_COPY_FIELD + + "(other, " + fieldnumbers + "[i]);"); + impl.add("}"); + return impl; + } + + static List getJDOCopyFieldImpl(String classname, + String copy, + String fieldnumber, + String[] fieldnames, + boolean isRoot) + { + classname = normalizeClassName(classname); + final List impl = new ArrayList(50); + impl.add("switch (" + fieldnumber + + " - " + FIELDNAME_JDO_INHERITED_FIELD_COUNT + ") {"); + for (int i = 0; i < fieldnames.length; i++) { + impl.add("case " + i + ':'); + impl.add(" if (" + copy + " == null) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add(" }"); + impl.add(" this." + fieldnames[i] + + " = " + copy + "." + fieldnames[i] + ';'); + impl.add(" return;"); + } + impl.add("default:"); + if (isRoot) { + impl.add(" throw new IllegalArgumentException(\"arg2\");"); + } else { + impl.add(" super." + METHODNAME_JDO_COPY_FIELD + + "(" + copy + ", " + fieldnumber + ");"); + } + impl.add("}"); + return impl; + } + + static List getWriteObjectImpl(String out) + { + final List impl = new ArrayList(5); + impl.add(METHODNAME_JDO_PRE_SERIALIZE + "();"); + impl.add(out + ".defaultWriteObject();"); + + return impl; + } + + static List getJDOStateManagerVoidDelegationImpl(String delegation) + { + final List impl = new ArrayList(5); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (sm != null) {"); + impl.add(" sm." + delegation + ';'); + impl.add("}"); + return impl; + + } + + static List getJDOStateManagerObjectDelegationImpl(String delegation) + { + final List impl = new ArrayList(5); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (sm != null) {"); + impl.add(" return sm." + delegation + ';'); + impl.add("}"); + impl.add("return null;"); + return impl; + } + + static List getJDOStateManagerBooleanDelegationImpl(String delegation) + { + final List impl = new ArrayList(5); + impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";"); + impl.add("if (sm != null) {"); + impl.add(" return sm." + delegation + ';'); + impl.add("}"); + impl.add("return false;"); + return impl; + } + + static List getJDOFieldIterationImpl(String fieldnumbers, + String method) + { + final List impl = new ArrayList(10); + impl.add("if (" + fieldnumbers + " == null) {"); + impl.add(" throw new IllegalArgumentException(\"arg1\");"); + impl.add("}"); + impl.add("final int n = " + fieldnumbers + ".length;"); + impl.add("for (int i = 0; i < n; i++) {"); + impl.add(" this." + method + "(" + fieldnumbers + "[i]);"); + impl.add("}"); + return impl; + } + + static List getOidHashCodeImpl(String[] pknames, + String[] pktypes, + boolean isRoot) + { + final List impl = new ArrayList(3); + if (isRoot) { + impl.add("int hash = 0;"); + } else { + impl.add("int hash = super.hashCode();"); + } + for (int i = 0; i < pknames.length; i++) { + if (isPrimitiveClass(pktypes[i])) { + if (pktypes[i].equals("boolean")) { + impl.add("hash += (" + pknames[i] + " ? 1 : 0);"); + } else { + impl.add("hash += (int)" + pknames[i] + ';'); + } + } else { + impl.add("hash += (this." + pknames[i] + + " != null ? this." + pknames[i] + + ".hashCode() : 0);"); + } + } + impl.add("return hash;"); + return impl; + } + + static List getOidEqualsImpl(String oidclassname, + String[] pknames, + String[] pktypes, + String pk, + boolean isRoot) + { + final List impl = new ArrayList(3); + if (isRoot) { + impl.add("if (" + pk + " == null || !this.getClass().equals(" + + pk + ".getClass())) {"); + } else { + impl.add("if (!super.equals(" + pk + ")) {"); + } + impl.add(" return false;"); + impl.add("}"); + oidclassname = getClassName(oidclassname); + impl.add(oidclassname + " oid = (" + oidclassname + ")" + pk + ';'); + for (int i = 0; i < pknames.length; i++) { + if (isPrimitiveClass(pktypes[i])) { + impl.add("if (this." + pknames[i] + " != oid." + + pknames[i] + ") return false;"); + } else { + impl.add("if (this." + pknames[i] + " != oid." + + pknames[i] + " && (this." + pknames[i] + + " == null || " + "!this." + pknames[i] + + ".equals(oid." + pknames[i] + + "))) return false;"); + } + } + impl.add("return true;"); + return impl; + } + + static private boolean isPrimitiveClass(String classname) + { + return (classname.equals("int") + || classname.equals("long") + || classname.equals("short") + || classname.equals("byte") + || classname.equals("boolean") + || classname.equals("char") + || classname.equals("double") + || classname.equals("float")); + } +}
Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/Main.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/Main.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/Main.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/Main.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,1138 @@ +/* + * 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.generator; + +import java.lang.reflect.Modifier; + +import java.util.Iterator; +import java.util.Collection; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Properties; + +import java.io.Serializable; +import java.io.File; +import java.io.Writer; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.BufferedWriter; +import java.io.InputStream; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.io.FileNotFoundException; + +import org.apache.jdo.impl.enhancer.meta.ExtendedMetaData; +import org.apache.jdo.impl.enhancer.meta.prop.EnhancerMetaDataPropertyImpl; +import org.apache.jdo.impl.enhancer.util.Support; + + + + +/** + * + */ +public final class Main + extends Support +{ + /** + * The stream to write messages to. + */ + private final PrintWriter out = new PrintWriter(System.out, true); + + /** + * The stream to write error messages to. + */ + private final PrintWriter err = new PrintWriter(System.err, true); + + /** + * The command line options. + */ + private final CmdLineOptions opts = new CmdLineOptions(); + + /** + * + */ + private final CodeWriter writer = new CodeWriter(); + + /** + * The MetaData for generating classes. + */ + private ExtendedMetaData meta = null; + + /** + * + */ + public Main() + {} + + /** + * + */ + public static final void main(String[] argv) + { + final Main gen = new Main(); + try { + gen.opts.processArgs(argv); + gen.init(); + gen.generate(); + } catch(Exception ex) { + gen.printError(null, ex); + } + } + + /** + * A class for holding the command line options. + */ + private class CmdLineOptions + { + // final Collection inputFileNames = new ArrayList(); + String destinationDirectory = null; + String jdoXMLModelFileName = null; + String jdoPropertiesFileName = null; + boolean verbose = false; + boolean quiet = false; + boolean forceWrite = false; + boolean noWrite = false; + + /** + * Print a usage message to System.err + */ + public void usage() { + err.println("Usage: Main <options> <arguments>..."); + err.println("Options:"); + err.println(" -v, --verbose print verbose output"); +/* + err.println(" -q, --quiet supress warnings"); + err.println(" -n, --nowrite never write classfiles"); + err.println(" -f, --force ever write classfiles"); +*/ + err.println(" -d, --dest <dir> destination directory for output files"); + err.println(" -p, --properties <file> use property file for meta data"); +/* + err.println(" -x, --xmlmodel <file> use JDO XML model file for meta data"); +*/ + err.println(); + err.println("Arguments:"); + err.println(); + err.println("Returns a non-zero value in case of errors."); + System.exit(1); + } + + /** + * Process command line options + */ + protected int processArgs(String[] argv) + { + for (int i = 0; i < argv.length; i++) { + final String arg = argv[i]; + if (arg.equals("-v") + || arg.equals("--verbose")) { + verbose = true; + quiet = false; + continue; + } +/* + if (arg.equals("-q") + || arg.equals("--quiet")) { + quiet = true; + verbose = false; + continue; + } + if (arg.equals("-f") + || arg.equals("--force")) { + forceWrite = true; + continue; + } + if (arg.equals("-n") + || arg.equals("--nowrite")) { + noWrite = true; + continue; + } +*/ + if (arg.equals("-d") + || arg.equals("--dest")) { + if (argv.length - i < 2) { + printError("Missing argument to the -d/-dest option", null); + usage(); + } + destinationDirectory = argv[++i]; + continue; + } + if (arg.equals("-p") || + arg.equals("--properties")) { + if (argv.length - i < 2) { + printError("Missing argument to the -p/--properties option", null); + usage(); + } + jdoPropertiesFileName = argv[++i]; + continue; + } +/* + if (arg.equals("-x") || + arg.equals("--xmlmodel")) { + if (argv.length - i < 2) { + printError("Missing argument to the -p/--properties option", null); + usage(); + } + jdoXMLModelFileName = argv[++i]; + continue; + } +*/ + if (arg.length() > 0 && arg.charAt(0) == '-') { + printError("Unrecognized option:" + arg, null); + usage(); + } + if (arg.length() == 0) { + printMessage("Ignoring empty command line argument."); + continue; + } + + //inputFileNames.add(arg); + } + + // The user must specify a destination directory + if (jdoPropertiesFileName == null) { + printError("No destination directory specified", null); + usage(); + } + + // The user must specify a destination directory + if (destinationDirectory == null) { + printError("No destination directory specified", null); + usage(); + } + + return 0; + } + } + + private void init() + throws FileNotFoundException, IOException + { + // load the properties + affirm(opts.jdoPropertiesFileName != null); + meta = new EnhancerMetaDataPropertyImpl(out, opts.verbose, + opts.jdoPropertiesFileName); + + // create the destination directory + affirm(opts.destinationDirectory != null); + final File destinationDir = new File(opts.destinationDirectory); + boolean res = destinationDir.mkdirs(); + if (!res) { + throw new IOException("unable to create destination directory: " + + "'" + destinationDir + "'"); + } + } + + private void generate() + { + final String[] classes = meta.getKnownClasses(); + for (int i = 0; i < classes.length; i++) { + final String classname = classes[i]; + try { + if (classname.indexOf('$') != -1) { + printMessage("Skipping generation of nested class " + classname + "." + + " Note, a nested ObjectId class is generated with its pc class."); + continue; + } + final Writer writer = createFileWriter(classname); + this.writer.setWriter(writer); + generateClass(classname); + writer.close(); + } catch(IOException ex) { + printError("Error generating class '" + classname + "'.", ex); + } + } + } + + private void generateClass(final String classname) + throws IOException + { + affirm(classname); + + final String normClassName = NameHelper.normalizeClassName(classname); + printMessage("generating '" + normClassName + "'..."); + + final String packageName = NameHelper.getPackageName(classname); + writer.writePackage( + packageName, + null); + + writer.writeImports( + null, + null); + + // write the class header and key class + final String oidClassName = meta.getKeyClass(classname); + if (oidClassName == null) { + writeClassHeader(classname); + } else { + final String oidPackageName + = NameHelper.getPackageName(oidClassName); + affirm(packageName.equals(oidPackageName), + "PC class and key class must be in same package."); + + final boolean enclosedOid + = oidClassName.startsWith(classname + "$"); + if (enclosedOid) { + writeClassHeader(classname); + writeOidClass(classname, oidClassName, enclosedOid); + } else { + writeOidClass(classname, oidClassName, enclosedOid); + writeClassHeader(classname); + } + } + + writeClassMembers(classname); + + // write the augmentation + final boolean isPC = meta.isPersistenceCapableClass(classname); + if (isPC) { + final boolean isPCRoot + = meta.isPersistenceCapableRootClass(classname); + if (isPCRoot) { + writePCRootMembers(classname); + } + writePCMembers(classname); + + writeClassMemberAccessors(classname); + } + + writer.writeClassEnd(); + } + + private Writer createFileWriter(String classname) + throws IOException + { + final File file = new File(opts.destinationDirectory, + classname + ".java"); + file.getAbsoluteFile().getParentFile().mkdirs(); + return new BufferedWriter(new FileWriter(file)); + } + + private void writeClassHeader(final String classname) + throws IOException + { + final boolean isPCRoot = meta.isPersistenceCapableRootClass(classname); + final String superclass = meta.getSuperClass(classname); + + String[] interfaces = null; + String[] comments = null; + interfaces + = new String[]{ ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE }; + writer.writeClassHeader(meta.getClassModifiers(classname), + ImplHelper.getClassName(classname), + superclass, + interfaces, + comments); + } + + private void writeClassMembers(final String classname) + throws IOException + { + writer.writeComments(1, new String[]{ + "----------------------------------------------------------------------", + "Class Members:", + "----------------------------------------------------------------------" + }); + writer.writeln(); + + // write default constructor + writer.writeConstructor( + ImplHelper.getClassName(classname), + Modifier.PUBLIC, + null, null, null, + ImplHelper.getDefaultConstructorImpl(), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + // write default constructor + writer.writeConstructor( + ImplHelper.getClassName(classname), + Modifier.PUBLIC, + new String[]{ "str" }, + new String[]{ "String" }, + null, + ImplHelper.getDummyConstructorImpl(), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + final String[] fieldnames = meta.getKnownFields(classname); + final int n = (fieldnames != null ? fieldnames.length : 0); + + // write the fields and with their bean getters/setters + for (int i = 0; i < n; i++) { + final String fieldname = (String)fieldnames[i]; + writeFieldMember(classname, fieldname); + } + } + + private void writeFieldMember(final String classname, + final String fieldname) + throws IOException + { + final String fieldtype = meta.getFieldType(classname, fieldname); + final int access = meta.getFieldModifiers(classname, fieldname); + final String normClassName = NameHelper.normalizeClassName(classname); + final List impl = new ArrayList(); + + // the field + writer.writeField( + fieldname, + access, + fieldtype, + null, null); + + // do not write bean getters and setters for static fields + if ((access & Modifier.STATIC) != 0) { + return; + } + + // write bean getter (calling accessor) + impl.clear(); + impl.add("//return this." + fieldname + ';'); + final String accessor + = ImplHelper.createJDOFieldAccessorName(classname, fieldname); + impl.add("return " + normClassName + "." + accessor + "(this);"); + writer.writeMethod( + createMethodName("get", fieldname), + Modifier.PUBLIC, + fieldtype, + null, + null, + null, + impl, + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + // write bean setter (calling mutator) + impl.clear(); + impl.add("//this." + fieldname + " = " + fieldname + ';'); + final String mutator + = ImplHelper.createJDOFieldMutatorName(classname, fieldname); + impl.add(normClassName + "." + mutator + "(this, " + fieldname + ");"); + writer.writeMethod( + createMethodName("set", fieldname), + Modifier.PUBLIC, + "void", + new String[]{ fieldname }, + new String[]{ fieldtype }, + null, + impl, + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + } + + private void writeClassMemberAccessors(final String classname) + throws IOException + { + writer.writeComments(1, new String[]{ + "----------------------------------------------------------------------", + "Augmentation for Field Accessors and Mutators (added by enhancer):", + "----------------------------------------------------------------------" + }); + writer.writeln(); + + // write the fields and their access methods + final String[] fields = meta.getManagedFields(classname); + final int n = (fields != null ? fields.length : 0); + for (int i = 0; i < n; i++) { + final String fieldname = (String)fields[i]; + writeFieldAccessors(classname, fieldname); + } + } + + private void writeFieldAccessors(final String classname, + final String fieldname) + throws IOException + { + final String fieldtype + = meta.getFieldType(classname, fieldname); + final int fieldnumber + = meta.getFieldNumber(classname, fieldname); + final boolean dfg + = meta.isDefaultFetchGroupField(classname, fieldname); + final int access + = meta.getFieldModifiers(classname, fieldname); + final int flags + = meta.getFieldFlags(classname, fieldname); + + final String accessor + = ImplHelper.createJDOFieldAccessorName(classname, fieldname); + final String mutator + = ImplHelper.createJDOFieldMutatorName(classname, fieldname); + + final String instancename + = "instance"; + + // jdo accessor + { + affirm(((flags & meta.CHECK_READ) == 0) + | (flags & meta.MEDIATE_READ) == 0); + final List impl; + if ((flags & meta.CHECK_READ) != 0) { + impl = ImplHelper.getJDOFieldCheckReadImpl(fieldname, + fieldtype, + fieldnumber, + instancename); + } else if ((flags & meta.MEDIATE_READ) != 0) { + impl = ImplHelper.getJDOFieldMediateReadImpl(fieldname, + fieldtype, + fieldnumber, + instancename); + } else { + impl = ImplHelper.getJDOFieldDirectReadImpl(fieldname, + fieldtype, + fieldnumber, + instancename); + } + writer.writeMethod( + accessor, + access | Modifier.STATIC | Modifier.FINAL, + fieldtype, + new String[]{ instancename }, + new String[]{ classname }, + null, + impl, + ImplHelper.COMMENT_ENHANCER_ADDED); + } + + // jdo mutator + { + affirm(((flags & meta.CHECK_WRITE) == 0) + | (flags & meta.MEDIATE_WRITE) == 0); + final List impl; + if ((flags & meta.CHECK_WRITE) != 0) { + impl = ImplHelper.getJDOFieldCheckWriteImpl(fieldname, + fieldtype, + fieldnumber, + instancename, + fieldname); + } else if ((flags & meta.MEDIATE_WRITE) != 0) { + impl = ImplHelper.getJDOFieldMediateWriteImpl(fieldname, + fieldtype, + fieldnumber, + instancename, + fieldname); + } else { + impl = ImplHelper.getJDOFieldDirectWriteImpl(fieldname, + fieldtype, + fieldnumber, + instancename, + fieldname); + } + writer.writeMethod( + mutator, + access | Modifier.STATIC | Modifier.FINAL, + "void", + new String[]{ instancename, fieldname }, + new String[]{ classname, fieldtype }, + null, + impl, + ImplHelper.COMMENT_ENHANCER_ADDED); + } + } + + private void writePCRootMembers(final String classname) + throws IOException + { + writer.writeComments(1, new String[]{ + "----------------------------------------------------------------------", + "Augmentation for Persistence-Capable Root Classes (added by enhancer):", + "----------------------------------------------------------------------" + }); + writer.writeln(); + + // jdoStateManager + writer.writeField( + ImplHelper.FIELDNAME_JDO_STATE_MANAGER, + Modifier.PROTECTED | Modifier.TRANSIENT, + ImplHelper.CLASSNAME_JDO_STATE_MANAGER, + "null", + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoFlags + writer.writeField( + ImplHelper.FIELDNAME_JDO_FLAGS, + Modifier.PROTECTED | Modifier.TRANSIENT, + "byte", + "0", // (ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE + // + "." + "READ_WRITE_OK"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoReplaceStateManager + writer.writeMethod( + ImplHelper.METHODNAME_JDO_REPLACE_STATE_MANAGER, + Modifier.PUBLIC | Modifier.FINAL | Modifier.SYNCHRONIZED, + "void", + new String[]{ "sm" }, + new String[]{ ImplHelper.CLASSNAME_JDO_STATE_MANAGER }, + null, + ImplHelper.getJDOReplaceStateManagerImpl("sm"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoReplaceFlags + writer.writeMethod( + ImplHelper.METHODNAME_JDO_REPLACE_FLAGS, + Modifier.PUBLIC | Modifier.FINAL, + "void", null, null, null, + ImplHelper.getJDOReplaceFlagsImpl(), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // getPersistenceManager + writer.writeMethod( + ImplHelper.METHODNAME_JDO_GET_PERSISTENCE_MANAGER, + Modifier.PUBLIC | Modifier.FINAL, + ImplHelper.CLASSNAME_JDO_PERSISTENCE_MANAGER, null, null, null, + ImplHelper.getJDOStateManagerObjectDelegationImpl("getPersistenceManager(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // getObjectId + writer.writeMethod( + ImplHelper.METHODNAME_JDO_GET_OBJECT_ID, + Modifier.PUBLIC | Modifier.FINAL, + Object.class.getName(), null, null, null, + ImplHelper.getJDOStateManagerObjectDelegationImpl("getObjectId(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_GET_TRANSACTIONAL_OBJECT_ID, + Modifier.PUBLIC | Modifier.FINAL, + Object.class.getName(), null, null, null, + ImplHelper.getJDOStateManagerObjectDelegationImpl("getTransactionalObjectId(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // is-methods + writer.writeMethod( + ImplHelper.METHODNAME_JDO_IS_PERSISTENT, + Modifier.PUBLIC | Modifier.FINAL, + "boolean", null, null, null, + ImplHelper.getJDOStateManagerBooleanDelegationImpl("isPersistent(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_IS_TRANSACTIONAL, + Modifier.PUBLIC | Modifier.FINAL, + "boolean", null, null, null, + ImplHelper.getJDOStateManagerBooleanDelegationImpl("isTransactional(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_IS_NEW, + Modifier.PUBLIC | Modifier.FINAL, + "boolean", null, null, null, + ImplHelper.getJDOStateManagerBooleanDelegationImpl("isNew(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_IS_DELETED, + Modifier.PUBLIC | Modifier.FINAL, + "boolean", null, null, null, + ImplHelper.getJDOStateManagerBooleanDelegationImpl("isDeleted(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_IS_DIRTY, + Modifier.PUBLIC | Modifier.FINAL, + "boolean", null, null, null, + ImplHelper.getJDOStateManagerBooleanDelegationImpl("isDirty(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // makeDirty + writer.writeMethod( + ImplHelper.METHODNAME_JDO_MAKE_DIRTY, + Modifier.PUBLIC | Modifier.FINAL, + "void", + new String[]{ "fieldname" }, + new String[]{ String.class.getName() }, + null, + ImplHelper.getJDOStateManagerVoidDelegationImpl("makeDirty(this, fieldname)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // replaceFields + writer.writeMethod( + ImplHelper.METHODNAME_JDO_REPLACE_FIELDS, + Modifier.PUBLIC | Modifier.FINAL, + "void", + new String[]{ "fieldnumbers" }, + new String[]{ "int[]" }, + null, + ImplHelper.getJDOFieldIterationImpl("fieldnumbers", + ImplHelper.METHODNAME_JDO_REPLACE_FIELD), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // provideFields + writer.writeMethod( + ImplHelper.METHODNAME_JDO_PROVIDE_FIELDS, + Modifier.PUBLIC | Modifier.FINAL, + "void", + new String[]{ "fieldnumbers" }, + new String[]{ "int[]" }, + null, + ImplHelper.getJDOFieldIterationImpl("fieldnumbers", + ImplHelper.METHODNAME_JDO_PROVIDE_FIELD), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // preSerialize + writer.writeMethod( + ImplHelper.METHODNAME_JDO_PRE_SERIALIZE, + Modifier.PROTECTED | Modifier.FINAL, + "void", null, null, null, + ImplHelper.getJDOStateManagerVoidDelegationImpl("preSerialize(this)"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // write method clone() + writer.writeMethod( + "clone", + Modifier.PUBLIC, + "Object", + null, + null, + new String[]{ "java.lang.CloneNotSupportedException" }, + ImplHelper.getCloneImpl(classname), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + } + + private void writePCMembers(final String classname) + throws IOException + { + writer.writeComments(1, new String[]{ + "----------------------------------------------------------------------", + "Augmentation for Persistence-Capable Classes (added by enhancer):", + "----------------------------------------------------------------------" + }); + writer.writeln(); + + final String[] managedFieldNames + = meta.getManagedFields(classname); + final String[] managedFieldTypes + = meta.getFieldType(classname, managedFieldNames); + final boolean isPCRoot + = meta.isPersistenceCapableRootClass(classname); + + writePCStaticMembers(classname); + + // jdoNewInstance + writer.writeMethod( + ImplHelper.METHODNAME_JDO_NEW_INSTANCE, + Modifier.PUBLIC, + ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE, + new String[]{ "sm" }, + new String[]{ ImplHelper.CLASSNAME_JDO_STATE_MANAGER }, + null, + ImplHelper.getJDONewInstanceImpl(classname, + "sm"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoNewInstance + writer.writeMethod( + ImplHelper.METHODNAME_JDO_NEW_INSTANCE, + Modifier.PUBLIC, + ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE, + new String[]{ "sm", "oid" }, + new String[]{ ImplHelper.CLASSNAME_JDO_STATE_MANAGER, "Object" }, + null, + ImplHelper.getJDONewInstanceKeyImpl(classname, + //oidClassName, + "sm", + "oid"), + //keyFieldNames), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoReplaceField + writer.writeMethod( + ImplHelper.METHODNAME_JDO_REPLACE_FIELD, + Modifier.PUBLIC, + "void", + new String[]{ "fieldnumber" }, + new String[]{ "int" }, + null, + ImplHelper.getJDOReplaceFieldImpl("fieldnumber", + isPCRoot, + managedFieldNames, + managedFieldTypes), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoProvideField(s) + writer.writeMethod( + ImplHelper.METHODNAME_JDO_PROVIDE_FIELD, + Modifier.PUBLIC, + "void", + new String[]{ "fieldnumber" }, + new String[]{ "int" }, + null, + ImplHelper.getJDOProvideFieldImpl("fieldnumber", + isPCRoot, + managedFieldNames, + managedFieldTypes), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoCopyFields + writer.writeMethod( + ImplHelper.METHODNAME_JDO_COPY_FIELDS, + Modifier.PUBLIC, + "void", + new String[]{ "pc", "fieldnumbers" }, + new String[]{ Object.class.getName(), "int[]" }, + null, + ImplHelper.getJDOCopyFieldsImpl(classname, + "pc", + "fieldnumbers"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoCopyField + writer.writeMethod( + ImplHelper.METHODNAME_JDO_COPY_FIELD, + Modifier.PROTECTED | Modifier.FINAL, + "void", + new String[]{ "pc", "fieldnumber" }, + new String[]{ classname, "int" }, + null, + ImplHelper.getJDOCopyFieldImpl(classname, + "pc", + "fieldnumber", + managedFieldNames, + isPCRoot), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writePCKeyHandlingMembers(classname); + + writePCSerializationMembers(classname); + } + + private void writePCStaticMembers(final String classname) + throws IOException + { + final String[] managedFieldNames + = meta.getManagedFields(classname); + final String superPC + = meta.getPersistenceCapableSuperClass(classname); + final String[] managedFieldTypes + = meta.getFieldType(classname, managedFieldNames); + final int[] managedFieldFlags + = meta.getFieldFlags(classname, managedFieldNames); + final boolean isPCRoot + = meta.isPersistenceCapableRootClass(classname); + + // inheritedFieldCount + writer.writeField( + ImplHelper.FIELDNAME_JDO_INHERITED_FIELD_COUNT, + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + "int", + null, + ImplHelper.COMMENT_ENHANCER_ADDED); + + // fieldNames + writer.writeField( + ImplHelper.FIELDNAME_JDO_FIELD_NAMES, + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + "String[]", + null, + ImplHelper.COMMENT_ENHANCER_ADDED); + + // fieldTypes + writer.writeField( + ImplHelper.FIELDNAME_JDO_FIELD_TYPES, + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + "Class[]", + null, + ImplHelper.COMMENT_ENHANCER_ADDED); + + // fieldFlags + writer.writeField( + ImplHelper.FIELDNAME_JDO_FIELD_FLAGS, + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + "byte[]", + null, + ImplHelper.COMMENT_ENHANCER_ADDED); + + // PC superclass + writer.writeField( + ImplHelper.FIELDNAME_JDO_PC_SUPERCLASS, + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + "Class", + null, + ImplHelper.COMMENT_ENHANCER_ADDED); + + // static initializer + writer.writeStaticInitializer( + ImplHelper.getStaticInitializerImpl(classname, + superPC, + managedFieldNames, + managedFieldTypes, + managedFieldFlags), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoGetManagedFieldCount + writer.writeMethod( + ImplHelper.METHODNAME_JDO_GET_MANAGED_FIELD_COUNT, + Modifier.PROTECTED | Modifier.STATIC, + "int", null, null, null, + ImplHelper.getJDOGetManagedFieldCountImpl( + isPCRoot, superPC, managedFieldNames.length), + ImplHelper.COMMENT_ENHANCER_ADDED); + } + + private void writePCKeyHandlingMembers(final String classname) + throws IOException + { + final boolean isPCRoot + = meta.isPersistenceCapableRootClass(classname); + final String oidClassName + = NameHelper.normalizeClassName(meta.getKeyClass(classname)); + + // generate these methods if this is the PC root class or if + // there's a key class definition + if (!isPCRoot && oidClassName == null) { + return; + } + + final String superOidClassName + = NameHelper.normalizeClassName(meta.getSuperKeyClass(classname)); + final String[] keyFieldNames + = meta.getKeyFields(classname); + final String[] keyFieldTypes + = meta.getFieldType(classname, keyFieldNames); + final int[] keyFieldNumbers + = meta.getFieldNumber(classname, keyFieldNames); + + // jdoNewOidInstance + writer.writeMethod( + ImplHelper.METHODNAME_JDO_NEW_OID_INSTANCE, + Modifier.PUBLIC, + Object.class.getName(), null, null, null, + ImplHelper.getJDONewOidInstanceImpl(oidClassName), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_NEW_OID_INSTANCE, + Modifier.PUBLIC, + Object.class.getName(), + new String[]{ "str" }, + new String[]{ "String" }, + null, + ImplHelper.getJDONewOidInstanceImpl(oidClassName, + "str"), + ImplHelper.COMMENT_ENHANCER_ADDED); + + // jdoCopyKeyFieldsTo/FromOid + writer.writeMethod( + ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID, + Modifier.PUBLIC, + "void", + new String[]{ "oid" }, + new String[]{ "Object" }, + null, + ImplHelper.getJDOCopyKeyFieldsToOid(oidClassName, + superOidClassName, + "oid", + keyFieldNames), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID, + Modifier.PROTECTED, + "void", + new String[]{ "oid" }, + new String[]{ "Object" }, + null, + ImplHelper.getJDOCopyKeyFieldsFromOid(oidClassName, + superOidClassName, + "oid", + keyFieldNames), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID, + Modifier.PUBLIC, + "void", + new String[]{ "ofs", "oid" }, + new String[]{ ImplHelper.CLASSNAME_JDO_OBJECT_ID_FIELD_SUPPLIER, + "Object" }, + null, + ImplHelper.getJDOCopyKeyFieldsToOid(oidClassName, + superOidClassName, + "ofs", + "oid", + keyFieldNames, + keyFieldTypes, + keyFieldNumbers), + ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID, + Modifier.PUBLIC, + "void", + new String[]{ "ofc", "oid" }, + new String[]{ ImplHelper.CLASSNAME_JDO_OBJECT_ID_FIELD_CONSUMER, + "Object" }, + null, + ImplHelper.getJDOCopyKeyFieldsFromOid(oidClassName, + superOidClassName, + "ofc", + "oid", + keyFieldNames, + keyFieldTypes, + keyFieldNumbers), + ImplHelper.COMMENT_ENHANCER_ADDED); + } + + private void writePCSerializationMembers(final String classname) + throws IOException + { + final long serialUID + = createJDOVersionUID(classname); + + //^olsen: to adapt + writer.writeField( + ImplHelper.FIELDNAME_SERIAL_VERSION_UID, + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + "long", + ImplHelper.getSerialVersionUIDInitValue(serialUID), + new String[]{ "only a dummy value yet"}); + //ImplHelper.COMMENT_ENHANCER_ADDED); + + writer.writeMethod( + ImplHelper.METHODNAME_WRITE_OBJECT, + Modifier.PRIVATE, + "void", + new String[]{ "out" }, + new String[]{ ObjectOutputStream.class.getName() }, + new String[]{ IOException.class.getName() }, + ImplHelper.getWriteObjectImpl("out"), + ImplHelper.COMMENT_ENHANCER_ADDED); + } + + private void writeOidClass(final String classname, + final String oidClassName, + final boolean enclosedOid) + throws IOException + { + final int indent = (enclosedOid ? 1 : 0); + writer.writeComments(indent, new String[]{ + "----------------------------------------------------------------------", + "Key Class:", + "----------------------------------------------------------------------" + }); + writer.writeln(); + + writer.setInitialIndents(indent); + + final String superOidClassName + = NameHelper.normalizeClassName(meta.getSuperKeyClass(classname)); + + writer.writeClassHeader( + (enclosedOid ? Modifier.PUBLIC | Modifier.STATIC : 0), + oidClassName, + superOidClassName, + new String[]{ Serializable.class.getName() }, + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + final boolean isPCRoot + = meta.isPersistenceCapableRootClass(classname); + + final String[] pknames = meta.getKeyFields(classname); + final String[] pktypes = meta.getFieldType(classname, pknames); + + // write the PK-fields + for (int i = 0; i < pknames.length; i++) { + writer.writeField( + pknames[i], + Modifier.PUBLIC, + pktypes[i], + null, + null); + } + + // write default constructor + writer.writeConstructor( + NameHelper.getClassName(oidClassName), + Modifier.PUBLIC, + null, null, null, + ImplHelper.getDefaultConstructorImpl(), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + // write string argument constructor + writer.writeConstructor( + NameHelper.getClassName(oidClassName), + Modifier.PUBLIC, + new String[]{ "str" }, + new String[]{ "String" }, + null, + ImplHelper.getOidStringArgConstructorImpl(superOidClassName, + "str"), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + // hashCode + writer.writeMethod( + "hashCode", + Modifier.PUBLIC, + "int", + null, + null, + null, + ImplHelper.getOidHashCodeImpl(pknames, + pktypes, + isPCRoot), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + // equals + writer.writeMethod( + "equals", Modifier.PUBLIC, "boolean", + new String[]{ "pk" }, + new String[]{ Object.class.getName() }, + null, + ImplHelper.getOidEqualsImpl(oidClassName, + pknames, + pktypes, + "pk", + isPCRoot), + ImplHelper.COMMENT_NOT_ENHANCER_ADDED); + + writer.writeClassEnd(); + writer.setInitialIndents(0); + } + + //^olsen to adapt + static private long createJDOVersionUID(final String classname) + { + return classname.hashCode(); + } + + static private String createMethodName(final String prefix, + final String fieldname) + { + return (prefix + Character.toUpperCase(fieldname.charAt(0)) + + fieldname.substring(1)); + } + + private void printMessage(String msg) + { + out.println(msg); + } + + private void printError(String msg, + Throwable ex) + { + if (msg != null) { + err.println(msg + (ex != null ? ": " + ex.getMessage() : "")); + } + if (ex != null) { + ex.printStackTrace(err); + } + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/NameHelper.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/NameHelper.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/NameHelper.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/generator/NameHelper.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.generator; + + +/** + * Helps with class name conversions. + */ +class NameHelper +{ + static String normalizeClassName(String classname) + { + if (classname == null) { + return null; + } + return classname.replace('/', '.').replace('$', '.'); + } + +/* + static String convertClassName(String classname) + { + if (classname == null) { + return null; + } + return classname.replace('.', '_').replace('$', '_'); + } +*/ + + static String getPackageName(String classname) + { + if (classname == null) { + return null; + } + classname = classname.replace('/', '.'); + final int p = classname.lastIndexOf('.'); + return classname.substring(0, p > 0 ? p : 0); + } + + static String getEnclosedClassName(String classname) + { + if (classname == null) { + return null; + } + classname = classname.replace('/', '.'); + final int p = classname.lastIndexOf('.'); + return classname.substring(p + 1); + } + + static String getClassName(String classname) + { + if (classname == null) { + return null; + } + classname = normalizeClassName(classname); + final int p = classname.lastIndexOf('.'); + return classname.substring(p + 1); + } +}