1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.templates;
  58. //import org.w3c.dom.Node;
  59. //import org.w3c.dom.DOMException;
  60. import org.apache.xml.dtm.DTM;
  61. import javax.xml.transform.TransformerException;
  62. import org.apache.xml.utils.QName;
  63. import org.apache.xalan.res.XSLTErrorResources;
  64. import org.apache.xalan.res.XSLMessages;
  65. import org.apache.xalan.transformer.TransformerImpl;
  66. import org.apache.xalan.transformer.ResultTreeHandler;
  67. import org.apache.xpath.XPathContext;
  68. import org.xml.sax.SAXException;
  69. /**
  70. * <meta name="usage" content="advanced"/>
  71. * Implement xsl:attribute.
  72. * <pre>
  73. * &!ELEMENT xsl:attribute %char-template;>
  74. * &!ATTLIST xsl:attribute
  75. * name %avt; #REQUIRED
  76. * namespace %avt; #IMPLIED
  77. * %space-att;
  78. * &
  79. * </pre>
  80. * @see <a href="http://www.w3.org/TR/xslt#creating-attributes">creating-attributes in XSLT Specification</a>
  81. */
  82. public class ElemAttribute extends ElemElement
  83. {
  84. /**
  85. * Get an int constant identifying the type of element.
  86. * @see org.apache.xalan.templates.Constants
  87. *
  88. * @return The token ID for this element
  89. */
  90. public int getXSLToken()
  91. {
  92. return Constants.ELEMNAME_ATTRIBUTE;
  93. }
  94. /**
  95. * Return the node name.
  96. *
  97. * @return The element name
  98. */
  99. public String getNodeName()
  100. {
  101. return Constants.ELEMNAME_ATTRIBUTE_STRING;
  102. }
  103. /**
  104. * Create an attribute in the result tree.
  105. * @see <a href="http://www.w3.org/TR/xslt#creating-attributes">creating-attributes in XSLT Specification</a>
  106. *
  107. * @param transformer non-null reference to the the current transform-time state.
  108. *
  109. * @throws TransformerException
  110. */
  111. public void execute(
  112. TransformerImpl transformer)
  113. throws TransformerException
  114. {
  115. ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  116. // If they are trying to add an attribute when there isn't an
  117. // element pending, it is an error.
  118. // I don't think we need this check here because it is checked in
  119. // ResultTreeHandler.addAttribute. (is)
  120. // if (!rhandler.isElementPending())
  121. // {
  122. // // Make sure the trace event is sent.
  123. // if (TransformerImpl.S_DEBUG)
  124. // transformer.getTraceManager().fireTraceEvent(this);
  125. //
  126. // XPathContext xctxt = transformer.getXPathContext();
  127. // int sourceNode = xctxt.getCurrentNode();
  128. // String attrName = m_name_avt.evaluate(xctxt, sourceNode, this);
  129. // transformer.getMsgMgr().warn(this,
  130. // XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_POSITION,
  131. // new Object[]{ attrName });
  132. //
  133. // if (TransformerImpl.S_DEBUG)
  134. // transformer.getTraceManager().fireTraceEndEvent(this);
  135. // return;
  136. //
  137. // // warn(templateChild, sourceNode, "Trying to add attribute after element child has been added, ignoring...");
  138. // }
  139. super.execute(transformer);
  140. }
  141. /**
  142. * Resolve the namespace into a prefix. At this level, if no prefix exists,
  143. * then return a manufactured prefix.
  144. *
  145. * @param rhandler The current result tree handler.
  146. * @param prefix The probable prefix if already known.
  147. * @param nodeNamespace The namespace, which should not be null.
  148. *
  149. * @return The prefix to be used.
  150. */
  151. protected String resolvePrefix(ResultTreeHandler rhandler,
  152. String prefix, String nodeNamespace)
  153. throws TransformerException
  154. {
  155. if (null != prefix && (prefix.length() == 0 || prefix.equals("xmlns")))
  156. {
  157. // Since we can't use default namespace, in this case we try and
  158. // see if a prefix has already been defined or this namespace.
  159. prefix = rhandler.getPrefix(nodeNamespace);
  160. // System.out.println("nsPrefix: "+nsPrefix);
  161. if (null == prefix || prefix.length() == 0 || prefix.equals("xmlns"))
  162. {
  163. if(nodeNamespace.length() > 0)
  164. {
  165. prefix = rhandler.getNewUniqueNSPrefix();
  166. }
  167. else
  168. prefix = "";
  169. }
  170. }
  171. return prefix;
  172. }
  173. /**
  174. * Validate that the node name is good.
  175. *
  176. * @param nodeName Name of the node being constructed, which may be null.
  177. *
  178. * @return true if the node name is valid, false otherwise.
  179. */
  180. protected boolean validateNodeName(String nodeName)
  181. {
  182. if(null == nodeName)
  183. return false;
  184. if(nodeName.equals("xmlns"))
  185. return false;
  186. return super.validateNodeName(nodeName);
  187. }
  188. /**
  189. * Construct a node in the result tree. This method is overloaded by
  190. * xsl:attribute. At this class level, this method creates an element.
  191. *
  192. * @param nodeName The name of the node, which may be null.
  193. * @param prefix The prefix for the namespace, which may be null.
  194. * @param nodeNamespace The namespace of the node, which may be null.
  195. * @param transformer non-null reference to the the current transform-time state.
  196. * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  197. * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
  198. *
  199. * @throws TransformerException
  200. */
  201. void constructNode(
  202. String nodeName, String prefix, String nodeNamespace, TransformerImpl transformer)
  203. throws TransformerException
  204. {
  205. if(null != nodeName && nodeName.length() > 0)
  206. {
  207. ResultTreeHandler rhandler = transformer.getResultTreeHandler();
  208. if(prefix != null && prefix.length() > 0)
  209. {
  210. try
  211. {
  212. rhandler.startPrefixMapping(prefix, nodeNamespace, false);
  213. }
  214. catch(SAXException se)
  215. {
  216. throw new TransformerException(se);
  217. }
  218. }
  219. String val = transformer.transformToString(this);
  220. String localName = QName.getLocalPart(nodeName);
  221. rhandler.addAttribute(nodeNamespace, localName, nodeName, "CDATA", val);
  222. }
  223. }
  224. /**
  225. * Add a child to the child list.
  226. * <!ELEMENT xsl:attribute %char-template;>
  227. * <!ATTLIST xsl:attribute
  228. * name %avt; #REQUIRED
  229. * namespace %avt; #IMPLIED
  230. * %space-att;
  231. * >
  232. *
  233. * @param newChild Child to append to the list of this node's children
  234. *
  235. * @return The node we just appended to the children list
  236. *
  237. * @throws DOMException
  238. */
  239. public ElemTemplateElement appendChild(ElemTemplateElement newChild)
  240. {
  241. int type = ((ElemTemplateElement) newChild).getXSLToken();
  242. switch (type)
  243. {
  244. // char-instructions
  245. case Constants.ELEMNAME_TEXTLITERALRESULT :
  246. case Constants.ELEMNAME_APPLY_TEMPLATES :
  247. case Constants.ELEMNAME_APPLY_IMPORTS :
  248. case Constants.ELEMNAME_CALLTEMPLATE :
  249. case Constants.ELEMNAME_FOREACH :
  250. case Constants.ELEMNAME_VALUEOF :
  251. case Constants.ELEMNAME_COPY_OF :
  252. case Constants.ELEMNAME_NUMBER :
  253. case Constants.ELEMNAME_CHOOSE :
  254. case Constants.ELEMNAME_IF :
  255. case Constants.ELEMNAME_TEXT :
  256. case Constants.ELEMNAME_COPY :
  257. case Constants.ELEMNAME_VARIABLE :
  258. case Constants.ELEMNAME_MESSAGE :
  259. // instructions
  260. // case Constants.ELEMNAME_PI:
  261. // case Constants.ELEMNAME_COMMENT:
  262. // case Constants.ELEMNAME_ELEMENT:
  263. // case Constants.ELEMNAME_ATTRIBUTE:
  264. break;
  265. default :
  266. error(XSLTErrorResources.ER_CANNOT_ADD,
  267. new Object[]{ newChild.getNodeName(),
  268. this.getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
  269. //" to " + this.m_elemName);
  270. }
  271. return super.appendChild(newChild);
  272. }
  273. /**
  274. * @see ElemElement#setName(AVT)
  275. */
  276. public void setName(AVT v) {
  277. if (v.isSimple())
  278. {
  279. if (v.getSimpleString().equals("xmlns"))
  280. {
  281. throw new IllegalArgumentException();
  282. }
  283. }
  284. super.setName(v);
  285. }
  286. }