📄 sort.java
字号:
il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int level = 0; level < nsorts; level++) { final Sort sort = (Sort)sortObjects.elementAt(level); il.append(DUP); il.append(new PUSH(cpg, level)); sort.translateLang(classGen, methodGen); il.append(AASTORE); } il.append(new ASTORE(sortLangTemp.getIndex())); LocalVariableGen sortCaseOrderTemp = methodGen.addLocalVariable("sort_case_order_tmp", Util.getJCRefType("[" + STRING_SIG), il.getEnd(), null); il.append(new PUSH(cpg, nsorts)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int level = 0; level < nsorts; level++) { final Sort sort = (Sort)sortObjects.elementAt(level); il.append(DUP); il.append(new PUSH(cpg, level)); sort.translateCaseOrder(classGen, methodGen); il.append(AASTORE); } il.append(new ASTORE(sortCaseOrderTemp.getIndex())); il.append(new NEW(cpg.addClass(sortRecordFactoryClass))); il.append(DUP); il.append(methodGen.loadDOM()); il.append(new PUSH(cpg, sortRecordClass)); il.append(classGen.loadTranslet()); il.append(new ALOAD(sortOrderTemp.getIndex())); il.append(new ALOAD(sortTypeTemp.getIndex())); il.append(new ALOAD(sortLangTemp.getIndex())); il.append(new ALOAD(sortCaseOrderTemp.getIndex())); il.append(new INVOKESPECIAL( cpg.addMethodref(sortRecordFactoryClass, "<init>", "(" + DOM_INTF_SIG + STRING_SIG + TRANSLET_INTF_SIG + "[" + STRING_SIG + "[" + STRING_SIG + "[" + STRING_SIG + "[" + STRING_SIG + ")V"))); // Initialize closure variables in sortRecordFactory 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++) { VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i); // Discard duplicate variable references if (dups.contains(varRef)) continue; final VariableBase var = varRef.getVariable(); // Store variable in new closure il.append(DUP); il.append(var.loadInstruction()); il.append(new PUTFIELD( cpg.addFieldref(sortRecordFactoryClass, var.getEscapedName(), var.getType().toSignature()))); dups.add(varRef); } } } 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 com.sun.org.apache.bcel.internal.generic.Type[] argTypes = new com.sun.org.apache.bcel.internal.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, com.sun.org.apache.bcel.internal.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 com.sun.org.apache.bcel.internal.generic.Type[] { com.sun.org.apache.bcel.internal.generic.Type.INT, com.sun.org.apache.bcel.internal.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; } /** * 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); } } Method init = compileInit(sortObjects, sortRecord, cpg, className); Method extract = compileExtract(sortObjects, sortRecord, cpg, className); sortRecord.addMethod(init); sortRecord.addMethod(extract); xsltc.dumpClass(sortRecord.getJavaClass()); return className; } /** * Create a constructor for the new class. Updates the reference to the * collator in the super calls only when the stylesheet specifies a new * language in xsl:sort. */ private static Method compileInit(Vector sortObjects, NodeSortRecordGenerator sortRecord, ConstantPoolGen cpg, String className) { final InstructionList il = new InstructionList(); final MethodGenerator init = new MethodGenerator(ACC_PUBLIC, com.sun.org.apache.bcel.internal.generic.Type.VOID, null, null, "<init>", className, il, cpg); // Call the constructor in the NodeSortRecord superclass il.append(ALOAD_0); il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_RECORD, "<init>", "()V"))); il.append(RETURN); init.stripAttributes(true); init.setMaxLocals(); init.setMaxStack(); return init.getMethod(); } /** * Compiles a method that overloads NodeSortRecord.extractValueFromDOM() */ private static Method compileExtract(Vector sortObjects, NodeSortRecordGenerator sortRecord, ConstantPoolGen cpg, String className) { final InstructionList il = new InstructionList(); // String NodeSortRecord.extractValueFromDOM(dom,node,level); final CompareGenerator extractMethod = new CompareGenerator(ACC_PUBLIC | ACC_FINAL, com.sun.org.apache.bcel.internal.generic.Type.STRING, new com.sun.org.apache.bcel.internal.generic.Type[] { Util.getJCRefType(DOM_INTF_SIG), com.sun.org.apache.bcel.internal.generic.Type.INT, com.sun.org.apache.bcel.internal.generic.Type.INT, Util.getJCRefType(TRANSLET_SIG), com.sun.org.apache.bcel.internal.generic.Type.INT }, new String[] { "dom", "current", "level", "translet", "last" }, "extractValueFromDOM", className, il, cpg); // Values needed for the switch statement final int levels = sortObjects.size(); final int match[] = new int[levels]; final InstructionHandle target[] = new InstructionHandle[levels]; InstructionHandle tblswitch = null; // Compile switch statement only if the key has multiple levels if (levels > 1) { // Put the parameter to the swtich statement on the stack il.append(new ILOAD(extractMethod.getLocalIndex("level"))); // Append the switch statement here later on tblswitch = il.append(new NOP()); } // Append all the cases for the switch statment for (int level = 0; level < levels; level++) { match[level] = level; final Sort sort = (Sort)sortObjects.elementAt(level); target[level] = il.append(NOP); sort.translateSelect(sortRecord, extractMethod); il.append(ARETURN); } // Compile def. target for switch statement if key has multiple levels if (levels > 1) { // Append the default target - it will _NEVER_ be reached InstructionHandle defaultTarget = il.append(new PUSH(cpg, EMPTYSTRING)); il.insert(tblswitch,new TABLESWITCH(match, target, defaultTarget)); il.append(ARETURN); } extractMethod.stripAttributes(true); extractMethod.setMaxLocals(); extractMethod.setMaxStack(); extractMethod.removeNOPs(); return extractMethod.getMethod(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -