001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: ClassGenerator.java 468649 2006-10-28 07:00:55Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.compiler.util;
023    
024    import org.apache.bcel.classfile.Method;
025    import org.apache.bcel.generic.ALOAD;
026    import org.apache.bcel.generic.ClassGen;
027    import org.apache.bcel.generic.Instruction;
028    import org.apache.xalan.xsltc.compiler.Constants;
029    import org.apache.xalan.xsltc.compiler.Parser;
030    import org.apache.xalan.xsltc.compiler.Stylesheet;
031    
032    /**
033     * The class that implements any class that inherits from 
034     * <tt>AbstractTranslet</tt>, i.e. any translet. Methods in this 
035     * class may be of the following kinds: 
036     *
037     * 1. Main method: applyTemplates, implemented by intances of 
038     * <tt>MethodGenerator</tt>.
039     *
040     * 2. Named methods: for named templates, implemented by instances 
041     * of <tt>NamedMethodGenerator</tt>.
042     *
043     * 3. Rt methods: for result tree fragments, implemented by 
044     * instances of <tt>RtMethodGenerator</tt>.
045     * @author Jacek Ambroziak
046     * @author Santiago Pericas-Geertsen
047     */
048    public class ClassGenerator extends ClassGen {
049        protected final static int TRANSLET_INDEX = 0;
050    
051        private Stylesheet _stylesheet;
052        private final Parser _parser;               // --> can be moved to XSLT
053        // a  single instance cached here
054        private final Instruction _aloadTranslet;
055        private final String _domClass;
056        private final String _domClassSig;
057        private final String _applyTemplatesSig;
058            private final String _applyTemplatesSigForImport;
059        
060        public ClassGenerator(String class_name, String super_class_name,
061                              String file_name,
062                              int access_flags, String[] interfaces,
063                              Stylesheet stylesheet) {
064            super(class_name, super_class_name, file_name,
065                  access_flags, interfaces);
066            _stylesheet = stylesheet;
067            _parser = stylesheet.getParser();
068            _aloadTranslet = new ALOAD(TRANSLET_INDEX);
069            
070            if (stylesheet.isMultiDocument()) {
071                _domClass = "org.apache.xalan.xsltc.dom.MultiDOM";
072                _domClassSig = "Lorg/apache/xalan/xsltc/dom/MultiDOM;";
073            }
074            else {
075                _domClass = "org.apache.xalan.xsltc.dom.DOMAdapter";
076                _domClassSig = "Lorg/apache/xalan/xsltc/dom/DOMAdapter;";
077            }
078            _applyTemplatesSig = "(" 
079                + Constants.DOM_INTF_SIG
080                + Constants.NODE_ITERATOR_SIG
081                + Constants.TRANSLET_OUTPUT_SIG
082                + ")V";
083    
084        _applyTemplatesSigForImport = "(" 
085            + Constants.DOM_INTF_SIG
086            + Constants.NODE_ITERATOR_SIG
087            + Constants.TRANSLET_OUTPUT_SIG
088            + Constants.NODE_FIELD_SIG
089            + ")V";  
090        }
091    
092        public final Parser getParser() {
093            return _parser;
094        }
095    
096        public final Stylesheet getStylesheet() {
097            return _stylesheet;
098        }
099    
100        /**
101         * Pretend this is the stylesheet class. Useful when compiling 
102         * references to global variables inside a predicate.
103         */
104        public final String getClassName() {
105            return _stylesheet.getClassName();
106        }
107    
108        public Instruction loadTranslet() {
109            return _aloadTranslet;
110        }
111    
112        public final String getDOMClass() {
113            return _domClass;
114        }
115    
116        public final String getDOMClassSig() {
117            return _domClassSig;
118        }
119    
120        public final String getApplyTemplatesSig() {
121            return _applyTemplatesSig;
122        }
123        
124        public final String getApplyTemplatesSigForImport() {
125        return _applyTemplatesSigForImport;
126        }
127    
128        /**
129         * Returns <tt>true</tt> or <tt>false</tt> depending on whether
130         * this class inherits from <tt>AbstractTranslet</tt> or not.
131         */
132        public boolean isExternal() {
133            return false;
134        }
135    
136        public void addMethod(MethodGenerator methodGen) {
137            Method[] methodsToAdd = methodGen.getGeneratedMethods(this);
138            for (int i = 0; i < methodsToAdd.length; i++) {
139                addMethod(methodsToAdd[i]);
140            }
141        }
142    }