com.sun.jdo.api.persistence.enhancer.impl.MethodBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.jdo.api.persistence.enhancer.impl;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Enumeration;
import com.sun.jdo.api.persistence.enhancer.classfile.*;
import com.sun.jdo.api.persistence.enhancer.util.Support;
import com.sun.jdo.api.persistence.enhancer.util.InternalError;
import com.sun.jdo.api.persistence.enhancer.util.ClassFileSource;
//@olsen: added import
import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaData;
//@olsen: cosmetics
//@olsen: moved: this class -> package impl
//@olsen: subst: (object)state -> flags
//@olsen: subst: JDOflags -> jdoFlags
//@olsen: subst: makeJDO[gs]etFlags -> makeJDO[GS]etFlags
//@olsen: subst: JDO[gs]etFlags -> jdo[GS]etFlags
//@olsen: subst: [Nn]eedsJDORefMethods -> [Nn]eedsJDOStateManagerMethods
//@olsen: subst: JDOref -> jdoStateManager
//@olsen: subst: makeJDO[gs]etRef -> makeJDO[GS]etStateManager
//@olsen: subst: JDO[gs]etRef -> jdo[GS]etStateManager
//@olsen: subst: [iI]Persistent -> [pP]ersistenceCapable
//@olsen: subst: PersistentAux -> StateManager
//@olsen: subst: jdo/ -> com/sun/forte4j/persistence/internal/
//@olsen: subst: jdo. -> com.sun.forte4j.persistence.internal.
//@olsen: subst: /* ... */ -> // ...
//@olsen: added: final modifiers on local variables
//@olsen: subst: FilterEnv -> Environment
//@olsen: made MethodBuilder's methods non-static
//@olsen: dropped parameter 'Environment env', use association instead
//@olsen: subst: Enumeration,... -> Iterator, hasNext(), next()
//@olsen: subst: myMethodName -> methodName
//@olsen: added: support for I18N
//@olsen: subst: FilterError -> UserException, affirm()
//@olsen: removed: proprietary support for ClassInfo
//@olsen: removed: proprietary support for FieldNote
//@olsen: removed: old, disabled ODI code
/**
* MethodBuilder is a collection of methods which
* create the persistence methods of a persistent class
*/
class MethodBuilder
extends Support
implements VMConstants {
//@olsen: fix for bug 4467428:
// Debugging under jdk 1.3.1 shows the problem that any breakpoints
// in PC classes are ignored if the added jdo methods do NOT have a
// non-empty line number table attribute, no matter whether the
// 'Synthetic' attribute is given or not. However, this doesn't
// seem to comply with the JVM Spec (2nd edition), which states
// that the synthetic attribute _must_ be specified if no source
// code information is available for the member:
//
// 4.7.6 The Synthetic Attribute
// ... A class member that does not appear in the source code must
// be marked using a Synthetic attribute. ...
//
// 4.7.8 The LineNumberTable Attribute
// The LineNumberTable attribute is an optional variable-length
// attribute in the attributes table of a Code (see 4.7.3)
// attribute. It may be used by debuggers to determine which
// part of the Java virtual machine code array corresponds to a
// given line number in the original source file. ... Furthermore,
// multiple LineNumberTable attributes may together represent a
// given line of a source file; that is, LineNumberTable attributes
// need not be one-to-one with source lines.
//
// Unfortunately, if we do both, adding the synthetic attribute and
// a (dummy) line number table on generated methods, jdk's 1.3.1 javap
// fails to disassemble the classfile with an exception:
//
// sun.tools.java.CompilerError: checkOverride() synthetic
//
// So, to workaround these problems and to allow for both, debugging
// and disassembling with the jdk (1.3.1) tools, we pretend that the
// generated jdo methods have source code equivalents by
// - not adding the synthetic code attribute
// - providing a dummy line number table code attribute
static private final boolean addSyntheticAttr = false;
static private final boolean addLineNumberTableAttr = true;
/* Central repository for the options and classes */
//@olsen: added association
//@olsen: made final
private final Environment env;
/**
* Constructor.
*/
//@olsen: added constructor
//@olsen: added parameter 'env' for association
public MethodBuilder(Environment env) {
this.env = env;
}
/**
* Build a null method named methodName for the class.
*
* public void methodName() {
* }
*/
//@olsen: moved to beginning of this class
ClassMethod makeNullMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass thisClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod nullMethod
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// end of method body
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
0, // maxStack
1, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return nullMethod;
}
/**
* Build the initializeContents method for the class
*/
//@olsen: dropped method
/*
ClassMethod makeInitializeContents(ClassAction ca) {
final ConstantPool pool = ca.classFile().pool();
final ConstClass thisClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
ClassMethod initializeContentsMethod =
new ClassMethod(ACCPublic,
pool.addUtf8("initializeContents"),
pool.addUtf8("(Lcom/sun/forte4j/persistence/internal/ObjectContents;)V"),
methodAttrs);
// begin of method body
Insn begin = new InsnTarget();
Insn insn = begin;
// Allocated reg 2 as cached ClassInfo*
insn = insn.append(
Insn.create(opc_getstatic,
pool.addFieldRef(thisClass.asString(),
ca.getClassInfoMember(),
"Lcom/sun/forte4j/persistence/internal/ClassInfo;")));
insn = insn.append(Insn.create(opc_astore_2));
for (Iterator e = ca.fieldActions(); e.hasNext();) {
FieldAction act = (FieldAction)e.next();
if (act.isPersistent()) {
int idx = act.index();
// get this
insn = insn.append(Insn.create(opc_aload_0));
// get GenericObject
insn = insn.append(Insn.create(opc_aload_1));
// get field index
insn = insn.append(InsnUtils.integerConstant(idx, pool));
// get ClassInfo
insn = insn.append(Insn.create(opc_aload_2));
// call the get method
insn = insn.append(Insn.create(opc_invokevirtual,
pool.addMethodRef("com/sun/forte4j/persistence/internal/ObjectContents",
act.getMethod(), act.getMethodSig())));
switch(act.getMethodReturn()) {
case T_DOUBLE:
case T_LONG:
case T_BOOLEAN:
case T_CHAR:
case T_FLOAT:
case T_BYTE:
case T_SHORT:
case T_INT:
case TC_STRING:
// The above types are assumed to be accurate, with no
// conversions required
break;
case TC_OBJECT:
case TC_INTERFACE:
if (!act.typeDescriptor().equals("Ljava/lang/Object;")) {
ConstClass fieldType = pool.addClass(act.typeName());
// Add a cast to the appropriate type
insn = insn.append(Insn.create(opc_checkcast, fieldType));
}
break;
default:
throw new InternalError("Unexpected return type");
}
// finally, store the result
insn = insn.append(Insn.create(opc_putfield,
pool.addFieldRef(thisClass.asString(), act.fieldName(),
act.typeDescriptor())));
}
}
ConstClass superClass = ca.classFile().superName();
if (!ca.getImplementsPersistence()) {
// Need to invoke initializeContents on super
// get this
insn = insn.append(Insn.create(opc_aload_0));
// get generic object
insn = insn.append(Insn.create(opc_aload_1));
// do the invoke
insn = insn.append(Insn.create(opc_invokespecial,
pool.addMethodRef(superClass.asString(),
"initializeContents", "(Lcom/sun/forte4j/persistence/internal/ObjectContents;)V")));
}
// end of method body
insn = insn.append(Insn.create(opc_return));
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
4, // maxStack
3, // maxLocals
begin,
new ExceptionTable(),
new AttributeVector()));
return initializeContentsMethod;
}
*/
/**
* Build the flushContents method for the class
*/
//@olsen: dropped method
/*
ClassMethod makeFlushContents(ClassAction ca) {
final ConstantPool pool = ca.classFile().pool();
final ConstClass thisClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
ClassMethod flushContentsMethod =
new ClassMethod(ACCPublic,
pool.addUtf8("flushContents"),
pool.addUtf8("(Lcom/sun/forte4j/persistence/internal/ObjectContents;)V"),
methodAttrs);
// begin of method body
Insn begin = new InsnTarget();
Insn insn = begin;
// Allocated reg 2 as cached ClassInfo*
insn = insn.append(
Insn.create(opc_getstatic,
pool.addFieldRef(thisClass.asString(),
ca.getClassInfoMember(),
"Lcom/sun/forte4j/persistence/internal/ClassInfo;")));
insn = insn.append(Insn.create(opc_astore_2));
for (Iterator e = ca.fieldActions(); e.hasNext();) {
FieldAction act = (FieldAction)e.next();
if (act.isPersistent()) {
int idx = act.index();
// get GenericObject
insn = insn.append(Insn.create(opc_aload_1));
// get field index
insn = insn.append(InsnUtils.integerConstant(idx, pool));
// get this
insn = insn.append(Insn.create(opc_aload_0));
// get the field value
insn = insn = insn.append(Insn.create(opc_getfield,
pool.addFieldRef(thisClass.asString(), act.fieldName(),
act.typeDescriptor())));
// get ClassInfo
insn = insn.append(Insn.create(opc_aload_2));
// call the set method
insn = insn.append(Insn.create(opc_invokevirtual,
pool.addMethodRef("com/sun/forte4j/persistence/internal/ObjectContents",
act.setMethod(), act.setMethodSig())));
}
}
ConstClass superClass = ca.classFile().superName();
if (!ca.getImplementsPersistence()) {
// Need to invoke flushContents on super
// get this
insn = insn.append(Insn.create(opc_aload_0));
// get generic object
insn = insn.append(Insn.create(opc_aload_1));
// do the invoke
insn = insn.append(Insn.create(opc_invokespecial,
pool.addMethodRef(superClass.asString(),
"flushContents", "(Lcom/sun/forte4j/persistence/internal/ObjectContents;)V")));
}
// end of method body
insn = insn.append(Insn.create(opc_return));
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
6, // maxStack (might actually be 5, but ok)
3, // maxLocals
begin,
new ExceptionTable(),
new AttributeVector()));
return flushContentsMethod;
}
*/
/**
* Build the clearContents method for the class
*/
//@olsen: dropped method
/*
ClassMethod makeClearContents(ClassAction ca) {
final ConstantPool pool = ca.classFile().pool();
final ConstClass thisClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
ClassMethod clearContentsMethod =
new ClassMethod(ACCPublic,
pool.addUtf8("clearContents"),
pool.addUtf8("()V"),
methodAttrs);
// begin of method body
Insn begin = new InsnTarget();
Insn insn = begin;
for (Iterator e = ca.fieldActions(); e.hasNext();) {
FieldAction act = (FieldAction)e.next();
if (act.isPersistent()) {
int idx = act.index();
// get this
insn = insn.append(Insn.create(opc_aload_0));
// Use the getMethodReturn type to decide how to initialize
switch(act.getMethodReturn()) {
case T_DOUBLE:
insn = insn.append(Insn.create(opc_dconst_0));
break;
case T_LONG:
insn = insn.append(Insn.create(opc_lconst_0));
break;
case T_FLOAT:
insn = insn.append(Insn.create(opc_fconst_0));
break;
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
case T_INT:
insn = insn.append(Insn.create(opc_iconst_0));
break;
case TC_STRING:
case TC_OBJECT:
case TC_INTERFACE:
insn = insn.append(Insn.create(opc_aconst_null));
break;
default:
throw new InternalError("Unexpected return type");
}
// finally, store the result
insn = insn.append(Insn.create(opc_putfield,
pool.addFieldRef(thisClass.asString(), act.fieldName(),
act.typeDescriptor())));
}
}
ConstClass superClass = ca.classFile().superName();
if (!ca.getImplementsPersistence()) {
// Need to invoke clearContents on super
// get this
insn = insn.append(Insn.create(opc_aload_0));
// do the invoke
insn = insn.append(Insn.create(opc_invokespecial,
pool.addMethodRef(superClass.asString(),
"clearContents", "()V")));
}
// end of method body
insn = insn.append(Insn.create(opc_return));
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
3, // maxStack (maybe only 2 - ok)
1, // maxLocals
begin,
new ExceptionTable(),
new AttributeVector()));
return clearContentsMethod;
}
*/
/**
* Build an empty class initializer method for this class
*/
//@olsen: dropped method
/*
ClassMethod makeClassInit(ClassAction ca) {
final ConstantPool pool = ca.classFile().pool();
final ConstClass thisClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
ClassMethod classInitMethod =
new ClassMethod(ACCStatic,
pool.addUtf8(""),
pool.addUtf8("()V"),
methodAttrs);
// begin of method body
Insn begin = new InsnTarget();
Insn insn = begin;
// return from the initializer
// end of method body
insn = insn.append(Insn.create(opc_return));
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
0,
0, // maxLocals
begin,
new ExceptionTable(),
new AttributeVector()));
return classInitMethod;
}
*/
/**
* Build the jdoGetStateManager method for the class.
*
* public StateManager jdoGetStateManager() {
* return this.jdoStateManager;
* }
*/
//@olsen: cosmetics
ClassMethod makeJDOGetStateManager(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()" + JDOMetaData.JDOStateManagerSig;//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoGetStateManagerMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// get jdoStateManager field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
// end of method body
insn = insn.append(Insn.create(opc_areturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
1, // maxStack
1, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoGetStateManagerMethod;
}
/**
* Build the jdoSetStateManager method for the class.
*
* public void jdoSetStateManager(StateManager sm) {
* this.jdoStateManager = sm;
* }
*/
//@olsen: cosmetics
ClassMethod makeJDOSetStateManager(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(" + JDOMetaData.JDOStateManagerSig + ")V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoSetStateManagerMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// put argument value to jdoStateManager field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
// end of method body
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
2, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoSetStateManagerMethod;
}
/**
* Build the jdoGetFlags method for the class.
*
* public byte jdoGetFlags() {
* return this.jdoFlags;
* }
*/
//@olsen: cosmetics
ClassMethod makeJDOGetFlags(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()B";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoGetFlagsMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// get jdoFlags field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig)));
// end of method body
insn = insn.append(Insn.create(opc_ireturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
1, // maxStack
1, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoGetFlagsMethod;
}
/**
* Build the jdoSetFlags method for the class.
*
* public void jdoSetFlags(byte flags) {
* this.jdoFlags = flags;
* }
*/
//@olsen: cosmetics
ClassMethod makeJDOSetFlags(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(B)V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoSetFlagsMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// put argument value to jdoFlags field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(Insn.create(opc_iload_1));
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig)));
// end of method body
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
2, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoSetFlagsMethod;
}
/**
* Build the jdoMakeDirty method for the class.
*
* public void makeDirty() {
* final StateManager sm = this.jdoStateManager;
* if (sm != null)
* sm.makeDirty(fieldName);
* }
*/
//@olsen: added method for generating the jdoMakeDirty method
ClassMethod makeJDOMakeDirtyMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(Ljava/lang/String;)V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoMakeDirtyMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// fetch the jdoStateManager field into local var
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(
opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
insn = insn.append(Insn.create(opc_astore_2));
// test the jdoStateManager field and goto end if null
InsnTarget end = new InsnTarget();
insn = insn.append(Insn.create(opc_aload_2));
insn = insn.append(Insn.create(opc_ifnull, end));
// call the jdoStateManager's makeDirty method with argument
insn = insn.append(Insn.create(opc_aload_2));
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
new InsnInterfaceInvoke(
pool.addInterfaceMethodRef(
JDOMetaData.JDOStateManagerPath,
"makeDirty",//NOI18N
"(Ljava/lang/String;)V"),//NOI18N
2));
// end of method body
insn = insn.append(end);
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
2, // maxStack
3, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoMakeDirtyMethod;
}
/**
* Build an interrogative method named methodName for the class.
*
* public boolean isXXX() {
* final StateManager sm = this.jdoStateManager;
* if (sm == null)
* return false;
* return sm.isXXXX();
* }
*/
//@olsen: added method for generating an interrogative JDO method
ClassMethod makeJDOInterrogativeMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()Z";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod interrogativeMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// fetch the jdoStateManager field into local var
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(
opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
insn = insn.append(Insn.create(opc_astore_1));
// test the jdoStateManager field and return false if null
InsnTarget call = new InsnTarget();
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(Insn.create(opc_ifnonnull, call));
insn = insn.append(Insn.create(opc_iconst_0));
insn = insn.append(Insn.create(opc_ireturn));
// call the jdoStateManager's interrogative method (jdoIs... -> is...)
final String callName = "i" + methodName.substring(4);//NOI18N
insn = insn.append(call);
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
new InsnInterfaceInvoke(
pool.addInterfaceMethodRef(
JDOMetaData.JDOStateManagerPath,
callName,
"()Z"),//NOI18N
1));
// end of method body
insn = insn.append(Insn.create(opc_ireturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
1, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return interrogativeMethod;
}
/**
* Build the jdoGetPersistenceManager method for the class.
*
* public PersistenceManager jdoGetPersistenceManager() {
* final StateManager sm = this.jdoStateManager;
* if (sm == null)
* return null;
* return sm.getPersistenceManager();
* }
*/
//@olsen: added method for generating the jdoGetPersistenceManager method
ClassMethod makeJDOGetPersistenceManagerMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()" + JDOMetaData.JDOPersistenceManagerSig;//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoGetPersistenceManagerMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// fetch the jdoStateManager field into local var
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(
opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
insn = insn.append(Insn.create(opc_astore_1));
// test the jdoStateManager field and return null if null
InsnTarget call = new InsnTarget();
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(Insn.create(opc_ifnonnull, call));
insn = insn.append(Insn.create(opc_aconst_null));
insn = insn.append(Insn.create(opc_areturn));
// call the jdoStateManager's getPersistenceManager method
insn = insn.append(call);
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
new InsnInterfaceInvoke(
pool.addInterfaceMethodRef(
JDOMetaData.JDOStateManagerPath,
"getPersistenceManager",//NOI18N
"()" + JDOMetaData.JDOPersistenceManagerSig),//NOI18N
1));
// end of method body
insn = insn.append(Insn.create(opc_areturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
1, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoGetPersistenceManagerMethod;
}
/**
* Build the jdoGetObjectId method for the class.
*
* public Object jdoGetObjectId() {
* final StateManager sm = this.jdoStateManager;
* if (sm == null)
* return null;
* return sm.getObjectId();
* }
*/
//@olsen: added method for generating the jdoGetObjectId method
ClassMethod makeJDOGetObjectIdMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()Ljava/lang/Object;";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: made method final
final ClassMethod jdoGetObjectIdMethod
= new ClassMethod(ACCPublic | ACCFinal,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// fetch the jdoStateManager field into local var
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(
opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
insn = insn.append(Insn.create(opc_astore_1));
// test the jdoStateManager field and return null if null
InsnTarget call = new InsnTarget();
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(Insn.create(opc_ifnonnull, call));
insn = insn.append(Insn.create(opc_aconst_null));
insn = insn.append(Insn.create(opc_areturn));
// call the jdoStateManager's getObjectId method
insn = insn.append(call);
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
new InsnInterfaceInvoke(
pool.addInterfaceMethodRef(
JDOMetaData.JDOStateManagerPath,
"getObjectId",//NOI18N
"()Ljava/lang/Object;"),//NOI18N
1));
// end of method body
insn = insn.append(Insn.create(opc_areturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
1, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoGetObjectIdMethod;
}
/**
* Build the jdoGetJDOConstructor method for the class.
*
* public (StateManager sm) {
* this.jdoFlags = 1;
* this.jdoStateManager = sm;
* }
*/
//@olsen: added method for generating the JDO constructor
ClassMethod makeJDOConstructor(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(" + JDOMetaData.JDOStateManagerSig + ")V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod jdoGetJDOConstructor
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// call the super-class' constructor
final ConstClass superClass = ca.classFile().superName();
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_invokespecial,
pool.addMethodRef(superClass.asString(),
"",//NOI18N
"()V")));//NOI18N
// put argument value to jdoFlags field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(Insn.create(opc_iconst_1));
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig)));
// put argument value to jdoStateManager field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
Insn.create(
opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
// end of method body
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
2, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoGetJDOConstructor;
}
/**
* Build the jdoNewInstance method for the class.
*
* public Object jdoNewInstance(StateManager sm) {
* return new (sm);
* }
*/
//@olsen: added method for generating the getObjectId method
ClassMethod makeJDONewInstanceMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig
= "(" + JDOMetaData.JDOStateManagerSig + ")Ljava/lang/Object;";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod jdoNewInstanceMethod
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// create an instance of the class by JDO constructor
insn = insn.append(Insn.create(opc_new, theClass));
insn = insn.append(Insn.create(opc_dup));
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
Insn.create(
opc_invokespecial,
pool.addMethodRef(
theClass.asString(),
"",//NOI18N
"(" + JDOMetaData.JDOStateManagerSig + ")V")));//NOI18N
// end of method body
insn = insn.append(Insn.create(opc_areturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
3, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoNewInstanceMethod;
}
/**
* Build the jdoClear method for the class.
*
* public void jdoClear() {
* ...
* }
*/
//@olsen: added method for generating the jdoClear method
ClassMethod makeJDOClearMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod jdoClearMethod
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
//@olsen: disabled code
if (false) {
// reset jdoFlags = LOAD_REQUIRED
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(Insn.create(opc_iconst_1));
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig)));
}
// iterate over all declared fields of the class
for (Iterator e = ca.fieldActions(); e.hasNext();) {
final FieldAction act = (FieldAction)e.next();
//printFieldAction(act);
//System.out.println();
// ignore non-persistent fields
if (!act.isPersistent())
continue;
// ignore primary key fields
if (act.isPrimaryKey())
continue;
//@olsen: disconnect mutable SCOs before clear
if (act.isMutableSCO()) {
// fetch field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
// test whether instanceof SCO base type
// skip disconnecting if == 0
final ConstClass cc
= pool.addClass(JDOMetaData.JDOSecondClassObjectBasePath);
InsnTarget disconnect = new InsnTarget();
InsnTarget afterDisconnect = new InsnTarget();
insn = insn.append(
Insn.create(opc_dup));
insn = insn.append(
Insn.create(opc_instanceof,
cc));
insn = insn.append(
Insn.create(opc_ifne,
disconnect));
// pop field and skip disconnecting
insn = insn.append(
Insn.create(opc_pop));
insn = insn.append(
Insn.create(opc_goto, afterDisconnect));
// disconnect SCO field's object
insn = insn.append(disconnect);
// cast to SCO base type
insn = insn.append(
Insn.create(opc_checkcast,
cc));
// call method: void unsetOwner();
final int requiredStack = 1;
insn = insn.append(
new InsnInterfaceInvoke(
pool.addInterfaceMethodRef(
JDOMetaData.JDOSecondClassObjectBasePath,
"unsetOwner",//NOI18N
"()V"),//NOI18N
requiredStack));
insn = insn.append(afterDisconnect);
}
// get this
insn = insn.append(Insn.create(opc_aload_0));
// use the getMethodReturn type to decide how to clear field
switch(act.getMethodReturn()) {
case T_DOUBLE:
insn = insn.append(Insn.create(opc_dconst_0));
break;
case T_LONG:
insn = insn.append(Insn.create(opc_lconst_0));
break;
case T_FLOAT:
insn = insn.append(Insn.create(opc_fconst_0));
break;
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
case T_INT:
insn = insn.append(Insn.create(opc_iconst_0));
break;
case TC_STRING:
case TC_OBJECT:
case TC_INTERFACE:
insn = insn.append(Insn.create(opc_aconst_null));
break;
default:
throw new InternalError("Unexpected return type");//NOI18N
}
// put default value to field
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
}
// end of method body
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
3, // maxStack
1, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoClearMethod;
}
/**
* Build the jdoCopy method for the class.
*
* public void jdoCopy(Object o, boolean cloneSCOs) {
* ...
* }
*/
//@lars, @olsen: disabled jdoCopy becuase of two problems with the
// current code (this method hasn't been used by the runtime anyway):
// 4388418: Generated jdoCopy() must ignore static fields
// 4388367: Generated jdoCopy() can throw NPE if argument = 'true'
/*
//@olsen: added method for generating the jdoCopy method
ClassMethod makeJDOCopyMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(Ljava/lang/Object;Z)V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod jdoCopyMethod
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// get class object of this and of argument object
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
Insn.create(opc_invokevirtual,
pool.addMethodRef(
"java/lang/Object",//NOI18N
"getClass",//NOI18N
"()Ljava/lang/Class;")));//NOI18N
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(
Insn.create(opc_invokevirtual,
pool.addMethodRef(
"java/lang/Object",//NOI18N
"getClass",//NOI18N
"()Ljava/lang/Class;")));//NOI18N
// test class objects for equality and throw exception if false
insn = insn.append(
Insn.create(opc_invokevirtual,
pool.addMethodRef(
"java/lang/Object",//NOI18N
"equals",//NOI18N
"(Ljava/lang/Object;)Z")));//NOI18N
InsnTarget cast = new InsnTarget();
insn = insn.append(Insn.create(opc_ifne, cast));
final String exceptionClassName
= "com/sun/forte4j/persistence/JDOFatalException";//NOI18N
insn = insn.append(
Insn.create(opc_new,
pool.addClass(exceptionClassName)));
insn = insn.append(Insn.create(opc_dup));
insn = insn.append(
Insn.create(opc_invokespecial,
pool.addMethodRef(
exceptionClassName,
"",//NOI18N
"()V")));//NOI18N
insn = insn.append(Insn.create(opc_athrow));
// cast argument object to this class' type and store into local var
insn = insn.append(cast);
insn = insn.append(Insn.create(opc_aload_1));
insn = insn.append(Insn.create(opc_checkcast, theClass));
insn = insn.append(Insn.create(opc_astore_3));
// iterate over all declared fields of the class
final ArrayList mscoFields = new ArrayList();
final JDOMetaData jdoMetaData = env.getJDOMetaData();
for (Iterator e = ca.fieldActions(); e.hasNext();) {
final FieldAction act = (FieldAction)e.next();
//printFieldAction(act);
//System.out.println();
// remember fields of MSCO type for later processing
if (act.isMutableSCO()) {
mscoFields.add(act);
continue;
}
// get this object
insn = insn.append(Insn.create(opc_aload_0));
// fetch arguments object's field
insn = insn.append(Insn.create(opc_aload_3));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
// store into this object's field
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
}
if (mscoFields.size() > 0) {
// test boolean argument value and clone msco fields if true
insn = insn.append(Insn.create(opc_iload_2));
InsnTarget shallow = new InsnTarget();
insn = insn.append(Insn.create(opc_ifeq, shallow));
// clone fields
for (Iterator i = mscoFields.iterator(); i.hasNext();) {
final FieldAction act = (FieldAction)i.next();
// get this object
insn = insn.append(Insn.create(opc_aload_0));
// fetch arguments object's field
insn = insn.append(Insn.create(opc_aload_3));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
// clone field value and cast to field's type
insn = insn.append(
Insn.create(opc_invokevirtual,
pool.addMethodRef(
act.typeName(),
"clone",//NOI18N
"()Ljava/lang/Object;")));//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(act.typeName())));
// store into this object's field
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
}
InsnTarget done = new InsnTarget();
insn = insn.append(Insn.create(opc_goto, done));
// copy field values
insn = insn.append(shallow);
for (Iterator i = mscoFields.iterator(); i.hasNext();) {
final FieldAction act = (FieldAction)i.next();
// get this object
insn = insn.append(Insn.create(opc_aload_0));
// fetch arguments object's field
insn = insn.append(Insn.create(opc_aload_3));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
// store into this object's field
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
}
insn = insn.append(done);
}
// end of method body
insn = insn.append(Insn.create(opc_return));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
4, // maxStack
4, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoCopyMethod;
}
*/
/**
* Build the jdoGetField method for the class.
*
* public Object jdoGetField(int fieldNumber) {
* return ...
* }
*/
//@olsen: added method for generating the jdoGetField method
ClassMethod makeJDOGetFieldMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(I)Ljava/lang/Object;";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod jdoGetFieldMethod
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// get the declared, persistent fields from the JDOMetaData
final String className = ca.className();
//@lars: changed getPersistentFields() into getManagedFields()
final String[] fieldNames
= env.getJDOMetaData().getManagedFields(className);
final int nofFields = fieldNames.length;
//@olsen: added println() for debugging
if (false) {
System.out.print("MethodBuilder.makeJDOGetFieldMethod(): "//NOI18N
+ " declared, persistent fields of class '"//NOI18N
+ className + "' = {");//NOI18N
for (int i = 0; i < nofFields; i++)
System.out.print(" " + fieldNames[i]);//NOI18N
System.out.println(" }");//NOI18N
}
// generate the switch-statement only if more than zero fields
final InsnTarget defaultOp = new InsnTarget();
if (nofFields > 0) {
// get the declared, persistent fields from the class
final HashMap fieldsByName = new HashMap();
for (Iterator e = ca.fieldActions(); e.hasNext();) {
final FieldAction act = (FieldAction)e.next();
fieldsByName.put(act.fieldName(), act);
}
// do the tableswitch on argument
insn = insn.append(Insn.create(opc_iload_1));
final int lowOp = 0;
final InsnTarget[] targetsOp = new InsnTarget[nofFields];
for (int i = 0; i < nofFields; i++)
targetsOp[i] = new InsnTarget();
insn = insn.append(
new InsnTableSwitch(lowOp, defaultOp, targetsOp));
// do the case-targets for field accesses
for (int i = 0; i < nofFields; i++) {
// target for accessing field [i]
insn = insn.append(targetsOp[i]);
final FieldAction act
= (FieldAction)fieldsByName.get(fieldNames[i]);
affirm(act,
("Field '" + fieldNames[i]//NOI18N
+ "' returned by JDOMetaData is not known by class '"//NOI18N
+ className + "'."));//NOI18N
// use the getMethodReturn type to create the wrapper object
final String wrapperClassName;
final String wrapperSignature;
switch(act.getMethodReturn()) {
case T_DOUBLE:
wrapperClassName = "java/lang/Double";//NOI18N
wrapperSignature = "(D)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_LONG:
wrapperClassName = "java/lang/Long";//NOI18N
wrapperSignature = "(J)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_FLOAT:
wrapperClassName = "java/lang/Float";//NOI18N
wrapperSignature = "(F)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_BOOLEAN:
wrapperClassName = "java/lang/Boolean";//NOI18N
wrapperSignature = "(Z)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_CHAR:
wrapperClassName = "java/lang/Character";//NOI18N
wrapperSignature = "(C)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_BYTE:
wrapperClassName = "java/lang/Byte";//NOI18N
wrapperSignature = "(B)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_SHORT:
wrapperClassName = "java/lang/Short";//NOI18N
wrapperSignature = "(S)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case T_INT:
wrapperClassName = "java/lang/Integer";//NOI18N
wrapperSignature = "(I)V";//NOI18N
insn = insn.append(
Insn.create(opc_new, pool.addClass(wrapperClassName)));
insn = insn.append(Insn.create(opc_dup));
break;
case TC_STRING:
case TC_OBJECT:
case TC_INTERFACE:
wrapperClassName = null;
wrapperSignature = null;
break;
default:
throw new InternalError("Unexpected return type");//NOI18N
}
// fetch this object's field
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(
opc_getfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
// wrap the field value if primitive
switch(act.getMethodReturn()) {
case T_DOUBLE:
case T_LONG:
case T_FLOAT:
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
case T_INT:
insn = insn.append(
Insn.create(
opc_invokespecial,
pool.addMethodRef(
wrapperClassName,
"",//NOI18N
wrapperSignature)));
break;
case TC_STRING:
case TC_OBJECT:
case TC_INTERFACE:
break;
default:
throw new InternalError("Unexpected return type");//NOI18N
}
// return the object (break)
insn = insn.append(Insn.create(opc_areturn));
}
}
// do the default branch target creating a fatal exception
insn = insn.append(defaultOp);
final String exceptionClassName
= "com/sun/jdo/api/persistence/support/JDOFatalException";//NOI18N
insn = insn.append(
Insn.create(
opc_new,
pool.addClass(exceptionClassName)));
insn = insn.append(Insn.create(opc_dup));
insn = insn.append(
Insn.create(
opc_invokespecial,
pool.addMethodRef(
exceptionClassName,
"",//NOI18N
"()V")));//NOI18N
// end of method body
insn = insn.append(Insn.create(opc_athrow));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
4, // maxStack
2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoGetFieldMethod;
}
/**
* Build the jdoSetField method for the class.
*
* public jdoSetField(int fieldNumber, Object value) {
* ...
* }
*/
//@olsen: added method for generating the jdoSetField method
ClassMethod makeJDOSetFieldMethod(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "(ILjava/lang/Object;)V";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ConstantPool pool = ca.classFile().pool();
final ConstClass theClass = ca.classFile().className();
final AttributeVector methodAttrs = new AttributeVector();
final ClassMethod jdoSetFieldMethod
= new ClassMethod(ACCPublic,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
// get the declared, persistent fields from the JDOMetaData
final String className = ca.className();
//@lars: changed getPersistentFields() into getManagedFields()
final String[] fieldNames
= env.getJDOMetaData().getManagedFields(className);
final int nofFields = fieldNames.length;
//@olsen: added println() for debugging
if (false) {
System.out.print("MethodBuilder.makeJDOSetFieldMethod(): "//NOI18N
+ " declared, persistent fields of class '"//NOI18N
+ className + "' = {");//NOI18N
for (int i = 0; i < nofFields; i++)
System.out.print(" " + fieldNames[i]);//NOI18N
System.out.println(" }");//NOI18N
}
// generate the switch-statement only if more than zero fields
final InsnTarget defaultOp = new InsnTarget();
if (nofFields > 0) {
// get the declared, persistent fields from the class
final HashMap fieldsByName = new HashMap();
for (Iterator e = ca.fieldActions(); e.hasNext();) {
final FieldAction act = (FieldAction)e.next();
fieldsByName.put(act.fieldName(), act);
}
// do the tableswitch on argument
insn = insn.append(Insn.create(opc_iload_1));
final int lowOp = 0;
final InsnTarget[] targetsOp = new InsnTarget[nofFields];
for (int i = 0; i < nofFields; i++)
targetsOp[i] = new InsnTarget();
insn = insn.append(
new InsnTableSwitch(lowOp, defaultOp, targetsOp));
// do the case-targets for field accesses
for (int i = 0; i < nofFields; i++) {
// target for accessing field [i]
insn = insn.append(targetsOp[i]);
final FieldAction act
= (FieldAction)fieldsByName.get(fieldNames[i]);
affirm(act,
("Field '"//NOI18N
+ fieldNames[i]
+ "' returned by JDOMetaData is not known by class '"//NOI18N
+ className + "'."));//NOI18N
// get object and value argument
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(Insn.create(opc_aload_2));
// use the getMethodReturn type to downcast the Object argument
final String wrapperClassName;
final String unwrapperSignature;
final String unwrapperName;
switch(act.getMethodReturn()) {
case T_DOUBLE:
wrapperClassName = "java/lang/Double";//NOI18N
unwrapperSignature = "()D";//NOI18N
unwrapperName = "doubleValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_LONG:
wrapperClassName = "java/lang/Long";//NOI18N
unwrapperSignature = "()J";//NOI18N
unwrapperName = "longValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_FLOAT:
wrapperClassName = "java/lang/Float";//NOI18N
unwrapperSignature = "()F";//NOI18N
unwrapperName = "floatValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_BOOLEAN:
wrapperClassName = "java/lang/Boolean";//NOI18N
unwrapperSignature = "()Z";//NOI18N
unwrapperName = "booleanValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_CHAR:
wrapperClassName = "java/lang/Character";//NOI18N
unwrapperSignature = "()C";//NOI18N
unwrapperName = "charValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_BYTE:
wrapperClassName = "java/lang/Byte";//NOI18N
unwrapperSignature = "()B";//NOI18N
unwrapperName = "byteValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_SHORT:
wrapperClassName = "java/lang/Short";//NOI18N
unwrapperSignature = "()S";//NOI18N
unwrapperName = "shortValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case T_INT:
wrapperClassName = "java/lang/Integer";//NOI18N
unwrapperSignature = "()I";//NOI18N
unwrapperName = "intValue";//NOI18N
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(wrapperClassName)));
break;
case TC_STRING:
case TC_OBJECT:
case TC_INTERFACE:
wrapperClassName = null;
unwrapperSignature = null;
unwrapperName = null;
insn = insn.append(
Insn.create(opc_checkcast,
pool.addClass(act.typeName())));
break;
default:
throw new InternalError("Unexpected return type");//NOI18N
}
// unwrap the object if primitive wrapper
switch(act.getMethodReturn()) {
case T_DOUBLE:
case T_LONG:
case T_FLOAT:
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
case T_INT:
insn = insn.append(
Insn.create(
opc_invokevirtual,
pool.addMethodRef(
wrapperClassName,
unwrapperName,
unwrapperSignature)));
break;
case TC_STRING:
case TC_OBJECT:
case TC_INTERFACE:
break;
default:
throw new InternalError("Unexpected return type");//NOI18N
}
// store argument value in field
insn = insn.append(
Insn.create(
opc_putfield,
pool.addFieldRef(
theClass.asString(),
act.fieldName(),
act.typeDescriptor())));
// return (break)
insn = insn.append(Insn.create(opc_return));
}
}
// do the default branch target creating a fatal exception
insn = insn.append(defaultOp);
final String exceptionClassName
= "com/sun/jdo/api/persistence/support/JDOFatalException";//NOI18N
insn = insn.append(
Insn.create(
opc_new,
pool.addClass(exceptionClassName)));
insn = insn.append(Insn.create(opc_dup));
insn = insn.append(
Insn.create(
opc_invokespecial,
pool.addMethodRef(
exceptionClassName,
"",//NOI18N
"()V")));//NOI18N
// end of method body
insn = insn.append(Insn.create(opc_athrow));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
3, // maxStack
3, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
return jdoSetFieldMethod;
}
/**
* Build the clone method for the class.
*/
//@olsen: subst: makeClone -> makeJDOClone
ClassMethod makeJDOClone(final ClassAction ca,
final String methodName) {
//@olsen: added variable
final String methodSig = "()Ljava/lang/Object;";//NOI18N
env.message("adding "//NOI18N
+ ca.classControl().userClassName() +
"." + methodName//NOI18N
+ Descriptor.userMethodArgs(methodSig));
final ClassFile cFile = ca.classFile();
final ConstantPool pool = cFile.pool();
final ConstClass theClass = cFile.className();
final ConstClass superClass = cFile.superName();
final AttributeVector methodAttrs = new AttributeVector();
//@olsen: fixed bug: changed ACCProtected to ACCPublic to allow for
// an inherited method clone() to be public!
//@olsen: removed ACCSynchronized flag
final ClassMethod cloneMethod
= new ClassMethod(ACCPublic, //|ACCSynchronized,
pool.addUtf8(methodName),
pool.addUtf8(methodSig),
methodAttrs);
// begin of method body
//@olsen: fix 4467428, made 'begin' final InsnTarget
final InsnTarget begin = new InsnTarget();
Insn insn = begin;
//@olsen: disabled feature
/*
// if (jdoFlags < 0)
// Implementation.fetch(this);
InsnTarget cloneStart = new InsnTarget();
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_getfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig)));
insn = insn.append(Insn.create(opc_ifge, cloneStart));
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_invokestatic,
pool.addMethodRef("com/sun/forte4j/persistence/internal/Implementation", "fetch",
"(" + JDOMetaData.JDOPersistenceCapableSig + ")V")));
insn = insn.append(cloneStart);
*/
// THISCLASS newObject = (THISCLASS) super.clone();
{
insn = insn.append(Insn.create(opc_aload_0));
insn = insn.append(
Insn.create(opc_invokespecial,
pool.addMethodRef(superClass.asString(),
// pool.addMethodRef("java/lang/Object",
methodName,
methodSig)));
// add cast to the appropriate type
insn = insn.append(Insn.create(opc_checkcast, theClass));
}
//@olsen: disabled feature
/*
if (ca.getNeedsJDOStateManagerMethods()) {
*/
// newObject.jdoStateManager = null;
if (false)
{
insn = insn.append(Insn.create(opc_dup));
insn = insn.append(Insn.create(opc_aconst_null));
insn = insn.append(
Insn.create(
opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOStateManagerFieldName,
JDOMetaData.JDOStateManagerFieldSig)));
}
//@olsen: disabled feature
/*
if (ca.getNeedsJDOFlagsMethods()) {
*/
// newObject.jdoFlags = 0;
if (false)
{
insn = insn.append(Insn.create(opc_dup));
insn = insn.append(Insn.create(opc_iconst_0));
insn = insn.append(
Insn.create(opc_putfield,
pool.addFieldRef(theClass.asString(),
JDOMetaData.JDOFlagsFieldName,
JDOMetaData.JDOFlagsFieldSig)));
}
// return newObject;
// end of method body
insn = insn.append(Insn.create(opc_areturn));
final AttributeVector codeSpecificAttrs = new AttributeVector();
//@olsen: fix 4467428, added dummy, non-empty line number table
if (addLineNumberTableAttr) {
codeSpecificAttrs.addElement(
new LineNumberTableAttribute(
pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
new short[]{ 0 }, new InsnTarget[]{ begin }));
}
methodAttrs.addElement(
new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
//@olsen: updated maxLocals
1, //3, //3, // maxStack
1, //2, // maxLocals
begin,
new ExceptionTable(),
codeSpecificAttrs));
//@olsen: fix 4467428, added synthetic attribute for generated method
if (addSyntheticAttr) {
methodAttrs.addElement(
new SyntheticAttribute(
pool.addUtf8(SyntheticAttribute.expectedAttrName)));
}
methodAttrs.addElement(
new ExceptionsAttribute(
pool.addUtf8(ExceptionsAttribute.expectedAttrName),
pool.addClass("java/lang/CloneNotSupportedException")));//NOI18N
return cloneMethod;
}
// for debugging
static private void printFieldAction(FieldAction act) {
System.out.println("fieldName() = " + act.fieldName());//NOI18N
System.out.println("userFieldName() = " + act.userFieldName());//NOI18N
System.out.println("typeDescriptor() = " + act.typeDescriptor());//NOI18N
System.out.println("typeName() = " + act.typeName());//NOI18N
System.out.println("fieldClassName() = " + act.fieldClassName());//NOI18N
System.out.println("isPersistent() = " + act.isPersistent());//NOI18N
System.out.println("isPrimaryKey() = " + act.isPrimaryKey());//NOI18N
System.out.println("isMutableSCO() = " + act.isMutableSCO());//NOI18N
System.out.println("isSynthetic() = " + act.isSynthetic());//NOI18N
//System.out.println("index() = " + act.index());
System.out.println("nDims() = " + act.nDims());//NOI18N
System.out.println("createMethod() = " + act.createMethod());//NOI18N
System.out.println("createMethodSig() = " + act.createMethodSig());//NOI18N
System.out.println("setMethod() = " + act.setMethod());//NOI18N
System.out.println("setMethodSig() = " + act.setMethodSig());//NOI18N
System.out.println("setMethodArg() = "//NOI18N
+ typeToString(act.setMethodArg()));
System.out.println("getMethod() = " + act.getMethod());//NOI18N
System.out.println("getMethodSig() = " + act.getMethodSig());//NOI18N
System.out.println("getMethodReturn() = "//NOI18N
+ typeToString(act.getMethodReturn()));
}
// for debugging
static private String typeToString(int val) {
switch(val) {
case T_DOUBLE:
return "T_DOUBLE";//NOI18N
case T_LONG:
return "T_LONG";//NOI18N
case T_BOOLEAN:
return "T_BOOLEAN";//NOI18N
case T_CHAR:
return "T_CHAR";//NOI18N
case T_FLOAT:
return "T_FLOAT";//NOI18N
case T_BYTE:
return "T_BYTE";//NOI18N
case T_SHORT:
return "T_SHORT";//NOI18N
case T_INT:
return "T_INT";//NOI18N
case TC_STRING:
return "TC_STRING";//NOI18N
case TC_OBJECT:
return "TC_OBJECT";//NOI18N
case TC_INTERFACE:
return "TC_INTERFACE";//NOI18N
default:
throw new InternalError("Unexpected return type");//NOI18N
}
}
}