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.processor;
  58. import org.apache.xalan.templates.ElemLiteralResult;
  59. import org.apache.xalan.templates.ElemTemplateElement;
  60. import org.apache.xalan.templates.Stylesheet;
  61. import org.apache.xalan.templates.ElemExtensionCall;
  62. import org.apache.xalan.templates.ElemTemplate;
  63. import org.apache.xalan.templates.Constants;
  64. import org.apache.xalan.templates.XMLNSDecl;
  65. import org.apache.xalan.res.XSLMessages;
  66. import org.apache.xalan.res.XSLTErrorResources;
  67. import org.apache.xpath.XPath;
  68. import org.apache.xalan.templates.StylesheetRoot;
  69. import javax.xml.transform.TransformerException;
  70. import org.xml.sax.Attributes;
  71. import org.xml.sax.Locator;
  72. import org.xml.sax.helpers.AttributesImpl;
  73. import javax.xml.transform.TransformerConfigurationException;
  74. import org.apache.xml.utils.SAXSourceLocator;
  75. import java.util.Vector;
  76. /**
  77. * <meta name="usage" content="internal"/>
  78. * Processes an XSLT literal-result-element, or something that looks
  79. * like one. The actual {@link org.apache.xalan.templates.ElemTemplateElement}
  80. * produced may be a {@link org.apache.xalan.templates.ElemLiteralResult},
  81. * a {@link org.apache.xalan.templates.StylesheetRoot}, or a
  82. * {@link org.apache.xalan.templates.ElemExtensionCall}.
  83. *
  84. * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
  85. * @see org.apache.xalan.templates.ElemLiteralResult
  86. */
  87. public class ProcessorLRE extends ProcessorTemplateElem
  88. {
  89. /**
  90. * Receive notification of the start of an element.
  91. *
  92. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  93. * @param uri The Namespace URI, or an empty string.
  94. * @param localName The local name (without prefix), or empty string if not namespace processing.
  95. * @param rawName The qualified name (with prefix).
  96. * @param attributes The specified or defaulted attributes.
  97. */
  98. public void startElement(
  99. StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
  100. throws org.xml.sax.SAXException
  101. {
  102. try
  103. {
  104. ElemTemplateElement p = handler.getElemTemplateElement();
  105. boolean excludeXSLDecl = false;
  106. boolean isLREAsStyleSheet = false;
  107. if (null == p)
  108. {
  109. // Literal Result Template as stylesheet.
  110. XSLTElementProcessor lreProcessor = handler.popProcessor();
  111. XSLTElementProcessor stylesheetProcessor =
  112. handler.getProcessorFor(Constants.S_XSLNAMESPACEURL, "stylesheet",
  113. "xsl:stylesheet");
  114. handler.pushProcessor(lreProcessor);
  115. Stylesheet stylesheet;
  116. try
  117. {
  118. stylesheet = new StylesheetRoot(handler.getSchema(), handler.getStylesheetProcessor().getErrorListener());
  119. }
  120. catch(TransformerConfigurationException tfe)
  121. {
  122. throw new TransformerException(tfe);
  123. }
  124. // stylesheet.setDOMBackPointer(handler.getOriginatingNode());
  125. // ***** Note that we're assigning an empty locator. Is this necessary?
  126. SAXSourceLocator slocator = new SAXSourceLocator();
  127. Locator locator = handler.getLocator();
  128. if(null != locator)
  129. {
  130. slocator.setLineNumber(locator.getLineNumber());
  131. slocator.setColumnNumber(locator.getColumnNumber());
  132. slocator.setPublicId(locator.getPublicId());
  133. slocator.setSystemId(locator.getSystemId());
  134. }
  135. stylesheet.setLocaterInfo(slocator);
  136. stylesheet.setPrefixes(handler.getNamespaceSupport());
  137. handler.pushStylesheet(stylesheet);
  138. isLREAsStyleSheet = true;
  139. AttributesImpl stylesheetAttrs = new AttributesImpl();
  140. AttributesImpl lreAttrs = new AttributesImpl();
  141. int n = attributes.getLength();
  142. for (int i = 0; i < n; i++)
  143. {
  144. String attrLocalName = attributes.getLocalName(i);
  145. String attrUri = attributes.getURI(i);
  146. String value = attributes.getValue(i);
  147. if ((null != attrUri) && attrUri.equals(Constants.S_XSLNAMESPACEURL))
  148. {
  149. stylesheetAttrs.addAttribute(null, attrLocalName, attrLocalName,
  150. attributes.getType(i),
  151. attributes.getValue(i));
  152. }
  153. else if ((attrLocalName.startsWith("xmlns:") || attrLocalName.equals(
  154. "xmlns")) && value.equals(Constants.S_XSLNAMESPACEURL))
  155. {
  156. // ignore
  157. }
  158. else
  159. {
  160. lreAttrs.addAttribute(attrUri, attrLocalName,
  161. attributes.getQName(i),
  162. attributes.getType(i),
  163. attributes.getValue(i));
  164. }
  165. }
  166. attributes = lreAttrs;
  167. // Set properties from the attributes, but don't throw
  168. // an error if there is an attribute defined that is not
  169. // allowed on a stylesheet.
  170. try{
  171. stylesheetProcessor.setPropertiesFromAttributes(handler, "stylesheet",
  172. stylesheetAttrs, stylesheet);
  173. }
  174. catch (Exception e)
  175. {
  176. // This is pretty ugly, but it will have to do for now.
  177. // This is just trying to append some text specifying that
  178. // this error came from a missing or invalid XSLT namespace
  179. // declaration.
  180. // If someone comes up with a better solution, please feel
  181. // free to contribute it. -mm
  182. String msg = e.getMessage();
  183. if (stylesheet.getDeclaredPrefixes() == null ||
  184. !declaredXSLNS(stylesheet))
  185. {
  186. msg = msg +"; " + XSLMessages.createWarning(XSLTErrorResources.WG_OLD_XSLT_NS, null);
  187. }
  188. //else
  189. throw new org.xml.sax.SAXException(msg, e);
  190. }
  191. handler.pushElemTemplateElement(stylesheet);
  192. ElemTemplate template = new ElemTemplate();
  193. appendAndPush(handler, template);
  194. XPath rootMatch = new XPath("/", stylesheet, stylesheet, XPath.MATCH,
  195. handler.getStylesheetProcessor().getErrorListener());
  196. template.setMatch(rootMatch);
  197. // template.setDOMBackPointer(handler.getOriginatingNode());
  198. stylesheet.setTemplate(template);
  199. p = handler.getElemTemplateElement();
  200. excludeXSLDecl = true;
  201. }
  202. XSLTElementDef def = getElemDef();
  203. Class classObject = def.getClassObject();
  204. boolean isExtension = false;
  205. boolean isComponentDecl = false;
  206. boolean isUnknownTopLevel = false;
  207. while (null != p)
  208. {
  209. // System.out.println("Checking: "+p);
  210. if (p instanceof ElemLiteralResult)
  211. {
  212. ElemLiteralResult parentElem = (ElemLiteralResult) p;
  213. isExtension = parentElem.containsExtensionElementURI(uri);
  214. }
  215. else if (p instanceof Stylesheet)
  216. {
  217. Stylesheet parentElem = (Stylesheet) p;
  218. isExtension = parentElem.containsExtensionElementURI(uri);
  219. if ((false == isExtension) && (null != uri)
  220. && (uri.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
  221. || uri.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL)))
  222. {
  223. isComponentDecl = true;
  224. }
  225. else
  226. {
  227. isUnknownTopLevel = true;
  228. }
  229. }
  230. if (isExtension)
  231. break;
  232. p = p.getParentElem();
  233. }
  234. ElemTemplateElement elem = null;
  235. try
  236. {
  237. if (isExtension)
  238. {
  239. // System.out.println("Creating extension(1): "+uri);
  240. elem = new ElemExtensionCall();
  241. }
  242. else if (isComponentDecl)
  243. {
  244. elem = (ElemTemplateElement) classObject.newInstance();
  245. }
  246. else if (isUnknownTopLevel)
  247. {
  248. // TBD: Investigate, not sure about this. -sb
  249. elem = (ElemTemplateElement) classObject.newInstance();
  250. }
  251. else
  252. {
  253. elem = (ElemTemplateElement) classObject.newInstance();
  254. }
  255. elem.setDOMBackPointer(handler.getOriginatingNode());
  256. elem.setLocaterInfo(handler.getLocator());
  257. elem.setPrefixes(handler.getNamespaceSupport(), excludeXSLDecl);
  258. if (elem instanceof ElemLiteralResult)
  259. {
  260. ((ElemLiteralResult) elem).setNamespace(uri);
  261. ((ElemLiteralResult) elem).setLocalName(localName);
  262. ((ElemLiteralResult) elem).setRawName(rawName);
  263. ((ElemLiteralResult) elem).setIsLiteralResultAsStylesheet(
  264. isLREAsStyleSheet);
  265. }
  266. }
  267. catch (InstantiationException ie)
  268. {
  269. handler.error(XSLTErrorResources.ER_FAILED_CREATING_ELEMLITRSLT, null, ie);//"Failed creating ElemLiteralResult instance!", ie);
  270. }
  271. catch (IllegalAccessException iae)
  272. {
  273. handler.error(XSLTErrorResources.ER_FAILED_CREATING_ELEMLITRSLT, null, iae);//"Failed creating ElemLiteralResult instance!", iae);
  274. }
  275. setPropertiesFromAttributes(handler, rawName, attributes, elem);
  276. // bit of a hack here...
  277. if (!isExtension && (elem instanceof ElemLiteralResult))
  278. {
  279. isExtension =
  280. ((ElemLiteralResult) elem).containsExtensionElementURI(uri);
  281. if (isExtension)
  282. {
  283. // System.out.println("Creating extension(2): "+uri);
  284. elem = new ElemExtensionCall();
  285. elem.setLocaterInfo(handler.getLocator());
  286. elem.setPrefixes(handler.getNamespaceSupport());
  287. ((ElemLiteralResult) elem).setNamespace(uri);
  288. ((ElemLiteralResult) elem).setLocalName(localName);
  289. ((ElemLiteralResult) elem).setRawName(rawName);
  290. setPropertiesFromAttributes(handler, rawName, attributes, elem);
  291. }
  292. }
  293. appendAndPush(handler, elem);
  294. }
  295. catch(TransformerException te)
  296. {
  297. throw new org.xml.sax.SAXException(te);
  298. }
  299. }
  300. /**
  301. * Receive notification of the end of an element.
  302. *
  303. * @param name The element type name.
  304. * @param attributes The specified or defaulted attributes.
  305. *
  306. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  307. * @param uri The Namespace URI, or an empty string.
  308. * @param localName The local name (without prefix), or empty string if not namespace processing.
  309. * @param rawName The qualified name (with prefix).
  310. */
  311. public void endElement(
  312. StylesheetHandler handler, String uri, String localName, String rawName)
  313. throws org.xml.sax.SAXException
  314. {
  315. ElemTemplateElement elem = handler.getElemTemplateElement();
  316. if (elem instanceof ElemLiteralResult)
  317. {
  318. if (((ElemLiteralResult) elem).getIsLiteralResultAsStylesheet())
  319. {
  320. handler.popStylesheet();
  321. }
  322. }
  323. super.endElement(handler, uri, localName, rawName);
  324. }
  325. private boolean declaredXSLNS(Stylesheet stylesheet)
  326. {
  327. Vector declaredPrefixes = stylesheet.getDeclaredPrefixes();
  328. int n = declaredPrefixes.size();
  329. for (int i = 0; i < n; i++)
  330. {
  331. XMLNSDecl decl = (XMLNSDecl) declaredPrefixes.elementAt(i);
  332. if(decl.getURI().equals(Constants.S_XSLNAMESPACEURL))
  333. return true;
  334. }
  335. return false;
  336. }
  337. }