/******************************************************************************* | |
* Copyright (c) 2008 Standards for Technology in Automotive Retail | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* David Carver - STAR - bug 224197 - initial API and implementation | |
* based on work from Apache Xalan 2.7.0 | |
*******************************************************************************/ | |
/* | |
* Copyright 1999-2005 The Apache Software Foundation. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/* | |
* $Id: ElemLiteralResult.java,v 1.4 2008/03/28 02:38:15 dacarver Exp $ | |
*/ | |
package org.eclipse.wst.xsl.core.internal.compiler.xslt10.templates; | |
import java.util.Enumeration; | |
import java.util.Vector; | |
import javax.xml.transform.TransformerException; | |
import org.eclipse.wst.xsl.core.compiler.xslt10.res.Messages; | |
import org.eclipse.wst.xsl.core.compiler.xslt10.res.XSLTErrorResources; | |
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.transformer.TransformerImpl; | |
import org.apache.xml.serializer.SerializationHandler; | |
import org.apache.xml.utils.StringVector; | |
import org.apache.xpath.XPathContext; | |
import org.xml.sax.SAXException; | |
import org.w3c.dom.NamedNodeMap; | |
import org.w3c.dom.Attr; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Element; | |
import org.w3c.dom.Node; | |
import org.w3c.dom.NodeList; | |
import org.w3c.dom.DOMException; | |
import org.w3c.dom.TypeInfo; | |
import org.w3c.dom.UserDataHandler; | |
/** | |
* Implement a Literal Result Element. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element | |
* in XSLT Specification</a> | |
* @xsl.usage advanced | |
*/ | |
public class ElemLiteralResult extends ElemUse { | |
public static final long serialVersionUID = -8703409074421657260L; | |
/** The return value as Empty String. */ | |
private static final String EMPTYSTRING = ""; | |
/** | |
* Tells if this element represents a root element that is also the | |
* stylesheet element. TODO: This should be a derived class. | |
* | |
* @serial | |
*/ | |
private boolean isLiteralResultAsStylesheet = false; | |
/** | |
* Set whether this element represents a root element that is also the | |
* stylesheet element. | |
* | |
* | |
* @param b | |
* boolean flag indicating whether this element represents a root | |
* element that is also the stylesheet element. | |
*/ | |
public void setIsLiteralResultAsStylesheet(boolean b) { | |
isLiteralResultAsStylesheet = b; | |
} | |
/** | |
* Return whether this element represents a root element that is also the | |
* stylesheet element. | |
* | |
* | |
* @return boolean flag indicating whether this element represents a root | |
* element that is also the stylesheet element. | |
*/ | |
public boolean getIsLiteralResultAsStylesheet() { | |
return isLiteralResultAsStylesheet; | |
} | |
/** | |
* This function is called after everything else has been recomposed, and | |
* allows the template to set remaining values that may be based on some | |
* other property that depends on recomposition. | |
*/ | |
@Override | |
public void compose(StylesheetRoot sroot) throws TransformerException { | |
super.compose(sroot); | |
StylesheetRoot.ComposeState cstate = sroot.getComposeState(); | |
java.util.Vector vnames = cstate.getVariableNames(); | |
if (null != m_avts) { | |
int nAttrs = m_avts.size(); | |
for (int i = (nAttrs - 1); i >= 0; i--) { | |
AVT avt = (AVT) m_avts.elementAt(i); | |
avt.fixupVariables(vnames, cstate.getGlobalsSize()); | |
} | |
} | |
} | |
/** | |
* The created element node will have the attribute nodes that were present | |
* on the element node in the stylesheet tree, other than attributes with | |
* names in the XSLT namespace. | |
* | |
* @serial | |
*/ | |
private Vector m_avts = null; | |
/** | |
* List of attributes with the XSLT namespace. | |
* | |
* @serial | |
*/ | |
private Vector m_xslAttr = null; | |
/** | |
* Set a literal result attribute (AVTs only). | |
* | |
* @param avt | |
* literal result attribute to add (AVT only) | |
*/ | |
public void addLiteralResultAttribute(AVT avt) { | |
if (null == m_avts) | |
m_avts = new Vector(); | |
m_avts.addElement(avt); | |
} | |
/** | |
* Set a literal result attribute (used for xsl attributes). | |
* | |
* @param att | |
* literal result attribute to add | |
*/ | |
public void addLiteralResultAttribute(String att) { | |
if (null == m_xslAttr) | |
m_xslAttr = new Vector(); | |
m_xslAttr.addElement(att); | |
} | |
/** | |
* Set the "xml:space" attribute. A text node is preserved if an ancestor | |
* element of the text node has an xml:space attribute with a value of | |
* preserve, and no closer ancestor element has xml:space with a value of | |
* default. | |
* | |
* @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT | |
* Specification</a> | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#section-Creating-Text">section-Creating-Text | |
* in XSLT Specification</a> | |
* | |
* @param avt | |
* Enumerated value, either Constants.ATTRVAL_PRESERVE or | |
* Constants.ATTRVAL_STRIP. | |
*/ | |
public void setXmlSpace(AVT avt) { | |
// This function is a bit-o-hack, I guess... | |
addLiteralResultAttribute(avt); | |
String val = avt.getSimpleString(); | |
if (val.equals("default")) { | |
super.setXmlSpace(Constants.ATTRVAL_STRIP); | |
} else if (val.equals("preserve")) { | |
super.setXmlSpace(Constants.ATTRVAL_PRESERVE); | |
} | |
// else maybe it's a real AVT, so we can't resolve it at this time. | |
} | |
/** | |
* Get a literal result attribute by name. | |
* | |
* @param namespaceURI | |
* Namespace URI of attribute node to get | |
* @param localName | |
* Local part of qualified name of attribute node to get | |
* | |
* @return literal result attribute (AVT) | |
*/ | |
public AVT getLiteralResultAttributeNS(String namespaceURI, String localName) { | |
if (null != m_avts) { | |
int nAttrs = m_avts.size(); | |
for (int i = (nAttrs - 1); i >= 0; i--) { | |
AVT avt = (AVT) m_avts.elementAt(i); | |
if (avt.getName().equals(localName) | |
&& avt.getURI().equals(namespaceURI)) { | |
return avt; | |
} | |
} // end for | |
} | |
return null; | |
} | |
/** | |
* Return the raw value of the attribute. | |
* | |
* @param namespaceURI | |
* Namespace URI of attribute node to get | |
* @param localName | |
* Local part of qualified name of attribute node to get | |
* | |
* @return The Attr value as a string, or the empty string if that attribute | |
* does not have a specified or default value | |
*/ | |
@Override | |
public String getAttributeNS(String namespaceURI, String localName) { | |
AVT avt = getLiteralResultAttributeNS(namespaceURI, localName); | |
if ((null != avt)) { | |
return avt.getSimpleString(); | |
} | |
return EMPTYSTRING; | |
} | |
/** | |
* Get a literal result attribute by name. The name is | |
* namespaceURI:localname if namespace is not null. | |
* | |
* @param name | |
* Name of literal result attribute to get | |
* | |
* @return literal result attribute (AVT) | |
*/ | |
public AVT getLiteralResultAttribute(String name) { | |
if (null != m_avts) { | |
int nAttrs = m_avts.size(); | |
String namespace = null; | |
for (int i = (nAttrs - 1); i >= 0; i--) { | |
AVT avt = (AVT) m_avts.elementAt(i); | |
namespace = avt.getURI(); | |
if ((namespace != null && (!namespace.equals("")) && (namespace | |
+ ":" + avt.getName()).equals(name)) | |
|| ((namespace == null || namespace.equals("")) && avt | |
.getRawName().equals(name))) { | |
return avt; | |
} | |
} // end for | |
} | |
return null; | |
} | |
/** | |
* Return the raw value of the attribute. | |
* | |
* @param namespaceURI:localName | |
* or localName if the namespaceURI is null of the attribute to | |
* get | |
* | |
* @return The Attr value as a string, or the empty string if that attribute | |
* does not have a specified or default value | |
*/ | |
@Override | |
public String getAttribute(String rawName) { | |
AVT avt = getLiteralResultAttribute(rawName); | |
if ((null != avt)) { | |
return avt.getSimpleString(); | |
} | |
return EMPTYSTRING; | |
} | |
/** | |
* Get whether or not the passed URL is flagged by the | |
* "extension-element-prefixes" or "exclude-result-prefixes" properties. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#extension-element">extension-element | |
* in XSLT Specification</a> | |
* | |
* @param prefix | |
* non-null reference to prefix that might be excluded.(not | |
* currently used) | |
* @param uri | |
* reference to namespace that prefix maps to | |
* | |
* @return true if the prefix should normally be excluded. | |
*/ | |
@Override | |
public boolean containsExcludeResultPrefix(String prefix, String uri) { | |
if (uri == null | |
|| (null == m_excludeResultPrefixes && null == m_ExtensionElementURIs)) | |
return super.containsExcludeResultPrefix(prefix, uri); | |
if (prefix.length() == 0) | |
prefix = Constants.ATTRVAL_DEFAULT_PREFIX; | |
// This loop is ok here because this code only runs during | |
// stylesheet compile time. | |
if (m_excludeResultPrefixes != null) | |
for (int i = 0; i < m_excludeResultPrefixes.size(); i++) { | |
if (uri.equals(getNamespaceForPrefix(m_excludeResultPrefixes | |
.elementAt(i)))) | |
return true; | |
} | |
// JJK Bugzilla 1133: Also check locally-scoped extensions | |
if (m_ExtensionElementURIs != null | |
&& m_ExtensionElementURIs.contains(uri)) | |
return true; | |
return super.containsExcludeResultPrefix(prefix, uri); | |
} | |
/** | |
* Augment resolvePrefixTables, resolving the namespace aliases once the | |
* superclass has resolved the tables. | |
* | |
* @throws TransformerException | |
*/ | |
@Override | |
public void resolvePrefixTables() throws TransformerException { | |
super.resolvePrefixTables(); | |
StylesheetRoot stylesheet = getStylesheetRoot(); | |
if ((null != m_namespace) && (m_namespace.length() > 0)) { | |
NamespaceAlias nsa = stylesheet | |
.getNamespaceAliasComposed(m_namespace); | |
if (null != nsa) { | |
m_namespace = nsa.getResultNamespace(); | |
// String resultPrefix = nsa.getResultPrefix(); | |
String resultPrefix = nsa.getStylesheetPrefix(); // As per | |
// xsl WG, | |
// Mike Kay | |
if ((null != resultPrefix) && (resultPrefix.length() > 0)) | |
m_rawName = resultPrefix + ":" + m_localName; | |
else | |
m_rawName = m_localName; | |
} | |
} | |
if (null != m_avts) { | |
int n = m_avts.size(); | |
for (int i = 0; i < n; i++) { | |
AVT avt = (AVT) m_avts.elementAt(i); | |
// Should this stuff be a method on AVT? | |
String ns = avt.getURI(); | |
if ((null != ns) && (ns.length() > 0)) { | |
NamespaceAlias nsa = stylesheet | |
.getNamespaceAliasComposed(m_namespace); // %REVIEW% | |
// ns? | |
if (null != nsa) { | |
String namespace = nsa.getResultNamespace(); | |
// String resultPrefix = nsa.getResultPrefix(); | |
String resultPrefix = nsa.getStylesheetPrefix(); // As | |
// per | |
// XSL | |
// WG | |
String rawName = avt.getName(); | |
if ((null != resultPrefix) | |
&& (resultPrefix.length() > 0)) | |
rawName = resultPrefix + ":" + rawName; | |
avt.setURI(namespace); | |
avt.setRawName(rawName); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Return whether we need to check namespace prefixes against the exclude | |
* result prefixes or extensions lists. Note that this will create a new | |
* prefix table if one has not been created already. | |
* | |
* NEEDSDOC ($objectName$) | |
* | |
* @return | |
*/ | |
@Override | |
public boolean needToCheckExclude() { | |
if (null == m_excludeResultPrefixes && null == m_prefixTable | |
&& m_ExtensionElementURIs == null // JJK Bugzilla 1133 | |
) | |
return false; | |
else { | |
// Create a new prefix table if one has not already been created. | |
if (null == m_prefixTable) | |
m_prefixTable = new Vector(); | |
return true; | |
} | |
} | |
/** | |
* The namespace of the element to be created. | |
* | |
* @serial | |
*/ | |
private String m_namespace; | |
/** | |
* Set the namespace URI of the result element to be created. Note that | |
* after resolvePrefixTables has been called, this will return the aliased | |
* result namespace, not the original stylesheet namespace. | |
* | |
* @param ns | |
* The Namespace URI, or the empty string if the element has no | |
* Namespace URI. | |
*/ | |
public void setNamespace(String ns) { | |
if (null == ns) // defensive, shouldn't have to do this. | |
ns = ""; | |
m_namespace = ns; | |
} | |
/** | |
* Get the original namespace of the Literal Result Element. | |
* | |
* %REVIEW% Why isn't this overriding the getNamespaceURI method rather than | |
* introducing a new one? | |
* | |
* @return The Namespace URI, or the empty string if the element has no | |
* Namespace URI. | |
*/ | |
public String getNamespace() { | |
return m_namespace; | |
} | |
/** | |
* The local name of the element to be created. | |
* | |
* @serial | |
*/ | |
private String m_localName; | |
/** | |
* Set the local name of the LRE. | |
* | |
* @param localName | |
* The local name (without prefix) of the result element to be | |
* created. | |
*/ | |
public void setLocalName(String localName) { | |
m_localName = localName; | |
} | |
/** | |
* Get the local name of the Literal Result Element. Note that after | |
* resolvePrefixTables has been called, this will return the aliased name | |
* prefix, not the original stylesheet namespace prefix. | |
* | |
* @return The local name (without prefix) of the result element to be | |
* created. | |
*/ | |
@Override | |
public String getLocalName() { | |
return m_localName; | |
} | |
/** | |
* The raw name of the element to be created. | |
* | |
* @serial | |
*/ | |
private String m_rawName; | |
/** | |
* Set the raw name of the LRE. | |
* | |
* @param rawName | |
* The qualified name (with prefix), or the empty string if | |
* qualified names are not available. | |
*/ | |
public void setRawName(String rawName) { | |
m_rawName = rawName; | |
} | |
/** | |
* Get the raw name of the Literal Result Element. | |
* | |
* @return The qualified name (with prefix), or the empty string if | |
* qualified names are not available. | |
*/ | |
public String getRawName() { | |
return m_rawName; | |
} | |
/** | |
* Get the prefix part of the raw name of the Literal Result Element. | |
* | |
* @return The prefix, or the empty string if noprefix was provided. | |
*/ | |
@Override | |
public String getPrefix() { | |
int len = m_rawName.length() - m_localName.length() - 1; | |
return (len > 0) ? m_rawName.substring(0, len) : ""; | |
} | |
/** | |
* The "extension-element-prefixes" property, actually contains URIs. | |
* | |
* @serial | |
*/ | |
private StringVector m_ExtensionElementURIs; | |
/** | |
* Set the "extension-element-prefixes" property. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#extension-element">extension-element | |
* in XSLT Specification</a> | |
* | |
* @param v | |
* Vector of URIs (not prefixes) to set as the | |
* "extension-element-prefixes" property | |
*/ | |
public void setExtensionElementPrefixes(StringVector v) { | |
m_ExtensionElementURIs = v; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return NamedNodeMap | |
*/ | |
@Override | |
public NamedNodeMap getAttributes() { | |
return new LiteralElementAttributes(); | |
} | |
public class LiteralElementAttributes implements NamedNodeMap { | |
private int m_count = -1; | |
/** | |
* Construct a NameNodeMap. | |
* | |
*/ | |
public LiteralElementAttributes() { | |
} | |
/** | |
* Return the number of Attributes on this Element | |
* | |
* @return The number of nodes in this map. The range of valid child | |
* node indices is <code>0</code> to <code>length-1</code> | |
* inclusive | |
*/ | |
public int getLength() { | |
if (m_count == -1) { | |
if (null != m_avts) | |
m_count = m_avts.size(); | |
else | |
m_count = 0; | |
} | |
return m_count; | |
} | |
/** | |
* Retrieves a node specified by name. | |
* | |
* @param name | |
* The <code>nodeName</code> of a node to retrieve. | |
* @return A <code>Node</code> (of any type) with the specified | |
* <code>nodeName</code>, or <code>null</code> if it does | |
* not identify any node in this map. | |
*/ | |
public Node getNamedItem(String name) { | |
if (getLength() == 0) | |
return null; | |
String uri = null; | |
String localName = name; | |
int index = name.indexOf(":"); | |
if (-1 != index) { | |
uri = name.substring(0, index); | |
localName = name.substring(index + 1); | |
} | |
Node retNode = null; | |
Enumeration eum = m_avts.elements(); | |
while (eum.hasMoreElements()) { | |
AVT avt = (AVT) eum.nextElement(); | |
if (localName.equals(avt.getName())) { | |
String nsURI = avt.getURI(); | |
if ((uri == null && nsURI == null) | |
|| (uri != null && uri.equals(nsURI))) { | |
retNode = new Attribute(avt, ElemLiteralResult.this); | |
break; | |
} | |
} | |
} | |
return retNode; | |
} | |
/** | |
* Retrieves a node specified by local name and namespace URI. | |
* | |
* @param namespaceURI | |
* Namespace URI of attribute node to get | |
* @param localName | |
* Local part of qualified name of attribute node to get | |
* @return A <code>Node</code> (of any type) with the specified | |
* <code>nodeName</code>, or <code>null</code> if it does | |
* not identify any node in this map. | |
*/ | |
public Node getNamedItemNS(String namespaceURI, String localName) { | |
if (getLength() == 0) | |
return null; | |
Node retNode = null; | |
Enumeration eum = m_avts.elements(); | |
while (eum.hasMoreElements()) { | |
AVT avt = (AVT) eum.nextElement(); | |
if (localName.equals(avt.getName())) { | |
String nsURI = avt.getURI(); | |
if ((namespaceURI == null && nsURI == null) | |
|| (namespaceURI != null && namespaceURI | |
.equals(nsURI))) { | |
retNode = new Attribute(avt, ElemLiteralResult.this); | |
break; | |
} | |
} | |
} | |
return retNode; | |
} | |
/** | |
* Returns the <code>index</code>th item in the map. If <code>index | |
* </code> | |
* is greater than or equal to the number of nodes in this map, this | |
* returns <code>null</code>. | |
* | |
* @param i | |
* The index of the requested item. | |
* @return The node at the <code>index</code>th position in the map, | |
* or <code>null</code> if that is not a valid index. | |
*/ | |
public Node item(int i) { | |
if (getLength() == 0 || i >= m_avts.size()) | |
return null; | |
else | |
return new Attribute(((AVT) m_avts.elementAt(i)), | |
ElemLiteralResult.this); | |
} | |
/** | |
* @see org.w3c.dom.NamedNodeMap | |
* | |
* @param name | |
* of the node to remove | |
* | |
* @return The node removed from this map if a node with such a name | |
* exists. | |
* | |
* @throws DOMException | |
*/ | |
public Node removeNamedItem(String name) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.NamedNodeMap | |
* | |
* @param namespaceURI | |
* Namespace URI of the node to remove | |
* @param localName | |
* Local part of qualified name of the node to remove | |
* | |
* @return The node removed from this map if a node with such a local | |
* name and namespace URI exists | |
* | |
* @throws DOMException | |
*/ | |
public Node removeNamedItemNS(String namespaceURI, String localName) | |
throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* Unimplemented. See org.w3c.dom.NamedNodeMap | |
* | |
* @param A | |
* node to store in this map | |
* | |
* @return If the new Node replaces an existing node the replaced Node | |
* is returned, otherwise null is returned | |
* | |
* @throws DOMException | |
*/ | |
public Node setNamedItem(Node arg) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* Unimplemented. See org.w3c.dom.NamedNodeMap | |
* | |
* @param A | |
* node to store in this map | |
* | |
* @return If the new Node replaces an existing node the replaced Node | |
* is returned, otherwise null is returned | |
* | |
* @throws DOMException | |
*/ | |
public Node setNamedItemNS(Node arg) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
} | |
public class Attribute implements Attr { | |
private AVT m_attribute; | |
private Element m_owner = null; | |
/** | |
* Construct a Attr. | |
* | |
*/ | |
public Attribute(AVT avt, Element elem) { | |
m_attribute = avt; | |
m_owner = elem; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param newChild | |
* New node to append to the list of this node's children | |
* | |
* | |
* @throws DOMException | |
*/ | |
public Node appendChild(Node newChild) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param deep | |
* Flag indicating whether to clone deep (clone member | |
* variables) | |
* | |
* @return Returns a duplicate of this node | |
*/ | |
public Node cloneNode(boolean deep) { | |
return new Attribute(m_attribute, m_owner); | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return null | |
*/ | |
public NamedNodeMap getAttributes() { | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return a NodeList containing no nodes. | |
*/ | |
public NodeList getChildNodes() { | |
return new NodeList() { | |
public int getLength() { | |
return 0; | |
} | |
public Node item(int index) { | |
return null; | |
} | |
}; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return null | |
*/ | |
public Node getFirstChild() { | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return null | |
*/ | |
public Node getLastChild() { | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return the local part of the qualified name of this node | |
*/ | |
public String getLocalName() { | |
return m_attribute.getName(); | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return The namespace URI of this node, or null if it is unspecified | |
*/ | |
public String getNamespaceURI() { | |
String uri = m_attribute.getURI(); | |
return (uri.equals("")) ? null : uri; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return null | |
*/ | |
public Node getNextSibling() { | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return The name of the attribute | |
*/ | |
public String getNodeName() { | |
String uri = m_attribute.getURI(); | |
String localName = getLocalName(); | |
return (uri.equals("")) ? localName : uri + ":" + localName; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return The node is an Attr | |
*/ | |
public short getNodeType() { | |
return ATTRIBUTE_NODE; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return The value of the attribute | |
* | |
* @throws DOMException | |
*/ | |
public String getNodeValue() throws DOMException { | |
return m_attribute.getSimpleString(); | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return null | |
*/ | |
public Document getOwnerDocument() { | |
return m_owner.getOwnerDocument(); | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return the containing element node | |
*/ | |
public Node getParentNode() { | |
return m_owner; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return The namespace prefix of this node, or null if it is | |
* unspecified | |
*/ | |
public String getPrefix() { | |
String uri = m_attribute.getURI(); | |
String rawName = m_attribute.getRawName(); | |
return (uri.equals("")) ? null : rawName.substring(0, rawName | |
.indexOf(":")); | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return null | |
*/ | |
public Node getPreviousSibling() { | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return false | |
*/ | |
public boolean hasAttributes() { | |
return false; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return false | |
*/ | |
public boolean hasChildNodes() { | |
return false; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param newChild | |
* New child node to insert | |
* @param refChild | |
* Insert in front of this child | |
* | |
* @return null | |
* | |
* @throws DOMException | |
*/ | |
public Node insertBefore(Node newChild, Node refChild) | |
throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @return Returns <code>false</code> | |
* @since DOM Level 2 | |
*/ | |
public boolean isSupported(String feature, String version) { | |
return false; | |
} | |
/** @see org.w3c.dom.Node */ | |
public void normalize() { | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param oldChild | |
* Child to be removed | |
* | |
* @return null | |
* | |
* @throws DOMException | |
*/ | |
public Node removeChild(Node oldChild) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param newChild | |
* Replace existing child with this one | |
* @param oldChild | |
* Existing child to be replaced | |
* | |
* @return null | |
* | |
* @throws DOMException | |
*/ | |
public Node replaceChild(Node newChild, Node oldChild) | |
throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
return null; | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param nodeValue | |
* Value to set this node to | |
* | |
* @throws DOMException | |
*/ | |
public void setNodeValue(String nodeValue) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
} | |
/** | |
* @see org.w3c.dom.Node | |
* | |
* @param prefix | |
* Prefix to set for this node | |
* | |
* @throws DOMException | |
*/ | |
public void setPrefix(String prefix) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
} | |
/** | |
* | |
* @return The name of this attribute | |
*/ | |
public String getName() { | |
return m_attribute.getName(); | |
} | |
/** | |
* | |
* @return The value of this attribute returned as string | |
*/ | |
public String getValue() { | |
return m_attribute.getSimpleString(); | |
} | |
/** | |
* | |
* @return The Element node this attribute is attached to or null if | |
* this attribute is not in use | |
*/ | |
public Element getOwnerElement() { | |
return m_owner; | |
} | |
/** | |
* | |
* @return true | |
*/ | |
public boolean getSpecified() { | |
return true; | |
} | |
/** | |
* @see org.w3c.dom.Attr | |
* | |
* @param value | |
* Value to set this node to | |
* | |
* @throws DOMException | |
*/ | |
public void setValue(String value) throws DOMException { | |
throwDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, | |
XSLTErrorResources.NO_MODIFICATION_ALLOWED_ERR); | |
} | |
public TypeInfo getSchemaTypeInfo() { | |
return null; | |
} | |
public boolean isId() { | |
return false; | |
} | |
public Object setUserData(String key, Object data, | |
UserDataHandler handler) { | |
return getOwnerDocument().setUserData(key, data, handler); | |
} | |
public Object getUserData(String key) { | |
return getOwnerDocument().getUserData(key); | |
} | |
public Object getFeature(String feature, String version) { | |
return isSupported(feature, version) ? this : null; | |
} | |
public boolean isEqualNode(Node arg) { | |
return arg == this; | |
} | |
public String lookupNamespaceURI(String specifiedPrefix) { | |
return null; | |
} | |
public boolean isDefaultNamespace(String namespaceURI) { | |
return false; | |
} | |
public String lookupPrefix(String namespaceURI) { | |
return null; | |
} | |
public boolean isSameNode(Node other) { | |
// we do not use any wrapper so the answer is obvious | |
return this == other; | |
} | |
public void setTextContent(String textContent) throws DOMException { | |
setNodeValue(textContent); | |
} | |
public String getTextContent() throws DOMException { | |
return getNodeValue(); // overriden in some subclasses | |
} | |
public short compareDocumentPosition(Node other) throws DOMException { | |
return 0; | |
} | |
public String getBaseURI() { | |
return null; | |
} | |
} | |
/** | |
* Get an "extension-element-prefix" property. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#extension-element">extension-element | |
* in XSLT Specification</a> | |
* | |
* @param i | |
* Index of URI ("extension-element-prefix" property) to get | |
* | |
* @return URI at given index ("extension-element-prefix" property) | |
* | |
* @throws ArrayIndexOutOfBoundsException | |
*/ | |
public String getExtensionElementPrefix(int i) | |
throws ArrayIndexOutOfBoundsException { | |
if (null == m_ExtensionElementURIs) | |
throw new ArrayIndexOutOfBoundsException(); | |
return m_ExtensionElementURIs.elementAt(i); | |
} | |
/** | |
* Get the number of "extension-element-prefixes" Strings. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#extension-element">extension-element | |
* in XSLT Specification</a> | |
* | |
* @return the number of "extension-element-prefixes" Strings | |
*/ | |
public int getExtensionElementPrefixCount() { | |
return (null != m_ExtensionElementURIs) ? m_ExtensionElementURIs.size() | |
: 0; | |
} | |
/** | |
* Find out if the given "extension-element-prefix" property is defined. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#extension-element">extension-element | |
* in XSLT Specification</a> | |
* | |
* @param uri | |
* The URI to find | |
* | |
* @return True if the given URI is found | |
*/ | |
public boolean containsExtensionElementURI(String uri) { | |
if (null == m_ExtensionElementURIs) | |
return false; | |
return m_ExtensionElementURIs.contains(uri); | |
} | |
/** | |
* Get an int constant identifying the type of element. | |
* | |
* @see org.apache.xalan.templates.Constants | |
* | |
* @return The token ID for this element | |
*/ | |
@Override | |
public int getXSLToken() { | |
return Constants.ELEMNAME_LITERALRESULT; | |
} | |
/** | |
* Return the node name. | |
* | |
* @return The element's name | |
*/ | |
@Override | |
public String getNodeName() { | |
// TODO: Need prefix. | |
return m_rawName; | |
} | |
/** | |
* The XSLT version as specified by this element. | |
* | |
* @serial | |
*/ | |
private String m_version; | |
/** | |
* Set the "version" property. | |
* | |
* @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT | |
* Specification</a> | |
* | |
* @param v | |
* Version property value to set | |
*/ | |
public void setVersion(String v) { | |
m_version = v; | |
} | |
/** | |
* Get the "version" property. | |
* | |
* @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT | |
* Specification</a> | |
* | |
* @return Version property value | |
*/ | |
public String getVersion() { | |
return m_version; | |
} | |
/** | |
* The "exclude-result-prefixes" property. | |
* | |
* @serial | |
*/ | |
private StringVector m_excludeResultPrefixes; | |
/** | |
* Set the "exclude-result-prefixes" property. The designation of a | |
* namespace as an excluded namespace is effective within the subtree of the | |
* stylesheet rooted at the element bearing the exclude-result-prefixes or | |
* xsl:exclude-result-prefixes attribute; a subtree rooted at an | |
* xsl:stylesheet element does not include any stylesheets imported or | |
* included by children of that xsl:stylesheet element. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element | |
* in XSLT Specification</a> | |
* | |
* @param v | |
* vector of prefixes that are resolvable to strings. | |
*/ | |
public void setExcludeResultPrefixes(StringVector v) { | |
m_excludeResultPrefixes = v; | |
} | |
/** | |
* Tell if the result namespace decl should be excluded. Should be called | |
* before namespace aliasing (I think). | |
* | |
* @param prefix | |
* Prefix of namespace to check | |
* @param uri | |
* URI of namespace to check | |
* | |
* @return True if the given namespace should be excluded | |
* | |
* @throws TransformerException | |
*/ | |
private boolean excludeResultNSDecl(String prefix, String uri) | |
throws TransformerException { | |
if (null != m_excludeResultPrefixes) { | |
return containsExcludeResultPrefix(prefix, uri); | |
} | |
return false; | |
} | |
/** | |
* Copy a Literal Result Element into the Result tree, copy the non-excluded | |
* namespace attributes, copy the attributes not of the XSLT namespace, and | |
* execute the children of the LRE. | |
* | |
* @see <a | |
* href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element | |
* in XSLT Specification</a> | |
* | |
* @param transformer | |
* non-null reference to the the current transform-time state. | |
* | |
* @throws TransformerException | |
*/ | |
@Override | |
public void execute(TransformerImpl transformer) | |
throws TransformerException { | |
SerializationHandler rhandler = transformer.getSerializationHandler(); | |
try { | |
if (transformer.getDebug()) { | |
// flush any buffered pending processing before | |
// the trace event. | |
rhandler.flushPending(); | |
transformer.getTraceManager().fireTraceEvent(this); | |
} | |
// JJK Bugzilla 3464, test namespace85 -- make sure LRE's | |
// namespace is asserted even if default, since xsl:element | |
// may have changed the context. | |
rhandler.startPrefixMapping(getPrefix(), getNamespace()); | |
// Add namespace declarations. | |
executeNSDecls(transformer); | |
rhandler.startElement(getNamespace(), getLocalName(), getRawName()); | |
} catch (SAXException se) { | |
throw new TransformerException(se); | |
} | |
/* | |
* If we make it to here we have done a successful startElement() we | |
* will do an endElement() call for balance, no matter what happens in | |
* the middle. | |
*/ | |
// tException remembers if we had an exception "in the middle" | |
TransformerException tException = null; | |
try { | |
// Process any possible attributes from xsl:use-attribute-sets first | |
super.execute(transformer); | |
// xsl:version, excludeResultPrefixes??? | |
// Process the list of avts next | |
if (null != m_avts) { | |
int nAttrs = m_avts.size(); | |
for (int i = (nAttrs - 1); i >= 0; i--) { | |
AVT avt = (AVT) m_avts.elementAt(i); | |
XPathContext xctxt = transformer.getXPathContext(); | |
int sourceNode = xctxt.getCurrentNode(); | |
String stringedValue = avt | |
.evaluate(xctxt, sourceNode, this); | |
if (null != stringedValue) { | |
// Important Note: I'm not going to check for excluded | |
// namespace | |
// prefixes here. It seems like it's too expensive, and | |
// I'm not | |
// even sure this is right. But I could be wrong, so | |
// this needs | |
// to be tested against other implementations. | |
rhandler.addAttribute(avt.getURI(), avt.getName(), avt | |
.getRawName(), "CDATA", stringedValue, false); | |
} | |
} // end for | |
} | |
// Now process all the elements in this subtree | |
// TODO: Process m_extensionElementPrefixes && m_attributeSetsNames | |
transformer.executeChildTemplates(this, true); | |
} catch (TransformerException te) { | |
// thrown in finally to prevent original exception consumed by | |
// subsequent exceptions | |
tException = te; | |
} catch (SAXException se) { | |
tException = new TransformerException(se); | |
} | |
try { | |
/* | |
* we need to do this endElement() to balance the successful | |
* startElement() call even if there was an exception in the middle. | |
* Otherwise an exception in the middle could cause a system to | |
* hang. | |
*/ | |
if (transformer.getDebug()) { | |
// flush any buffered pending processing before | |
// the trace event. | |
// rhandler.flushPending(); | |
transformer.getTraceManager().fireTraceEndEvent(this); | |
} | |
rhandler.endElement(getNamespace(), getLocalName(), getRawName()); | |
} catch (SAXException se) { | |
/* | |
* we did call endElement(). If thee was an exception in the middle | |
* throw that one, otherwise if there was an exception from | |
* endElement() throw that one. | |
*/ | |
if (tException != null) | |
throw tException; | |
else | |
throw new TransformerException(se); | |
} | |
/* | |
* If an exception was thrown in the middle but not with startElement() | |
* or or endElement() then its time to let it percolate. | |
*/ | |
if (tException != null) | |
throw tException; | |
unexecuteNSDecls(transformer); | |
// JJK Bugzilla 3464, test namespace85 -- balance explicit start. | |
try { | |
rhandler.endPrefixMapping(getPrefix()); | |
} catch (SAXException se) { | |
throw new TransformerException(se); | |
} | |
} | |
/** | |
* Compiling templates requires that we be able to list the AVTs ADDED | |
* 9/5/2000 to support compilation experiment | |
* | |
* @return an Enumeration of the literal result attributes associated with | |
* this element. | |
*/ | |
public Enumeration enumerateLiteralResultAttributes() { | |
return (null == m_avts) ? null : m_avts.elements(); | |
} | |
/** | |
* Accept a visitor and call the appropriate method for this class. | |
* | |
* @param visitor | |
* The visitor whose appropriate method will be called. | |
* @return true if the children of the object should be visited. | |
*/ | |
@Override | |
protected boolean accept(XSLTVisitor visitor) { | |
return visitor.visitLiteralResultElement(this); | |
} | |
/** | |
* Call the children visitors. | |
* | |
* @param visitor | |
* The visitor whose appropriate method will be called. | |
*/ | |
@Override | |
protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs) { | |
if (callAttrs && null != m_avts) { | |
int nAttrs = m_avts.size(); | |
for (int i = (nAttrs - 1); i >= 0; i--) { | |
AVT avt = (AVT) m_avts.elementAt(i); | |
avt.callVisitors(visitor); | |
} | |
} | |
super.callChildVisitors(visitor, callAttrs); | |
} | |
/** | |
* Throw a DOMException | |
* | |
* @param msg | |
* key of the error that occured. | |
*/ | |
public void throwDOMException(short code, String msg) { | |
String themsg = Messages.createMessage(msg, null); | |
throw new DOMException(code, themsg); | |
} | |
} |