1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.util.Enumeration ; 23 import java.util.Hashtable ; 24 import java.util.Vector ; 25 26 import org.apache.bcel.generic.ConstantPoolGen; 27 import org.apache.bcel.generic.InstructionList; 28 import org.apache.bcel.generic.PUSH; 29 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 30 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 31 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 32 import org.apache.xalan.xsltc.compiler.util.Type; 33 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 34 import org.apache.xalan.xsltc.compiler.util.Util; 35 36 import org.apache.xml.serializer.ElemDesc; 37 import org.apache.xml.serializer.ToHTMLStream; 38 39 44 final class LiteralElement extends Instruction { 45 46 private String _name; 47 private LiteralElement _literalElemParent; 48 private Vector _attributeElements = null; 49 private Hashtable _accessedPrefixes = null; 50 51 private boolean _allAttributesUnique = false; 55 56 private final static String XMLNS_STRING = "xmlns"; 57 58 61 public QName getName() { 62 return _qname; 63 } 64 65 68 public void display(int indent) { 69 indent(indent); 70 Util.println("LiteralElement name = " + _name); 71 displayContents(indent + IndentIncrement); 72 } 73 74 77 private String accessedNamespace(String prefix) { 78 if (_accessedPrefixes == null) 79 return(null); 80 else 81 return((String )_accessedPrefixes.get(prefix)); 82 } 83 84 89 public void registerNamespace(String prefix, String uri, 90 SymbolTable stable, boolean declared) { 91 92 if (_literalElemParent != null) { 94 final String parentUri = _literalElemParent.accessedNamespace(prefix); 95 if (parentUri == null) { 96 _literalElemParent.registerNamespace(prefix, uri, stable, declared); 97 return; 98 } 99 if (parentUri.equals(uri)) return; 100 } 101 102 if (_accessedPrefixes == null) { 104 _accessedPrefixes = new Hashtable (); 105 } 106 else { 107 if (!declared) { 108 final String old = (String )_accessedPrefixes.get(prefix); 110 if (old != null) { 111 if (old.equals(uri)) 112 return; 113 else 114 prefix = stable.generateNamespacePrefix(); 115 } 116 } 117 } 118 119 if (!prefix.equals("xml")) { 120 _accessedPrefixes.put(prefix,uri); 121 } 122 } 123 124 129 private String translateQName(QName qname, SymbolTable stable) { 130 String localname = qname.getLocalPart(); 132 String prefix = qname.getPrefix(); 133 134 if (prefix == null) 136 prefix = Constants.EMPTYSTRING; 137 else if (prefix.equals(XMLNS_STRING)) 138 return(XMLNS_STRING); 139 140 final String alternative = stable.lookupPrefixAlias(prefix); 142 if (alternative != null) { 143 stable.excludeNamespaces(prefix); 144 prefix = alternative; 145 } 146 147 String uri = lookupNamespace(prefix); 149 if (uri == null) return(localname); 150 151 registerNamespace(prefix, uri, stable, false); 153 154 if (prefix != Constants.EMPTYSTRING) 156 return(prefix+":"+localname); 157 else 158 return(localname); 159 } 160 161 164 public void addAttribute(SyntaxTreeNode attribute) { 165 if (_attributeElements == null) { 166 _attributeElements = new Vector (2); 167 } 168 _attributeElements.add(attribute); 169 } 170 171 174 public void setFirstAttribute(SyntaxTreeNode attribute) { 175 if (_attributeElements == null) { 176 _attributeElements = new Vector (2); 177 } 178 _attributeElements.insertElementAt(attribute,0); 179 } 180 181 185 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 186 if (_attributeElements != null) { 188 final int count = _attributeElements.size(); 189 for (int i = 0; i < count; i++) { 190 SyntaxTreeNode node = 191 (SyntaxTreeNode)_attributeElements.elementAt(i); 192 node.typeCheck(stable); 193 } 194 } 195 typeCheckContents(stable); 196 return Type.Void; 197 } 198 199 204 public Enumeration getNamespaceScope(SyntaxTreeNode node) { 205 Hashtable all = new Hashtable (); 206 207 while (node != null) { 208 Hashtable mapping = node.getPrefixMapping(); 209 if (mapping != null) { 210 Enumeration prefixes = mapping.keys(); 211 while (prefixes.hasMoreElements()) { 212 String prefix = (String )prefixes.nextElement(); 213 if (!all.containsKey(prefix)) { 214 all.put(prefix, mapping.get(prefix)); 215 } 216 } 217 } 218 node = node.getParent(); 219 } 220 return(all.keys()); 221 } 222 223 227 public void parseContents(Parser parser) { 228 final SymbolTable stable = parser.getSymbolTable(); 229 stable.setCurrentNode(this); 230 231 SyntaxTreeNode _literalElemParent = getParent(); 233 while (_literalElemParent != null && !(_literalElemParent instanceof LiteralElement)) { 234 _literalElemParent = _literalElemParent.getParent(); 235 } 236 237 if (!(_literalElemParent instanceof LiteralElement)) { 238 _literalElemParent = null; 239 } 240 241 _name = translateQName(_qname, stable); 242 243 final int count = _attributes.getLength(); 245 for (int i = 0; i < count; i++) { 246 final QName qname = parser.getQName(_attributes.getQName(i)); 247 final String uri = qname.getNamespace(); 248 final String val = _attributes.getValue(i); 249 250 if (qname == parser.getUseAttributeSets()) { 254 if (!Util.isValidQNames(val)) { 255 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, val, this); 256 parser.reportError(Constants.ERROR, err); 257 } 258 setFirstAttribute(new UseAttributeSets(val, parser)); 259 } 260 else if (qname == parser.getExtensionElementPrefixes()) { 262 stable.excludeNamespaces(val); 263 } 264 else if (qname == parser.getExcludeResultPrefixes()) { 266 stable.excludeNamespaces(val); 267 } 268 else { 269 final String prefix = qname.getPrefix(); 271 if (prefix != null && prefix.equals(XMLNS_PREFIX) || 272 prefix == null && qname.getLocalPart().equals("xmlns") || 273 uri != null && uri.equals(XSLT_URI)) 274 { 275 continue; 276 } 277 278 final String name = translateQName(qname, stable); 280 LiteralAttribute attr = new LiteralAttribute(name, val, parser); 281 addAttribute(attr); 282 attr.setParent(this); 283 attr.parseContents(parser); 284 } 285 } 286 287 final Enumeration include = getNamespaceScope(this); 290 while (include.hasMoreElements()) { 291 final String prefix = (String )include.nextElement(); 292 if (!prefix.equals("xml")) { 293 final String uri = lookupNamespace(prefix); 294 if (uri != null && !stable.isExcludedNamespace(uri)) { 295 registerNamespace(prefix, uri, stable, true); 296 } 297 } 298 } 299 300 parseChildren(parser); 301 302 for (int i = 0; i < count; i++) { 304 final QName qname = parser.getQName(_attributes.getQName(i)); 305 final String val = _attributes.getValue(i); 306 307 if (qname == parser.getExtensionElementPrefixes()) { 309 stable.unExcludeNamespaces(val); 310 } 311 else if (qname == parser.getExcludeResultPrefixes()) { 313 stable.unExcludeNamespaces(val); 314 } 315 } 316 } 317 318 protected boolean contextDependent() { 319 return dependentContents(); 320 } 321 322 329 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 330 331 final ConstantPoolGen cpg = classGen.getConstantPool(); 332 final InstructionList il = methodGen.getInstructionList(); 333 334 _allAttributesUnique = checkAttributesUnique(); 336 337 il.append(methodGen.loadHandler()); 339 340 il.append(new PUSH(cpg, _name)); 341 il.append(DUP2); il.append(methodGen.startElement()); 343 344 int j=0; 346 while (j < elementCount()) 347 { 348 final SyntaxTreeNode item = (SyntaxTreeNode) elementAt(j); 349 if (item instanceof Variable) { 350 item.translate(classGen, methodGen); 351 removeElement(item); 358 } 359 else 360 j++; 361 } 362 363 if (_accessedPrefixes != null) { 365 boolean declaresDefaultNS = false; 366 Enumeration e = _accessedPrefixes.keys(); 367 368 while (e.hasMoreElements()) { 369 final String prefix = (String )e.nextElement(); 370 final String uri = (String )_accessedPrefixes.get(prefix); 371 372 if (uri != Constants.EMPTYSTRING || 373 prefix != Constants.EMPTYSTRING) 374 { 375 if (prefix == Constants.EMPTYSTRING) { 376 declaresDefaultNS = true; 377 } 378 il.append(methodGen.loadHandler()); 379 il.append(new PUSH(cpg,prefix)); 380 il.append(new PUSH(cpg,uri)); 381 il.append(methodGen.namespace()); 382 } 383 } 384 385 389 if (!declaresDefaultNS && (_parent instanceof XslElement) 390 && ((XslElement) _parent).declaresDefaultNS()) 391 { 392 il.append(methodGen.loadHandler()); 393 il.append(new PUSH(cpg, Constants.EMPTYSTRING)); 394 il.append(new PUSH(cpg, Constants.EMPTYSTRING)); 395 il.append(methodGen.namespace()); 396 } 397 } 398 399 if (_attributeElements != null) { 401 final int count = _attributeElements.size(); 402 for (int i = 0; i < count; i++) { 403 SyntaxTreeNode node = 404 (SyntaxTreeNode)_attributeElements.elementAt(i); 405 if (!(node instanceof XslAttribute)) { 406 node.translate(classGen, methodGen); 407 } 408 } 409 } 410 411 translateContents(classGen, methodGen); 413 414 il.append(methodGen.endElement()); 416 } 417 418 421 private boolean isHTMLOutput() { 422 return getStylesheet().getOutputMethod() == Stylesheet.HTML_OUTPUT; 423 } 424 425 430 public ElemDesc getElemDesc() { 431 if (isHTMLOutput()) { 432 return ToHTMLStream.getElemDesc(_name); 433 } 434 else 435 return null; 436 } 437 438 441 public boolean allAttributesUnique() { 442 return _allAttributesUnique; 443 } 444 445 448 private boolean checkAttributesUnique() { 449 boolean hasHiddenXslAttribute = canProduceAttributeNodes(this, true); 450 if (hasHiddenXslAttribute) 451 return false; 452 453 if (_attributeElements != null) { 454 int numAttrs = _attributeElements.size(); 455 Hashtable attrsTable = null; 456 for (int i = 0; i < numAttrs; i++) { 457 SyntaxTreeNode node = (SyntaxTreeNode)_attributeElements.elementAt(i); 458 459 if (node instanceof UseAttributeSets) { 460 return false; 461 } 462 else if (node instanceof XslAttribute) { 463 if (attrsTable == null) { 464 attrsTable = new Hashtable (); 465 for (int k = 0; k < i; k++) { 466 SyntaxTreeNode n = (SyntaxTreeNode)_attributeElements.elementAt(k); 467 if (n instanceof LiteralAttribute) { 468 LiteralAttribute literalAttr = (LiteralAttribute)n; 469 attrsTable.put(literalAttr.getName(), literalAttr); 470 } 471 } 472 } 473 474 XslAttribute xslAttr = (XslAttribute)node; 475 AttributeValue attrName = xslAttr.getName(); 476 if (attrName instanceof AttributeValueTemplate) { 477 return false; 478 } 479 else if (attrName instanceof SimpleAttributeValue) { 480 SimpleAttributeValue simpleAttr = (SimpleAttributeValue)attrName; 481 String name = simpleAttr.toString(); 482 if (name != null && attrsTable.get(name) != null) 483 return false; 484 else if (name != null) { 485 attrsTable.put(name, xslAttr); 486 } 487 } 488 } 489 } 490 } 491 return true; 492 } 493 494 500 private boolean canProduceAttributeNodes(SyntaxTreeNode node, boolean ignoreXslAttribute) { 501 Vector contents = node.getContents(); 502 int size = contents.size(); 503 for (int i = 0; i < size; i++) { 504 SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); 505 if (child instanceof Text) { 506 Text text = (Text)child; 507 if (text.isIgnore()) 508 continue; 509 else 510 return false; 511 } 512 else if (child instanceof LiteralElement 515 || child instanceof ValueOf 516 || child instanceof XslElement 517 || child instanceof Comment 518 || child instanceof Number 519 || child instanceof ProcessingInstruction) 520 return false; 521 else if (child instanceof XslAttribute) { 522 if (ignoreXslAttribute) 523 continue; 524 else 525 return true; 526 } 527 else if (child instanceof CallTemplate 532 || child instanceof ApplyTemplates 533 || child instanceof Copy 534 || child instanceof CopyOf) 535 return true; 536 else if ((child instanceof If 537 || child instanceof ForEach) 538 && canProduceAttributeNodes(child, false)) { 539 return true; 540 } 541 else if (child instanceof Choose) { 542 Vector chooseContents = child.getContents(); 543 int num = chooseContents.size(); 544 for (int k = 0; k < num; k++) { 545 SyntaxTreeNode chooseChild = (SyntaxTreeNode)chooseContents.elementAt(k); 546 if (chooseChild instanceof When || chooseChild instanceof Otherwise) { 547 if (canProduceAttributeNodes(chooseChild, false)) 548 return true; 549 } 550 } 551 } 552 } 553 return false; 554 } 555 556 } 557 | Popular Tags |