ClassActionpublic final class ClassAction extends com.sun.jdo.api.persistence.enhancer.util.Support implements VMConstantsClassAction handles the persistence annotation actions for a class.
The details specific to individual methods and fields are delegated
to instances of FieldAction and MethodAction. |
Fields Summary |
---|
private static final String | AnnotatedAttribute | private static final short | AnnotatedVersion | private static final String | jdoGetStateManagerName | private static final String | jdoSetStateManagerName | private static final String | jdoGetFlagsName | private static final String | jdoSetFlagsName | private static final String | jdoMakeDirtyName | private static final String | jdoIsDirtyName | private static final String | jdoIsTransactionalName | private static final String | jdoIsPersistentName | private static final String | jdoIsNewName | private static final String | jdoIsDeletedName | private static final String | jdoGetPersistenceManagerName | private static final String | jdoGetObjectIdName | private static final String | jdoConstructorName | private static final String | jdoNewInstanceName | private static final String | jdoClearName | private static final String | jdoCopyName | private static final String | jdoGetFieldName | private static final String | jdoSetFieldName | private static final String | jdoCloneName | private final ClassControl | control | private final Environment | env | private final MethodBuilder | methodBuilder | private final Map | methodActionTable | private final List | fieldActionTable | private boolean | previouslyAnnotated | private boolean | implementsPersistence | private boolean | sawImplementsPersistenceCapable | private boolean | sawImplementsCloneable | private boolean | sawFieldJDOStateManager | private boolean | sawFieldJDOFlags | private boolean | sawMethodJDOGetStateManager | private boolean | sawMethodJDOSetStateManager | private boolean | sawMethodJDOGetFlags | private boolean | sawMethodJDOSetFlags | private boolean | sawMethodJDOMakeDirty | private boolean | sawMethodJDOIsDirty | private boolean | sawMethodJDOIsTransactional | private boolean | sawMethodJDOIsPersistent | private boolean | sawMethodJDOIsNew | private boolean | sawMethodJDOIsDeleted | private boolean | sawMethodJDOGetPersistenceManager | private boolean | sawMethodJDOGetObjectId | private boolean | sawMethodJDOConstructor | private boolean | sawMethodJDONewInstance | private boolean | sawMethodJDOGetField | private boolean | sawMethodJDOSetField | private boolean | sawMethodJDOClear | private boolean | sawMethodJDOCopy | private boolean | sawMethodJDOClone |
Constructors Summary |
---|
public ClassAction(ClassControl control, Environment env)Constructor
/* True if the preDestroyPersistent() method needs to be generated
for PersistenceCapable. */
//@olsen: disabled feature
/*
private boolean needsPreDestroyPersistent = true;
*/
/* True if the postInitializeContents() method needs to be generated
for PersistenceCapable. */
//@olsen: disabled feature
/*
private boolean needsPostInitializeContents = true;
*/
/* True if the preFlushContents() method needs to be generated
for PersistenceCapable. */
//@olsen: disabled feature
/*
private boolean needsPreFlushContents = true;
*/
/* True if the preClearContents() method needs to be generated
for PersistenceCapable. */
//@olsen: disabled feature
/*
private boolean needsPreClearContents = true;
*/
// public accessors
//@olsen: added parameter 'env' for association
this.control = control;
this.env = env;
this.methodBuilder = new MethodBuilder(env);
|
Methods Summary |
---|
public void | annotate()Perform the annotation operations for this class
if (previouslyAnnotated)
return;
//@olsen: moved verbose output from ClassControl to ClassAction
env.message("annotating class " + control.userClassName());//NOI18N
boolean updates = false;
for (Iterator e = methodActions(); e.hasNext(); ) {
MethodAction methodAction = (MethodAction)e.next();
if (methodAction.needsAnnotation()) {
methodAction.annotate();
updates = true;
}
}
//@olsen: disabled feature
/*
if ((generate & GENInitContents) != 0) {
classFile().addMethod(methodBuilder.makeInitializeContents(this));
updates = true;
}
if ((generate & GENFlushContents) != 0) {
classFile().addMethod(methodBuilder.makeFlushContents(this));
updates = true;
}
if ((generate & GENClearContents) != 0) {
classFile().addMethod(methodBuilder.makeClearContents(this));
updates = true;
}
*/
// Even if we haven't updated anything, we want to add an annotated
// attribute if we are doing in-place updates so that we don't
// rewrite the file every time.
if (updates || env.updateInPlace()) {
control.noteUpdate();
//^olsen: to test
// Leave a hint that we've been here before
final byte[] data = new byte[2];
data[0] = (byte)(AnnotatedVersion >>> 8);
data[1] = (byte)(AnnotatedVersion & 0xff);
final ClassAttribute annotatedAttr
= new GenericAttribute(
classFile().pool().addUtf8(AnnotatedAttribute), data);
classFile().attributes().addElement(annotatedAttr);
}
| public void | augment()Add an PersistenceCapable implementation and PersistenceCapableHooks
implementation if needed.
if (previouslyAnnotated)
return;
if (implementsPersistence) {
env.message("augmenting class " + control.userClassName());//NOI18N
if (!sawImplementsPersistenceCapable) {
augmentClassInterface(JDOMetaData.JDOPersistenceCapablePath);
}
if (!sawImplementsCloneable) {
augmentClassInterface(JDOMetaData.javaLangCloneablePath);
}
//@olsen: made fields to have public access
{
insertPersistenceCapableFields(
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig,
JDOMetaData.JDOStateManagerFieldType,
ACCTransient | ACCPublic);
insertPersistenceCapableFields(
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig,
JDOMetaData.JDOFlagsFieldType,
ACCTransient | ACCPublic);
}
insertPersistenceCapableMethods();
}
//@olsen: disabled feature
/*
if (getImplementsPersistenceHooks() &&
!control.hasPersistenceCapableHooksProvided()) {
env.message("modifying class " + control.userClassName() +
" to implement " +
ClassControl.userClassFromVMClass(
JDOMetaData.JDOInstanceCallbacksName));
augmentClassInterface(JDOMetaData.JDOInstanceCallbacksName);
insertPersistenceCapableHooksMethods();
}
*/
| private void | augmentClassInterface(java.lang.String interfaceName)Add the specified interface to list.
control.noteUpdate();
ClassFile cfile = classFile();
ConstClass iface = cfile.pool().addClass(interfaceName);
//@olsen: moved output to here
env.message("adding implements "//NOI18N
+ ClassControl.userClassFromVMClass(interfaceName));
cfile.addInterface(iface);
| ClassControl | classControl()Get the control object
return control;
| ClassFile | classFile()Get the class file which we are operating on
return control.classFile();
| public java.lang.String | className()Return the class name in VM form
return control.className();
| java.util.Iterator | fieldActions()Return an Enumeration of the FieldActions for the class
return fieldActionTable.iterator();
| public boolean | getImplementsPersistence()Return true if this class will implement PersistenceCapable.
return implementsPersistence;
| public boolean | hasAnnotatedAttribute()Checks the class attributes for a filter.annotated attribute.
This works even if scan1 hasn't run yet.
if (previouslyAnnotated)
return true;
Enumeration e = classFile().attributes().elements();
while (e.hasMoreElements()) {
ClassAttribute attr = (ClassAttribute) e.nextElement();
if (attr.attrName().asString().equals(AnnotatedAttribute))
return true;
}
return false;
| public boolean | hasCloneMethod()Return true if this method needs an implementation of clone().
return sawMethodJDOClone;
| private void | insertPersistenceCapableFields(java.lang.String fieldName, java.lang.String fieldSig, java.lang.String printableFieldSig, int accessFlags)Add a field as the index'th element of the field vector in the class.
affirm(implementsPersistence);
control.noteUpdate();
// create it
env.message("adding "//NOI18N
+ control.userClassName() +
"." + fieldName + " " + printableFieldSig);//NOI18N
final ClassFile cfile = classFile();
final ConstantPool pool = cfile.pool();
//@olsen: fix 4467428, add synthetic attribute for generated fields
final AttributeVector fieldAttrs = new AttributeVector();
fieldAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
final ClassField theField
= new ClassField(accessFlags,
pool.addUtf8(fieldName),
pool.addUtf8(fieldSig),
fieldAttrs);
cfile.addField(theField);
| private void | insertPersistenceCapableMethods()Add all the methods required for com.sun.jdo.spi.persistence.support.sqlstore.PersistenceCapable interface.
affirm(implementsPersistence);
control.noteUpdate();
//@olsen: simplified generation of jdo[GS]etStateManager methods
affirm(!sawMethodJDOGetStateManager);
classFile().addMethod(
methodBuilder.makeJDOGetStateManager(
this,
jdoGetStateManagerName));
affirm(!sawMethodJDOSetStateManager);
classFile().addMethod(
methodBuilder.makeJDOSetStateManager(
this,
jdoSetStateManagerName));
//@olsen: simplified generation of jdo[GS]etFlags methods
affirm(!sawMethodJDOGetFlags);
classFile().addMethod(
methodBuilder.makeJDOGetFlags(
this,
jdoGetFlagsName));
affirm(!sawMethodJDOSetFlags);
classFile().addMethod(
methodBuilder.makeJDOSetFlags(
this,
jdoSetFlagsName));
//@olsen: add generation of jdoMakeDirty() method
affirm(!sawMethodJDOMakeDirty);
classFile().addMethod(
methodBuilder.makeJDOMakeDirtyMethod(
this,
jdoMakeDirtyName));
//@olsen: add generation of JDO interrogative methods
affirm(!sawMethodJDOIsDirty);
classFile().addMethod(
methodBuilder.makeJDOInterrogativeMethod(
this,
jdoIsDirtyName));
affirm(!sawMethodJDOIsTransactional);
classFile().addMethod(
methodBuilder.makeJDOInterrogativeMethod(
this,
jdoIsTransactionalName));
affirm(!sawMethodJDOIsPersistent);
classFile().addMethod(
methodBuilder.makeJDOInterrogativeMethod(
this,
jdoIsPersistentName));
affirm(!sawMethodJDOIsNew);
classFile().addMethod(
methodBuilder.makeJDOInterrogativeMethod(
this,
jdoIsNewName));
affirm(!sawMethodJDOIsDeleted);
classFile().addMethod(
methodBuilder.makeJDOInterrogativeMethod(
this,
jdoIsDeletedName));
//@olsen: add generation of jdoGetPersistenceManager method
affirm(!sawMethodJDOGetPersistenceManager);
classFile().addMethod(
methodBuilder.makeJDOGetPersistenceManagerMethod(
this,
jdoGetPersistenceManagerName));
//@olsen: add generation of jdoGetObjectId method
affirm(!sawMethodJDOGetObjectId);
classFile().addMethod(
methodBuilder.makeJDOGetObjectIdMethod(
this,
jdoGetObjectIdName));
//@olsen: add generation of the JDO constructor
affirm(!sawMethodJDOConstructor);
classFile().addMethod(
methodBuilder.makeJDOConstructor(
this,
jdoConstructorName));
//@olsen: add generation of the jdoNewInstance method
affirm(!sawMethodJDONewInstance);
classFile().addMethod(
methodBuilder.makeJDONewInstanceMethod(
this,
jdoNewInstanceName));
//@olsen: add generation of the jdoGetField method
affirm(!sawMethodJDOGetField);
classFile().addMethod(
methodBuilder.makeJDOGetFieldMethod(
this,
jdoGetFieldName));
//@olsen: add generation of the jdoSetField method
affirm(!sawMethodJDOSetField);
classFile().addMethod(
methodBuilder.makeJDOSetFieldMethod(
this,
jdoSetFieldName));
//@olsen: add generation of the jdoClear method
affirm(!sawMethodJDOClear);
classFile().addMethod(
methodBuilder.makeJDOClearMethod(
this,
jdoClearName));
//@lars: removed jdoCopy-method creation
//@olsen: add generation of the jdoCopy method
/*
affirm(!sawMethodJDOCopy);
classFile().addMethod(
methodBuilder.makeJDOCopyMethod(
this,
jdoCopyName));
*/
//@olsen: generate method clone() if not present
if (!sawMethodJDOClone) {
classFile().addMethod(
methodBuilder.makeJDOClone(
this,
jdoCloneName));
}
| java.util.Iterator | methodActions()Return an Enumeration of the MethodActions for the class
return methodActionTable.values().iterator();
| public void | scan1()Perform the pass1 scan of the class.
Certain scan operations must be completed for all classes before
the remaining operations can be completed.
//@olsen: moved verbose output from ClassControl to ClassAction
env.message("scanning class " + control.userClassName());//NOI18N
//@olsen: added constraints; ensured by ClassControl
affirm(!classFile().isInterface());
affirm(control.persistType() > ClassControl.TransientOnly);
scanAttributes();
//@olsen: 4357074 skip previously enhanced files
if (previouslyAnnotated) {
return;
}
//@olsen: initialize 'implementsPersistence' flag from JDOMetaData
final String name = className();
implementsPersistence
= env.getJDOMetaData().isPersistenceCapableRootClass(name);
//@olsen: checks on persistence-capable classes
final boolean isPersistent
= (control.persistType() == ClassControl.PersistCapable);
if (isPersistent) {
// check whether this class directly implements PersistenceCapable
// or clonable.
scanForImplementsInterfaces();
// check only fields of persistence-capable classes
scanFields();
}
//@olsen: removed check, ensured before already
//if (!previouslyAnnotated && !classFile().isInterface())
scanMethods();
| private void | scanAttributes()Scans the attributes of a ClassFile
Enumeration e = classFile().attributes().elements();
while (e.hasMoreElements()) {
ClassAttribute attr = (ClassAttribute) e.nextElement();
if (attr.attrName().asString().equals(AnnotatedAttribute)) {
previouslyAnnotated = true;
//@olsen: disabled feature
/*
if (!control.isImplicitlyPersistent() && !env.updateInPlace()) {
*/
{
// At some point we may want to consider stripping old
// annotations and re-annotating, but not yet
env.message("ignoring previously enhanced class "//NOI18N
+ control.userClassName());
}
break;
}
}
| private void | scanFields()Scans the fields of a ClassFile
If this is not a persistence capable class, do nothing.
Enumeration e = classFile().fields().elements();
while (e.hasMoreElements()) {
final ClassField f = (ClassField)e.nextElement();
final String fieldName = f.name().asString();
final String fieldSig = f.signature().asString();
//@olsen: added check
scanForJDOFields(fieldName, fieldSig);
FieldAction action = new FieldAction(this, f, env);
action.check();
fieldActionTable.add(action);
}
| private void | scanForImplementsInterfaces()Scans the class to check whether it implemens interfaces
PersistenceCapable and Clonable.
Sets instance variables sawImplementsPersistenceCapable if
the class implements JDOMetaData.JDOPersistenceCapablePath .
Sets the instance variable sawImplementsCloneable
if the class implements JDOMetaData.javaLangCloneablePath .
Please note that only the current class is scanned for implemented
interfaces by this method. Even if the super class implements
one of the above interfaces, the corresponding instance variable will
not be set.
for (Iterator ifc = classFile().interfaces().iterator();
ifc.hasNext();) {
final ConstClass i = (ConstClass)ifc.next();
String interfaceNamePath = i.asString();
if (interfaceNamePath.equals(JDOMetaData.JDOPersistenceCapablePath)) {
sawImplementsPersistenceCapable = true;
//@olsen: warn if user-defined 'implements PC' clause
env.warning(
getI18N("enhancer.class_implements_jdo_pc",//NOI18N
new Object[]{
userClassName(),
JDOMetaData.JDOPersistenceCapableType
}));
}
if(JDOMetaData.javaLangCloneablePath.equals(interfaceNamePath) ) {
sawImplementsCloneable = true;
}
}
//@olsen: disabled feature
//@olsen: don't check whether this class implements PC indirectly
/*
if (control.implementsPersistenceCapable())
env.warning(
getI18N("enhancer.class_implements_pc",
userClassName(),
meta.JDOPersistenceCapableType));
*/
| private void | scanForJDOFields(java.lang.String fieldName, java.lang.String fieldSig)Scan for JDO fields.
if (fieldName.equals(JDOMetaData.JDOStateManagerFieldName)) {
env.error(
getI18N("enhancer.class_defines_jdo_field",//NOI18N
userClassName(),
JDOMetaData.JDOStateManagerFieldName));
sawFieldJDOStateManager = true;
return;
}
if (fieldName.equals(JDOMetaData.JDOFlagsFieldName)) {
env.error(
getI18N("enhancer.class_defines_jdo_field",//NOI18N
userClassName(),
JDOMetaData.JDOFlagsFieldName));
sawFieldJDOFlags = true;
return;
}
//@olsen: check whether member starts with the reserved jdo prefix
if (fieldName.startsWith("jdo")) {//NOI18N
//@olsen: issue a warning only
env.warning(
getI18N("enhancer.class_has_jdo_like_member",//NOI18N
userClassName(), fieldName));
return;
}
| private void | scanForJDOMethods(java.lang.String methodName, java.lang.String methodSig)Scan for JDO methods.
if (methodName.equals(jdoGetStateManagerName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOGetStateManager = true;
return;
}
if (methodName.equals(jdoSetStateManagerName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOSetStateManager = true;
return;
}
if (methodName.equals(jdoGetFlagsName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOGetFlags = true;
return;
}
if (methodName.equals(jdoSetFlagsName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOSetFlags = true;
return;
}
if (methodName.equals(jdoMakeDirtyName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOMakeDirty = true;
return;
}
if (methodName.equals(jdoIsDirtyName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOIsDirty = true;
return;
}
if (methodName.equals(jdoIsTransactionalName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOIsTransactional = true;
return;
}
if (methodName.equals(jdoIsPersistentName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOIsPersistent = true;
return;
}
if (methodName.equals(jdoIsNewName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOIsNew = true;
return;
}
if (methodName.equals(jdoIsDeletedName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOIsDeleted = true;
return;
}
if (methodName.equals(jdoGetPersistenceManagerName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOGetPersistenceManager = true;
return;
}
if (methodName.equals(jdoGetObjectIdName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOGetObjectId = true;
return;
}
//^olsen: get signature from method builder
// for jdo constructor, check by name and signature
if (methodName.equals(jdoConstructorName)
&& methodSig.equals("(" + JDOMetaData.JDOStateManagerSig + ")V")) {//NOI18N
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOConstructor = true;
return;
}
if (methodName.equals(jdoNewInstanceName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDONewInstance = true;
return;
}
if (methodName.equals(jdoClearName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOClear = true;
return;
}
if (methodName.equals(jdoCopyName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOCopy = true;
return;
}
if (methodName.equals(jdoGetFieldName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOGetField = true;
return;
}
if (methodName.equals(jdoSetFieldName)) {
env.error(
getI18N("enhancer.class_defines_jdo_method",//NOI18N
userClassName(), methodName));
sawMethodJDOSetField = true;
return;
}
//^olsen: get signature from method builder
// for method clone(), check by name and signature
if (methodName.equals(jdoCloneName)
&& methodSig.equals("()Ljava/lang/Object;")) {//NOI18N
// it's OK to have a user-defined clone()
sawMethodJDOClone = true;
return;
}
//@olsen: check whether member starts with the reserved jdo prefix
if (methodName.startsWith("jdo")) {//NOI18N
//@olsen: issue a warning only
env.warning(
getI18N("enhancer.class_has_jdo_like_member",//NOI18N
userClassName(), methodName));
return;
}
//@olsen: disabled feature
/*
boolean sawInitializeContents = false;
boolean sawFlushContents = false;
boolean sawClearContents = false;
*/
//@olsen: disabled feature
/*
else if (methodName.equals("initializeContents") &&
methodSig.equals("(com/sun/forte4j/persistence/internal/ObjectContents;)V"))
sawInitializeContents = true;
else if (methodName.equals("flushContents") &&
methodSig.equals("(Lcom/sun/forte4j/persistence/internal/ObjectContents;)V"))
sawFlushContents = true;
else if (methodName.equals("clearContents") &&
methodSig.equals("()V"))
sawClearContents = true;
*/
//@olsen: disabled feature
/*
else if (methodName.equals("preDestroyPersistent") &&
methodSig.equals("()V"))
needsPreDestroyPersistent = false;
else if (methodName.equals("postInitializeContents") &&
methodSig.equals("()V"))
needsPostInitializeContents = false;
else if (methodName.equals("preFlushContents") &&
methodSig.equals("()V"))
needsPreFlushContents = false;
else if (methodName.equals("preClearContents") &&
methodSig.equals("()V"))
needsPreClearContents = false;
*/
//@olsen: disabled feature
/*
if (!sawInitializeContents)
generate |= GENInitContents;
if (!sawFlushContents)
generate |= GENFlushContents;
if (!sawClearContents)
generate |= GENClearContents;
*/
| private void | scanMethods()Scans the methods of a ClassFile.
final boolean isPersistent
= (control.persistType() == ClassControl.PersistCapable);
Enumeration e = classFile().methods().elements();
while (e.hasMoreElements()) {
final ClassMethod m = (ClassMethod)e.nextElement();
final String methodName = m.name().asString();
final String methodSig = m.signature().asString();
if (isPersistent) {
scanForJDOMethods(methodName, methodSig);
}
final MethodAction action = new MethodAction(this, m, env);
action.check();
methodActionTable.put(m, action);
}
| public java.lang.String | userClassName()Return the class name in user ('.' delimited) form
return control.userClassName();
|
|