String sortRecordClass)
{
final XSLTC xsltc = ((Sort)sortObjects.firstElement()).getXSLTC();
final String className = xsltc.getHelperClassName();
final NodeSortRecordFactGenerator sortRecordFactory =
new NodeSortRecordFactGenerator(className,
NODE_SORT_FACTORY,
className + ".java",
ACC_PUBLIC | ACC_SUPER | ACC_FINAL,
new String[] {},
classGen.getStylesheet());
ConstantPoolGen cpg = sortRecordFactory.getConstantPool();
// Add a new instance variable for each var in closure
final int nsorts = sortObjects.size();
final ArrayList dups = new ArrayList();
for (int j = 0; j < nsorts; j++) {
final Sort sort = (Sort) sortObjects.get(j);
final int length = (sort._closureVars == null) ? 0 :
sort._closureVars.size();
for (int i = 0; i < length; i++) {
final VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i);
// Discard duplicate variable references
if (dups.contains(varRef)) continue;
final VariableBase var = varRef.getVariable();
sortRecordFactory.addField(new Field(ACC_PUBLIC,
cpg.addUtf8(var.getEscapedName()),
cpg.addUtf8(var.getType().toSignature()),
null, cpg.getConstantPool()));
dups.add(varRef);
}
}
// Define a constructor for this class
final org.apache.bcel.generic.Type[] argTypes =
new org.apache.bcel.generic.Type[7];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
argTypes[1] = Util.getJCRefType(STRING_SIG);
argTypes[2] = Util.getJCRefType(TRANSLET_INTF_SIG);
argTypes[3] = Util.getJCRefType("[" + STRING_SIG);
argTypes[4] = Util.getJCRefType("[" + STRING_SIG);
argTypes[5] = Util.getJCRefType("[" + STRING_SIG);
argTypes[6] = Util.getJCRefType("[" + STRING_SIG);
final String[] argNames = new String[7];
argNames[0] = DOCUMENT_PNAME;
argNames[1] = "className";
argNames[2] = TRANSLET_PNAME;
argNames[3] = "order";
argNames[4] = "type";
argNames[5] = "lang";
argNames[6] = "case_order";
InstructionList il = new InstructionList();
final MethodGenerator constructor =
new MethodGenerator(ACC_PUBLIC,
org.apache.bcel.generic.Type.VOID,
argTypes, argNames, "<init>",
className, il, cpg);
// Push all parameters onto the stack and called super.<init>()
il.append(ALOAD_0);
il.append(ALOAD_1);
il.append(ALOAD_2);
il.append(new ALOAD(3));
il.append(new ALOAD(4));
il.append(new ALOAD(5));
il.append(new ALOAD(6));
il.append(new ALOAD(7));
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
"<init>",
"(" + DOM_INTF_SIG
+ STRING_SIG
+ TRANSLET_INTF_SIG
+ "[" + STRING_SIG
+ "[" + STRING_SIG
+ "[" + STRING_SIG
+ "[" + STRING_SIG + ")V")));
il.append(RETURN);
// Override the definition of makeNodeSortRecord()
il = new InstructionList();
final MethodGenerator makeNodeSortRecord =
new MethodGenerator(ACC_PUBLIC,
Util.getJCRefType(NODE_SORT_RECORD_SIG),
new org.apache.bcel.generic.Type[] {
org.apache.bcel.generic.Type.INT,
org.apache.bcel.generic.Type.INT },
new String[] { "node", "last" }, "makeNodeSortRecord",
className, il, cpg);
il.append(ALOAD_0);
il.append(ILOAD_1);
il.append(ILOAD_2);
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
"makeNodeSortRecord", "(II)" + NODE_SORT_RECORD_SIG)));
il.append(DUP);
il.append(new CHECKCAST(cpg.addClass(sortRecordClass)));
// Initialize closure in record class
final int ndups = dups.size();
for (int i = 0; i < ndups; i++) {
final VariableRefBase varRef = (VariableRefBase) dups.get(i);
final VariableBase var = varRef.getVariable();
final Type varType = var.getType();
il.append(DUP);
// Get field from factory class
il.append(ALOAD_0);
il.append(new GETFIELD(
cpg.addFieldref(className,
var.getEscapedName(), varType.toSignature())));
// Put field in record class
il.append(new PUTFIELD(
cpg.addFieldref(sortRecordClass,
var.getEscapedName(), varType.toSignature())));
}
il.append(POP);
il.append(ARETURN);
constructor.setMaxLocals();
constructor.setMaxStack();
sortRecordFactory.addMethod(constructor.getMethod());
makeNodeSortRecord.setMaxLocals();
makeNodeSortRecord.setMaxStack();
sortRecordFactory.addMethod(makeNodeSortRecord.getMethod());
xsltc.dumpClass(sortRecordFactory.getJavaClass());
return className;
}