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: UseAttributeSets.java 468650 2006-10-28 07:03:30Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.compiler;
023    
024    import java.util.StringTokenizer;
025    import java.util.Vector;
026    
027    import org.apache.bcel.generic.ConstantPoolGen;
028    import org.apache.bcel.generic.INVOKESPECIAL;
029    import org.apache.bcel.generic.InstructionList;
030    import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
031    import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
032    import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
033    import org.apache.xalan.xsltc.compiler.util.Type;
034    import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
035    
036    /**
037     * @author Jacek Ambroziak
038     * @author Santiago Pericas-Geertsen
039     * @author Morten Jorgensen
040     */
041    final class UseAttributeSets extends Instruction {
042    
043        // Only error that can occur:
044        private final static String ATTR_SET_NOT_FOUND =
045            "";
046    
047        // Contains the names of all references attribute sets
048        private final Vector _sets = new Vector(2);
049    
050        /**
051         * Constructur - define initial attribute sets to use
052         */
053        public UseAttributeSets(String setNames, Parser parser) {
054            setParser(parser);
055            addAttributeSets(setNames);
056        }
057    
058        /**
059         * This method is made public to enable an AttributeSet object to merge
060         * itself with another AttributeSet (including any other AttributeSets
061         * the two may inherit from).
062         */
063        public void addAttributeSets(String setNames) {
064            if ((setNames != null) && (!setNames.equals(Constants.EMPTYSTRING))) {
065                final StringTokenizer tokens = new StringTokenizer(setNames);
066                while (tokens.hasMoreTokens()) {
067                    final QName qname = 
068                        getParser().getQNameIgnoreDefaultNs(tokens.nextToken());
069                    _sets.add(qname);
070                }
071            }
072        }
073    
074        /**
075         * Do nada.
076         */
077        public Type typeCheck(SymbolTable stable) throws TypeCheckError {
078            return Type.Void;
079        }
080    
081        /**
082         * Generate a call to the method compiled for this attribute set
083         */
084        public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
085    
086            final ConstantPoolGen cpg = classGen.getConstantPool();
087            final InstructionList il = methodGen.getInstructionList();
088            final SymbolTable symbolTable = getParser().getSymbolTable();
089    
090            // Go through each attribute set and generate a method call
091            for (int i=0; i<_sets.size(); i++) {
092                // Get the attribute set name
093                final QName name = (QName)_sets.elementAt(i);
094                // Get the AttributeSet reference from the symbol table
095                final AttributeSet attrs = symbolTable.lookupAttributeSet(name);
096                // Compile the call to the set's method if the set exists
097                if (attrs != null) {
098                    final String methodName = attrs.getMethodName();
099                    il.append(classGen.loadTranslet());
100                    il.append(methodGen.loadDOM());
101                    il.append(methodGen.loadIterator());
102                    il.append(methodGen.loadHandler());
103                    final int method = cpg.addMethodref(classGen.getClassName(),
104                                                        methodName, ATTR_SET_SIG);
105                    il.append(new INVOKESPECIAL(method));
106                }
107                // Generate an error if the attribute set does not exist
108                else {
109                    final Parser parser = getParser();
110                    final String atrs = name.toString();
111                    reportError(this, parser, ErrorMsg.ATTRIBSET_UNDEF_ERR, atrs);
112                }
113            }
114        }
115    }