1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xalan.internal.xsltc.compiler;
  22 
  23 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  24 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
  25 import com.sun.org.apache.bcel.internal.generic.InstructionList;
  26 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
  28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  31 import java.util.ArrayList;
  32 import java.util.List;
  33 import java.util.StringTokenizer;
  34 
  35 /**
  36  * @author Jacek Ambroziak
  37  * @author Santiago Pericas-Geertsen
  38  * @author Morten Jorgensen
  39  * @LastModified: Oct 2017
  40  */
  41 final class UseAttributeSets extends Instruction {
  42 
  43     // Only error that can occur:
  44     private final static String ATTR_SET_NOT_FOUND =
  45         "";
  46 
  47     // Contains the names of all references attribute sets
  48     private final List<QName> _sets = new ArrayList<>(2);
  49 
  50     /**
  51      * Constructur - define initial attribute sets to use
  52      */
  53     public UseAttributeSets(String setNames, Parser parser) {
  54         setParser(parser);
  55         addAttributeSets(setNames);
  56     }
  57 
  58     /**
  59      * This method is made public to enable an AttributeSet object to merge
  60      * itself with another AttributeSet (including any other AttributeSets
  61      * the two may inherit from).
  62      */
  63     public void addAttributeSets(String setNames) {
  64         if ((setNames != null) && (!setNames.equals(Constants.EMPTYSTRING))) {
  65             final StringTokenizer tokens = new StringTokenizer(setNames);
  66             while (tokens.hasMoreTokens()) {
  67                 final QName qname =
  68                     getParser().getQNameIgnoreDefaultNs(tokens.nextToken());
  69                 _sets.add(qname);
  70             }
  71         }
  72     }
  73 
  74     /**
  75      * Do nada.
  76      */
  77     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  78         return Type.Void;
  79     }
  80 
  81     /**
  82      * Generate a call to the method compiled for this attribute set
  83      */
  84     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  85 
  86         final ConstantPoolGen cpg = classGen.getConstantPool();
  87         final InstructionList il = methodGen.getInstructionList();
  88         final SymbolTable symbolTable = getParser().getSymbolTable();
  89 
  90         for (QName name : _sets) {
  91             // Get the AttributeSet reference from the symbol table
  92             final AttributeSet attrs = symbolTable.lookupAttributeSet(name);
  93             // Compile the call to the set's method if the set exists
  94             if (attrs != null) {
  95                 final String methodName = attrs.getMethodName();
  96                 il.append(classGen.loadTranslet());
  97                 il.append(methodGen.loadDOM());
  98                 il.append(methodGen.loadIterator());
  99                 il.append(methodGen.loadHandler());
 100                 il.append(methodGen.loadCurrentNode());
 101                 final int method = cpg.addMethodref(classGen.getClassName(),
 102                         methodName, ATTR_SET_SIG);
 103                 il.append(new INVOKESPECIAL(method));
 104             }
 105             // Generate an error if the attribute set does not exist
 106             else {
 107                 final Parser parser = getParser();
 108                 final String atrs = name.toString();
 109                 reportError(this, parser, ErrorMsg.ATTRIBSET_UNDEF_ERR, atrs);
 110             }
 111         }
 112     }
 113 }