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 + -
显示快捷键?