1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.xalan.internal.xsltc.compiler; 23 24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 25 import com.sun.org.apache.bcel.internal.generic.InstructionList; 26 import com.sun.org.apache.bcel.internal.generic.PUSH; 27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 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 com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 32 33 import com.sun.org.apache.xml.internal.serializer.ElemDesc; 34 import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 35 36 /** 37 * @author Jacek Ambroziak 38 * @author Santiago Pericas-Geertsen 39 * @author Morten Jorgensen 40 */ 41 final class LiteralAttribute extends Instruction { 42 43 private final String _name; // Attribute name (incl. prefix) 44 private final AttributeValue _value; // Attribute value 45 46 /** 47 * Creates a new literal attribute (but does not insert it into the AST). 48 * @param name the attribute name (incl. prefix) as a String. 49 * @param value the attribute value. 50 * @param parser the XSLT parser (wraps XPath parser). 51 */ 52 public LiteralAttribute(String name, String value, Parser parser, 53 SyntaxTreeNode parent) 54 { 55 _name = name; 56 setParent(parent); 57 _value = AttributeValue.create(this, value, parser); 58 } 59 60 public void display(int indent) { 61 indent(indent); 62 Util.println("LiteralAttribute name=" + _name + " value=" + _value); 63 } 64 65 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 66 _value.typeCheck(stable); 67 typeCheckContents(stable); 68 return Type.Void; 69 } 70 71 protected boolean contextDependent() { 72 return _value.contextDependent(); 73 } 74 75 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 76 final ConstantPoolGen cpg = classGen.getConstantPool(); 77 final InstructionList il = methodGen.getInstructionList(); 78 79 // push handler 80 il.append(methodGen.loadHandler()); 81 // push attribute name - namespace prefix set by parent node 82 il.append(new PUSH(cpg, _name)); 83 // push attribute value 84 _value.translate(classGen, methodGen); 85 86 // Generate code that calls SerializationHandler.addUniqueAttribute() 87 // if all attributes are unique. 88 SyntaxTreeNode parent = getParent(); 89 if (parent instanceof LiteralElement 90 && ((LiteralElement)parent).allAttributesUnique()) { 91 92 int flags = 0; 93 boolean isHTMLAttrEmpty = false; 94 ElemDesc elemDesc = ((LiteralElement)parent).getElemDesc(); 95 96 // Set the HTML flags 97 if (elemDesc != null) { 98 if (elemDesc.isAttrFlagSet(_name, ElemDesc.ATTREMPTY)) { 99 flags = flags | SerializationHandler.HTML_ATTREMPTY; 100 isHTMLAttrEmpty = true; 101 } 102 else if (elemDesc.isAttrFlagSet(_name, ElemDesc.ATTRURL)) { 103 flags = flags | SerializationHandler.HTML_ATTRURL; 104 } 105 } 106 107 if (_value instanceof SimpleAttributeValue) { 108 String attrValue = ((SimpleAttributeValue)_value).toString(); 109 110 if (!hasBadChars(attrValue) && !isHTMLAttrEmpty) { 111 flags = flags | SerializationHandler.NO_BAD_CHARS; 112 } 113 } 114 115 il.append(new PUSH(cpg, flags)); 116 il.append(methodGen.uniqueAttribute()); 117 } 118 else { 119 // call attribute 120 il.append(methodGen.attribute()); 121 } 122 } 123 124 /** 125 * Return true if at least one character in the String is considered to 126 * be a "bad" character. A bad character is one whose code is: 127 * less than 32 (a space), 128 * or greater than 126, 129 * or it is one of '<', '>', '&' or '\"'. 130 * This helps the serializer to decide whether the String needs to be escaped. 131 */ 132 private boolean hasBadChars(String value) { 133 char[] chars = value.toCharArray(); 134 int size = chars.length; 135 for (int i = 0; i < size; i++) { 136 char ch = chars[i]; 137 if (ch < 32 || 126 < ch || ch == '<' || ch == '>' || ch == '&' || ch == '\"') 138 return true; 139 } 140 return false; 141 } 142 143 /** 144 * Return the name of the attribute 145 */ 146 public String getName() { 147 return _name; 148 } 149 150 /** 151 * Return the value of the attribute 152 */ 153 public AttributeValue getValue() { 154 return _value; 155 } 156 157 }