/** Create a new auxillary class extending NodeSortRecord. */ private static String compileSortRecord( Vector sortObjects, ClassGenerator classGen, MethodGenerator methodGen) { final XSLTC xsltc = ((Sort) sortObjects.firstElement()).getXSLTC(); final String className = xsltc.getHelperClassName(); // This generates a new class for handling this specific sort final NodeSortRecordGenerator sortRecord = new NodeSortRecordGenerator( className, NODE_SORT_RECORD, "sort$0.java", ACC_PUBLIC | ACC_SUPER | ACC_FINAL, new String[] {}, classGen.getStylesheet()); final ConstantPoolGen cpg = sortRecord.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); // Set the name of the inner class in this sort object sort.setInnerClassName(className); 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(); sortRecord.addField( new Field( ACC_PUBLIC, cpg.addUtf8(var.getEscapedName()), cpg.addUtf8(var.getType().toSignature()), null, cpg.getConstantPool())); dups.add(varRef); } } MethodGenerator init = compileInit(sortObjects, sortRecord, cpg, className); MethodGenerator extract = compileExtract(sortObjects, sortRecord, cpg, className); sortRecord.addMethod(init); sortRecord.addMethod(extract); xsltc.dumpClass(sortRecord.getJavaClass()); return className; }
public static String compileSortRecordFactory( Vector sortObjects, ClassGenerator classGen, MethodGenerator methodGen, 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); makeNodeSortRecord.setMaxLocals(); makeNodeSortRecord.setMaxStack(); sortRecordFactory.addMethod(makeNodeSortRecord); xsltc.dumpClass(sortRecordFactory.getJavaClass()); return className; }
/** * Create a new "Filter" class implementing <code>CurrentNodeListFilter</code>. Allocate registers * for local variables and local parameters passed in the closure to test(). Notice that local * variables need to be "unboxed". */ private void compileFilter(ClassGenerator classGen, MethodGenerator methodGen) { TestGenerator testGen; LocalVariableGen local; FilterGenerator filterGen; _className = getXSLTC().getHelperClassName(); filterGen = new FilterGenerator( _className, "java.lang.Object", toString(), ACC_PUBLIC | ACC_SUPER, new String[] {CURRENT_NODE_LIST_FILTER}, classGen.getStylesheet()); final ConstantPoolGen cpg = filterGen.getConstantPool(); final int length = (_closureVars == null) ? 0 : _closureVars.size(); // Add a new instance variable for each var in closure for (int i = 0; i < length; i++) { VariableBase var = ((VariableRefBase) _closureVars.get(i)).getVariable(); filterGen.addField( new Field( ACC_PUBLIC, cpg.addUtf8(var.getEscapedName()), cpg.addUtf8(var.getType().toSignature()), null, cpg.getConstantPool())); } final InstructionList il = new InstructionList(); testGen = new TestGenerator( ACC_PUBLIC | ACC_FINAL, org.apache.bcel.generic.Type.BOOLEAN, new org.apache.bcel.generic.Type[] { org.apache.bcel.generic.Type.INT, org.apache.bcel.generic.Type.INT, org.apache.bcel.generic.Type.INT, org.apache.bcel.generic.Type.INT, Util.getJCRefType(TRANSLET_SIG), Util.getJCRefType(NODE_ITERATOR_SIG) }, new String[] {"node", "position", "last", "current", "translet", "iterator"}, "test", _className, il, cpg); // Store the dom in a local variable local = testGen.addLocalVariable("document", Util.getJCRefType(DOM_INTF_SIG), null, null); final String className = classGen.getClassName(); il.append(filterGen.loadTranslet()); il.append(new CHECKCAST(cpg.addClass(className))); il.append(new GETFIELD(cpg.addFieldref(className, DOM_FIELD, DOM_INTF_SIG))); local.setStart(il.append(new ASTORE(local.getIndex()))); // Store the dom index in the test generator testGen.setDomIndex(local.getIndex()); _exp.translate(filterGen, testGen); il.append(IRETURN); filterGen.addEmptyConstructor(ACC_PUBLIC); filterGen.addMethod(testGen); getXSLTC().dumpClass(filterGen.getJavaClass()); }