stylesheet.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,413 行 · 第 1/4 页
JAVA
1,413 行
//_templates.addElement(template); getMode(template.getModeName()).addTemplate(template); } // xsl:attribute-set else if (element instanceof AttributeSet) { ((AttributeSet)element).translate(classGen, null); } else if (element instanceof Output) { // save the element for later to pass to compileConstructor Output output = (Output)element; if (output.enabled()) _lastOutputElement = output; } else { // Global variables and parameters are handled elsewhere. // Other top-level non-template elements are ignored. Literal // elements outside of templates will never be output. } } checkOutputMethod(); processModes(); compileModes(classGen); compileStaticInitializer(classGen); compileConstructor(classGen, _lastOutputElement); if (!getParser().errorsFound()) { getXSLTC().dumpClass(classGen.getJavaClass()); } } /** * Compile the namesArray, urisArray and typesArray into * the static initializer. They are read-only from the * translet. All translet instances can share a single * copy of this informtion. */ private void compileStaticInitializer(ClassGenerator classGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = new InstructionList(); final MethodGenerator staticConst = new MethodGenerator(ACC_PUBLIC|ACC_STATIC, com.sun.org.apache.bcel.internal.generic.Type.VOID, null, null, "<clinit>", _className, il, cpg); addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); // Create fields of type char[] that will contain literal text from // the stylesheet. final int charDataFieldCount = getXSLTC().getCharacterDataCount(); for (int i = 0; i < charDataFieldCount; i++) { addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, STATIC_CHAR_DATA_FIELD+i); } // Put the names array into the translet - used for dom/translet mapping final Vector namesIndex = getXSLTC().getNamesIndex(); int size = namesIndex.size(); String[] namesArray = new String[size]; String[] urisArray = new String[size]; int[] typesArray = new int[size]; int index; for (int i = 0; i < size; i++) { String encodedName = (String)namesIndex.elementAt(i); if ((index = encodedName.lastIndexOf(':')) > -1) { urisArray[i] = encodedName.substring(0, index); } index = index + 1; if (encodedName.charAt(index) == '@') { typesArray[i] = DTM.ATTRIBUTE_NODE; index++; } else if (encodedName.charAt(index) == '?') { typesArray[i] = DTM.NAMESPACE_NODE; index++; } else { typesArray[i] = DTM.ELEMENT_NODE; } if (index == 0) { namesArray[i] = encodedName; } else { namesArray[i] = encodedName.substring(index); } } il.append(new PUSH(cpg, size)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int i = 0; i < size; i++) { final String name = namesArray[i]; il.append(DUP); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, name)); il.append(AASTORE); } il.append(new PUTSTATIC(cpg.addFieldref(_className, STATIC_NAMES_ARRAY_FIELD, NAMES_INDEX_SIG))); il.append(new PUSH(cpg, size)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int i = 0; i < size; i++) { final String uri = urisArray[i]; il.append(DUP); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, uri)); il.append(AASTORE); } il.append(new PUTSTATIC(cpg.addFieldref(_className, STATIC_URIS_ARRAY_FIELD, URIS_INDEX_SIG))); il.append(new PUSH(cpg, size)); il.append(new NEWARRAY(BasicType.INT)); for (int i = 0; i < size; i++) { final int nodeType = typesArray[i]; il.append(DUP); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, nodeType)); il.append(IASTORE); } il.append(new PUTSTATIC(cpg.addFieldref(_className, STATIC_TYPES_ARRAY_FIELD, TYPES_INDEX_SIG))); // Put the namespace names array into the translet final Vector namespaces = getXSLTC().getNamespaceIndex(); il.append(new PUSH(cpg, namespaces.size())); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int i = 0; i < namespaces.size(); i++) { final String ns = (String)namespaces.elementAt(i); il.append(DUP); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, ns)); il.append(AASTORE); } il.append(new PUTSTATIC(cpg.addFieldref(_className, STATIC_NAMESPACE_ARRAY_FIELD, NAMESPACE_INDEX_SIG))); // Grab all the literal text in the stylesheet and put it in a char[] final int charDataCount = getXSLTC().getCharacterDataCount(); final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); for (int i = 0; i < charDataCount; i++) { il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); il.append(new INVOKEVIRTUAL(toCharArray)); il.append(new PUTSTATIC(cpg.addFieldref(_className, STATIC_CHAR_DATA_FIELD+i, STATIC_CHAR_DATA_FIELD_SIG))); } il.append(RETURN); staticConst.stripAttributes(true); staticConst.setMaxLocals(); staticConst.setMaxStack(); classGen.addMethod(staticConst.getMethod()); } /** * Compile the translet's constructor */ private void compileConstructor(ClassGenerator classGen, Output output) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = new InstructionList(); final MethodGenerator constructor = new MethodGenerator(ACC_PUBLIC, com.sun.org.apache.bcel.internal.generic.Type.VOID, null, null, "<init>", _className, il, cpg); // Call the constructor in the AbstractTranslet superclass il.append(classGen.loadTranslet()); il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, "<init>", "()V"))); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_NAMES_ARRAY_FIELD, NAMES_INDEX_SIG))); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, NAMES_INDEX, NAMES_INDEX_SIG))); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_URIS_ARRAY_FIELD, URIS_INDEX_SIG))); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, URIS_INDEX, URIS_INDEX_SIG))); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_TYPES_ARRAY_FIELD, TYPES_INDEX_SIG))); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, TYPES_INDEX, TYPES_INDEX_SIG))); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_NAMESPACE_ARRAY_FIELD, NAMESPACE_INDEX_SIG))); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, NAMESPACE_INDEX, NAMESPACE_INDEX_SIG))); il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, TRANSLET_VERSION_INDEX, TRANSLET_VERSION_INDEX_SIG))); if (_hasIdCall) { il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, Boolean.TRUE)); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, HASIDCALL_INDEX, HASIDCALL_INDEX_SIG))); } // Compile in code to set the output configuration from <xsl:output> if (output != null) { // Set all the output settings files in the translet output.translate(classGen, constructor); } // Compile default decimal formatting symbols. // This is an implicit, nameless xsl:decimal-format top-level element. if (_numberFormattingUsed) DecimalFormatting.translateDefaultDFS(classGen, constructor); il.append(RETURN); constructor.stripAttributes(true); constructor.setMaxLocals(); constructor.setMaxStack(); classGen.addMethod(constructor.getMethod()); } /** * Compile a topLevel() method into the output class. This method is * called from transform() to handle all non-template top-level elements. * Returns the signature of the topLevel() method. * * Global variables/params and keys are first sorted to resolve * dependencies between them. The XSLT 1.0 spec does not allow a key * to depend on a variable. However, for compatibility with Xalan * interpretive, that type of dependency is allowed. Note also that * the buildKeys() method is still generated as it is used by the * LoadDocument class, but it no longer called from transform(). */ private String compileTopLevel(ClassGenerator classGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = { Util.getJCRefType(DOM_INTF_SIG), Util.getJCRefType(NODE_ITERATOR_SIG), Util.getJCRefType(TRANSLET_OUTPUT_SIG) }; final String[] argNames = { DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME }; final InstructionList il = new InstructionList(); final MethodGenerator toplevel = new MethodGenerator(ACC_PUBLIC, com.sun.org.apache.bcel.internal.generic.Type.VOID, argTypes, argNames, "topLevel", _className, il, classGen.getConstantPool()); toplevel.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); // Define and initialize 'current' variable with the root node final LocalVariableGen current = toplevel.addLocalVariable("current", com.sun.org.apache.bcel.internal.generic.Type.INT, il.getEnd(), null); final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, "setFilter", "(Lcom/sun/org/apache/xalan/internal/xsltc/StripFilter;)V"); il.append(new PUSH(cpg, DTM.ROOT_NODE)); il.append(new ISTORE(current.getIndex())); // Create a new list containing variables/params + keys Vector varDepElements = new Vector(_globals); Enumeration elements = elements(); while (elements.hasMoreElements()) { final Object element = elements.nextElement(); if (element instanceof Key) { varDepElements.add(element); } } // Determine a partial order for the variables/params and keys varDepElements = resolveDependencies(varDepElements); // Translate vars/params and keys in the right order final int count = varDepElements.size(); for (int i = 0; i < count; i++) { final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i); tle.translate(classGen, toplevel); if (tle instanceof Key) { final Key key = (Key) tle; _keys.put(key.getName(), key); } } // Compile code for other top-level elements Vector whitespaceRules = new Vector(); elements = elements(); while (elements.hasMoreElements()) { final Object element = elements.nextElement(); // xsl:decimal-format if (element instanceof DecimalFormatting) { ((DecimalFormatting)element).translate(classGen,toplevel); } // xsl:strip/preserve-space else if (element instanceof Whitespace) { whitespaceRules.addAll(((Whitespace)element).getRules()); } } // Translate all whitespace strip/preserve rules if (whitespaceRules.size() > 0) { Whitespace.translateRules(whitespaceRules,classGen); } if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { il.append(toplevel.loadDOM()); il.append(classGen.loadTranslet()); il.append(new INVOKEINTERFACE(setFilter, 2)); } il.append(RETURN);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?