stylesheet.java

来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,413 行 · 第 1/4 页

JAVA
1,413
字号
        // Compute max locals + stack and add method to class        toplevel.stripAttributes(true);        toplevel.setMaxLocals();        toplevel.setMaxStack();        toplevel.removeNOPs();        classGen.addMethod(toplevel.getMethod());                return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V");    }    /**     * This method returns a vector with variables/params and keys in the      * order in which they are to be compiled for initialization. The order     * is determined by analyzing the 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 and, therefore, consider to determine the partial order.     */    private Vector resolveDependencies(Vector input) {      /* DEBUG CODE IGNORE       for (int i = 0; i < input.size(); i++) {          final TopLevelElement e = (TopLevelElement) input.elementAt(i);          System.out.println("e = " + e + " depends on:");          Vector dep = e.getDependencies();          for (int j = 0; j < (dep != null ? dep.size() : 0); j++) {              System.out.println("\t" + dep.elementAt(j));          }      }      System.out.println("=================================");      */         Vector result = new Vector();        while (input.size() > 0) {            boolean changed = false;            for (int i = 0; i < input.size(); ) {                final TopLevelElement vde = (TopLevelElement) input.elementAt(i);                final Vector dep = vde.getDependencies();                if (dep == null || result.containsAll(dep)) {                    result.addElement(vde);                     input.remove(i);                    changed = true;                }                else {                    i++;                }            }            // If nothing was changed in this pass then we have a circular ref            if (!changed) {                ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR,                                            input.toString(), this);                getParser().reportError(Constants.ERROR, err);                return(result);            }        }        /* DEBUG CODE - INGORE        System.out.println("=================================");        for (int i = 0; i < result.size(); i++) {            TopLevelElement e = (TopLevelElement) result.elementAt(i);            System.out.println("e = " + e);        }        */        return result;    }    /**     * Compile a buildKeys() method into the output class. Note that keys      * for the input document are created in topLevel(), not in this method.      * However, we still need this method to create keys for documents loaded     * via the XPath document() function.      */    private String compileBuildKeys(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),            com.sun.org.apache.bcel.internal.generic.Type.INT        };        final String[] argNames = {            DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME, "current"        };        final InstructionList il = new InstructionList();        final MethodGenerator buildKeys =            new MethodGenerator(ACC_PUBLIC,                                com.sun.org.apache.bcel.internal.generic.Type.VOID,                                argTypes, argNames,                                "buildKeys", _className, il,                                classGen.getConstantPool());        buildKeys.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");                final Enumeration elements = elements();        while (elements.hasMoreElements()) {            // xsl:key            final Object element = elements.nextElement();            if (element instanceof Key) {                final Key key = (Key)element;                key.translate(classGen, buildKeys);                _keys.put(key.getName(),key);            }        }                il.append(RETURN);                // Compute max locals + stack and add method to class        buildKeys.stripAttributes(true);        buildKeys.setMaxLocals();        buildKeys.setMaxStack();        buildKeys.removeNOPs();        classGen.addMethod(buildKeys.getMethod());                return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V");    }    /**     * Compile transform() into the output class. This method is used to      * initialize global variables and global parameters. The current node     * is set to be the document's root node.     */    private void compileTransform(ClassGenerator classGen) {        final ConstantPoolGen cpg = classGen.getConstantPool();        /*          * Define the the method transform with the following signature:         * void transform(DOM, NodeIterator, HandlerBase)         */        final com.sun.org.apache.bcel.internal.generic.Type[] argTypes =             new com.sun.org.apache.bcel.internal.generic.Type[3];        argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);        argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG);        argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG);        final String[] argNames = new String[3];        argNames[0] = DOCUMENT_PNAME;        argNames[1] = ITERATOR_PNAME;        argNames[2] = TRANSLET_OUTPUT_PNAME;        final InstructionList il = new InstructionList();        final MethodGenerator transf =            new MethodGenerator(ACC_PUBLIC,                                com.sun.org.apache.bcel.internal.generic.Type.VOID,                                argTypes, argNames,                                "transform",                                _className,                                il,                                classGen.getConstantPool());        transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");        // Define and initialize current with the root node        final LocalVariableGen current =             transf.addLocalVariable("current",                                    com.sun.org.apache.bcel.internal.generic.Type.INT,                                    il.getEnd(), null);        final String applyTemplatesSig = classGen.getApplyTemplatesSig();        final int applyTemplates = cpg.addMethodref(getClassName(),                                                    "applyTemplates",                                                    applyTemplatesSig);        final int domField = cpg.addFieldref(getClassName(),                                             DOM_FIELD,                                             DOM_INTF_SIG);        // push translet for PUTFIELD        il.append(classGen.loadTranslet());        // prepare appropriate DOM implementation                if (isMultiDocument()) {            il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS)));            il.append(DUP);        }                il.append(classGen.loadTranslet());        il.append(transf.loadDOM());        il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,                                                     "makeDOMAdapter",                                                     "("+DOM_INTF_SIG+")"+                                                     DOM_ADAPTER_SIG)));        // DOMAdapter is on the stack        if (isMultiDocument()) {            final int init = cpg.addMethodref(MULTI_DOM_CLASS,                                              "<init>",                                              "("+DOM_INTF_SIG+")V");            il.append(new INVOKESPECIAL(init));            // MultiDOM is on the stack        }                //store to _dom variable        il.append(new PUTFIELD(domField));        // continue with globals initialization        il.append(new PUSH(cpg, DTM.ROOT_NODE));        il.append(new ISTORE(current.getIndex()));        // Transfer the output settings to the output post-processor        il.append(classGen.loadTranslet());        il.append(transf.loadHandler());        final int index = cpg.addMethodref(TRANSLET_CLASS,                                           "transferOutputSettings",                                           "("+OUTPUT_HANDLER_SIG+")V");        il.append(new INVOKEVIRTUAL(index));        /*         * Compile buildKeys() method. Note that this method is not         * invoked here as keys for the input document are now created         * in topLevel(). However, this method is still needed by the         * LoadDocument class.         */        final String keySig = compileBuildKeys(classGen);        final int keyIdx = cpg.addMethodref(getClassName(),                                               "buildKeys", keySig);        // Look for top-level elements that need handling        final Enumeration toplevel = elements();        if (_globals.size() > 0 || toplevel.hasMoreElements()) {             // Compile method for handling top-level elements            final String topLevelSig = compileTopLevel(classGen);            // Get a reference to that method            final int topLevelIdx = cpg.addMethodref(getClassName(),                                                     "topLevel",                                                     topLevelSig);            // Push all parameters on the stack and call topLevel()            il.append(classGen.loadTranslet()); // The 'this' pointer            il.append(classGen.loadTranslet());            il.append(new GETFIELD(domField));  // The DOM reference            il.append(transf.loadIterator());            il.append(transf.loadHandler());    // The output handler            il.append(new INVOKEVIRTUAL(topLevelIdx));        }                // start document        il.append(transf.loadHandler());        il.append(transf.startDocument());        // push first arg for applyTemplates        il.append(classGen.loadTranslet());        // push translet for GETFIELD to get DOM arg        il.append(classGen.loadTranslet());        il.append(new GETFIELD(domField));        // push remaining 2 args        il.append(transf.loadIterator());        il.append(transf.loadHandler());        il.append(new INVOKEVIRTUAL(applyTemplates));        // endDocument        il.append(transf.loadHandler());        il.append(transf.endDocument());        il.append(RETURN);        // Compute max locals + stack and add method to class        transf.stripAttributes(true);        transf.setMaxLocals();        transf.setMaxStack();        transf.removeNOPs();        classGen.addMethod(transf.getMethod());    }    /**     * Peephole optimization: Remove sequences of [ALOAD, POP].     */    private void peepHoleOptimization(MethodGenerator methodGen) {        final String pattern = "`aload'`pop'`instruction'";        final InstructionList il = methodGen.getInstructionList();        final InstructionFinder find = new InstructionFinder(il);        for(Iterator iter=find.search(pattern); iter.hasNext(); ) {            InstructionHandle[] match = (InstructionHandle[])iter.next();            try {                il.delete(match[0], match[1]);            }             catch (TargetLostException e) {                // TODO: move target down into the list            }        }    }    public int addParam(Param param) {        _globals.addElement(param);        return _globals.size() - 1;    }    public int addVariable(Variable global) {        _globals.addElement(global);        return _globals.size() - 1;    }    public void display(int indent) {        indent(indent);        Util.println("Stylesheet");        displayContents(indent + IndentIncrement);    }    // do we need this wrapper ?????    public String getNamespace(String prefix) {        return lookupNamespace(prefix);    }    public String getClassName() {        return _className;    }    public Vector getTemplates() {        return _templates;    }    public Vector getAllValidTemplates() {        // Return templates if no imported/included stylesheets        if (_includedStylesheets == null) {            return _templates;        }                // Is returned value cached?        if (_allValidTemplates == null) {            Vector templates = new Vector();             templates.addAll(templates);            int size = _includedStylesheets.size();            for (int i = 0; i < size; i++) {                Stylesheet included =(Stylesheet)_includedStylesheets.elementAt(i);                templates.addAll(included.getAllValidTemplates());            }            // templates.addAll(_templates);            // Cache results in top-level stylesheet only            if (_parentStylesheet != null) {                return templates;            }            _allValidTemplates = templates;         }                return _allValidTemplates;    }        protected void addTemplate(Template template) {        _templates.addElement(template);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?