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.xml.sax.InputSource;
  59. import org.xml.sax.Attributes;
  60. import org.xml.sax.EntityResolver;
  61. import org.xml.sax.DTDHandler;
  62. import org.xml.sax.ContentHandler;
  63. import org.apache.xalan.res.XSLMessages;
  64. import org.apache.xalan.res.XSLTErrorResources;
  65. import org.apache.xalan.templates.ElemTemplateElement;
  66. import org.apache.xalan.templates.Constants;
  67. import org.apache.xml.utils.IntStack;
  68. import org.xml.sax.helpers.AttributesImpl;
  69. import javax.xml.transform.ErrorListener;
  70. import javax.xml.transform.TransformerException;
  71. import java.util.Vector;
  72. /**
  73. * This class acts as the superclass for all stylesheet element
  74. * processors, and deals with things that are common to all elements.
  75. * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
  76. */
  77. public class XSLTElementProcessor extends ElemTemplateElement
  78. {
  79. /**
  80. * Construct a processor for top-level elements.
  81. * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
  82. */
  83. XSLTElementProcessor(){}
  84. private IntStack m_savedLastOrder;
  85. /**
  86. * The element definition that this processor conforms to.
  87. */
  88. private XSLTElementDef m_elemDef;
  89. /**
  90. * Get the element definition that belongs to this element.
  91. *
  92. * @return The element definition object that produced and constrains this element.
  93. */
  94. XSLTElementDef getElemDef()
  95. {
  96. return m_elemDef;
  97. }
  98. /**
  99. * Set the element definition that belongs to this element.
  100. *
  101. * @param def The element definition object that produced and constrains this element.
  102. */
  103. void setElemDef(XSLTElementDef def)
  104. {
  105. m_elemDef = def;
  106. }
  107. /**
  108. * Resolve an external entity.
  109. *
  110. *
  111. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  112. * @param publicId The public identifer, or null if none is
  113. * available.
  114. * @param systemId The system identifier provided in the XML
  115. * document.
  116. * @return The new input source, or null to require the
  117. * default behaviour.
  118. */
  119. public InputSource resolveEntity(
  120. StylesheetHandler handler, String publicId, String systemId)
  121. throws org.xml.sax.SAXException
  122. {
  123. return null;
  124. }
  125. /**
  126. * Receive notification of a notation declaration.
  127. *
  128. *
  129. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  130. * @param name The notation name.
  131. * @param publicId The notation public identifier, or null if not
  132. * available.
  133. * @param systemId The notation system identifier.
  134. * @see org.xml.sax.DTDHandler#notationDecl
  135. */
  136. public void notationDecl(StylesheetHandler handler, String name,
  137. String publicId, String systemId)
  138. {
  139. // no op
  140. }
  141. /**
  142. * Receive notification of an unparsed entity declaration.
  143. *
  144. *
  145. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  146. * @param name The entity name.
  147. * @param publicId The entity public identifier, or null if not
  148. * available.
  149. * @param systemId The entity system identifier.
  150. * @param notationName The name of the associated notation.
  151. * @see org.xml.sax.DTDHandler#unparsedEntityDecl
  152. */
  153. public void unparsedEntityDecl(StylesheetHandler handler, String name,
  154. String publicId, String systemId,
  155. String notationName)
  156. {
  157. // no op
  158. }
  159. /**
  160. * Receive notification of the start of the non-text event. This
  161. * is sent to the current processor when any non-text event occurs.
  162. *
  163. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  164. */
  165. public void startNonText(StylesheetHandler handler) throws org.xml.sax.SAXException
  166. {
  167. // no op
  168. }
  169. /**
  170. * Receive notification of the start of an element.
  171. *
  172. * @param name The element type name.
  173. *
  174. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  175. * @param uri The Namespace URI, or an empty string.
  176. * @param localName The local name (without prefix), or empty string if not namespace processing.
  177. * @param rawName The qualified name (with prefix).
  178. * @param attributes The specified or defaulted attributes.
  179. */
  180. public void startElement(
  181. StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
  182. throws org.xml.sax.SAXException
  183. {
  184. if (m_savedLastOrder == null)
  185. m_savedLastOrder = new IntStack();
  186. m_savedLastOrder.push(getElemDef().getLastOrder());
  187. getElemDef().setLastOrder(-1);
  188. }
  189. /**
  190. * Receive notification of the end of an element.
  191. *
  192. * @param name The element type name.
  193. * @param attributes The specified or defaulted attributes.
  194. *
  195. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  196. * @param uri The Namespace URI, or an empty string.
  197. * @param localName The local name (without prefix), or empty string if not namespace processing.
  198. * @param rawName The qualified name (with prefix).
  199. */
  200. public void endElement(
  201. StylesheetHandler handler, String uri, String localName, String rawName)
  202. throws org.xml.sax.SAXException
  203. {
  204. if (m_savedLastOrder != null && !m_savedLastOrder.empty())
  205. getElemDef().setLastOrder(m_savedLastOrder.pop());
  206. if (!getElemDef().getRequiredFound())
  207. handler.error(XSLTErrorResources.ER_REQUIRED_ELEM_NOT_FOUND, new Object[]{getElemDef().getRequiredElem()}, null);
  208. }
  209. /**
  210. * Receive notification of character data inside an element.
  211. *
  212. *
  213. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  214. * @param ch The characters.
  215. * @param start The start position in the character array.
  216. * @param length The number of characters to use from the
  217. * character array.
  218. */
  219. public void characters(
  220. StylesheetHandler handler, char ch[], int start, int length)
  221. throws org.xml.sax.SAXException
  222. {
  223. handler.error(XSLTErrorResources.ER_CHARS_NOT_ALLOWED, null, null);//"Characters are not allowed at this point in the document!",
  224. //null);
  225. }
  226. /**
  227. * Receive notification of ignorable whitespace in element content.
  228. *
  229. *
  230. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  231. * @param ch The whitespace characters.
  232. * @param start The start position in the character array.
  233. * @param length The number of characters to use from the
  234. * character array.
  235. */
  236. public void ignorableWhitespace(
  237. StylesheetHandler handler, char ch[], int start, int length)
  238. throws org.xml.sax.SAXException
  239. {
  240. // no op
  241. }
  242. /**
  243. * Receive notification of a processing instruction.
  244. *
  245. *
  246. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  247. * @param target The processing instruction target.
  248. * @param data The processing instruction data, or null if
  249. * none is supplied.
  250. */
  251. public void processingInstruction(
  252. StylesheetHandler handler, String target, String data)
  253. throws org.xml.sax.SAXException
  254. {
  255. // no op
  256. }
  257. /**
  258. * Receive notification of a skipped entity.
  259. *
  260. *
  261. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  262. * @param name The name of the skipped entity.
  263. */
  264. public void skippedEntity(StylesheetHandler handler, String name)
  265. throws org.xml.sax.SAXException
  266. {
  267. // no op
  268. }
  269. /**
  270. * Set the properties of an object from the given attribute list.
  271. * @param handler The stylesheet's Content handler, needed for
  272. * error reporting.
  273. * @param rawName The raw name of the owner element, needed for
  274. * error reporting.
  275. * @param attributes The list of attributes.
  276. * @param target The target element where the properties will be set.
  277. */
  278. void setPropertiesFromAttributes(
  279. StylesheetHandler handler, String rawName, Attributes attributes,
  280. ElemTemplateElement target)
  281. throws org.xml.sax.SAXException
  282. {
  283. setPropertiesFromAttributes(handler, rawName, attributes, target, true);
  284. }
  285. /**
  286. * Set the properties of an object from the given attribute list.
  287. * @param handler The stylesheet's Content handler, needed for
  288. * error reporting.
  289. * @param rawName The raw name of the owner element, needed for
  290. * error reporting.
  291. * @param attributes The list of attributes.
  292. * @param target The target element where the properties will be set.
  293. * @param throwError True if it should throw an error if an
  294. * attribute is not defined.
  295. * @return the attributes not allowed on this element.
  296. *
  297. * @throws TransformerException
  298. */
  299. Attributes setPropertiesFromAttributes(
  300. StylesheetHandler handler, String rawName, Attributes attributes,
  301. ElemTemplateElement target, boolean throwError)
  302. throws org.xml.sax.SAXException
  303. {
  304. XSLTElementDef def = getElemDef();
  305. AttributesImpl undefines = throwError ? null : new AttributesImpl();
  306. // Keep track of which XSLTAttributeDefs have been processed, so
  307. // I can see which default values need to be set.
  308. Vector processedDefs = new Vector();
  309. // Keep track of XSLTAttributeDefs that were invalid
  310. Vector errorDefs = new Vector();
  311. int nAttrs = attributes.getLength();
  312. for (int i = 0; i < nAttrs; i++)
  313. {
  314. String attrUri = attributes.getURI(i);
  315. // Hack for Crimson. -sb
  316. if((null != attrUri) && (attrUri.length() == 0)
  317. && (attributes.getQName(i).startsWith("xmlns:") ||
  318. attributes.getQName(i).equals("xmlns")))
  319. {
  320. attrUri = org.apache.xalan.templates.Constants.S_XMLNAMESPACEURI;
  321. }
  322. String attrLocalName = attributes.getLocalName(i);
  323. XSLTAttributeDef attrDef = def.getAttributeDef(attrUri, attrLocalName);
  324. if (null == attrDef)
  325. {
  326. if (throwError)
  327. {
  328. // Then barf, because this element does not allow this attribute.
  329. handler.error(XSLTErrorResources.ER_ATTR_NOT_ALLOWED, new Object[]{attributes.getQName(i), rawName}, null);//"\""+attributes.getQName(i)+"\""
  330. //+ " attribute is not allowed on the " + rawName
  331. // + " element!", null);
  332. }
  333. else
  334. {
  335. undefines.addAttribute(attrUri, attrLocalName,
  336. attributes.getQName(i),
  337. attributes.getType(i),
  338. attributes.getValue(i));
  339. }
  340. }
  341. else
  342. {
  343. // Can we switch the order here:
  344. boolean success = attrDef.setAttrValue(handler, attrUri, attrLocalName,
  345. attributes.getQName(i), attributes.getValue(i),
  346. target);
  347. // Now we only add the element if it passed a validation check
  348. if (success)
  349. processedDefs.addElement(attrDef);
  350. else
  351. errorDefs.addElement(attrDef);
  352. }
  353. }
  354. XSLTAttributeDef[] attrDefs = def.getAttributes();
  355. int nAttrDefs = attrDefs.length;
  356. for (int i = 0; i < nAttrDefs; i++)
  357. {
  358. XSLTAttributeDef attrDef = attrDefs[i];
  359. String defVal = attrDef.getDefault();
  360. if (null != defVal)
  361. {
  362. if (!processedDefs.contains(attrDef))
  363. {
  364. attrDef.setDefAttrValue(handler, target);
  365. }
  366. }
  367. if (attrDef.getRequired())
  368. {
  369. if ((!processedDefs.contains(attrDef)) && (!errorDefs.contains(attrDef)))
  370. handler.error(
  371. XSLMessages.createMessage(
  372. XSLTErrorResources.ER_REQUIRES_ATTRIB, new Object[]{ rawName,
  373. attrDef.getName() }), null);
  374. }
  375. }
  376. return undefines;
  377. }
  378. }