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 }