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.xml.utils.StringToIntTable;
  59. import java.lang.reflect.InvocationTargetException;
  60. import java.lang.reflect.Method;
  61. import java.util.StringTokenizer;
  62. import java.util.Vector;
  63. import org.apache.xalan.templates.AVT;
  64. import org.apache.xalan.templates.ElemTemplateElement;
  65. import org.apache.xalan.templates.Constants;
  66. import org.apache.xalan.res.XSLMessages;
  67. import org.apache.xalan.res.XSLTErrorResources;
  68. import org.apache.xml.utils.QName;
  69. import org.apache.xml.utils.SystemIDResolver;
  70. import org.apache.xml.utils.StringVector;
  71. import org.apache.xml.utils.XMLChar;
  72. import org.apache.xpath.XPath;
  73. import javax.xml.transform.TransformerException;
  74. /**
  75. * This class defines an attribute for an element in a XSLT stylesheet,
  76. * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
  77. * mapping between Xalan classes and the markup attributes in the element.
  78. */
  79. public class XSLTAttributeDef
  80. {
  81. // How to handle invalid values for this attribute
  82. static final int FATAL = 0;
  83. static final int ERROR = 1;
  84. static final int WARNING = 2;
  85. /**
  86. * Construct an instance of XSLTAttributeDef.
  87. *
  88. * @param namespace The Namespace URI, or an empty string.
  89. * @param name The local name (without prefix), or empty string if not namespace processing.
  90. * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
  91. * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
  92. * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME, T_NCNAME.
  93. * @param required true if this is attribute is required by the XSLT specification.
  94. * @param supportsAVT true if this attribute supports AVT's.
  95. * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING.
  96. */
  97. XSLTAttributeDef(String namespace, String name, int type, boolean required, boolean supportsAVT, int errorType)
  98. {
  99. this.m_namespace = namespace;
  100. this.m_name = name;
  101. this.m_type = type;
  102. this.m_required = required;
  103. this.m_supportsAVT = supportsAVT;
  104. this.m_errorType = errorType;
  105. }
  106. /**
  107. * Construct an instance of XSLTAttributeDef.
  108. *
  109. * @param namespace The Namespace URI, or an empty string.
  110. * @param name The local name (without prefix), or empty string if not namespace processing.
  111. * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR,
  112. * T_CHAR, T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM,
  113. * T_SIMPLEPATTERNLIST, T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST,
  114. * T_ENUM_OR_PQNAME, T_NCNAME.
  115. * @param supportsAVT true if this attribute supports AVT's.
  116. * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING.
  117. * @param defaultVal The default value for this attribute.
  118. */
  119. XSLTAttributeDef(String namespace, String name, int type, boolean supportsAVT, int errorType, String defaultVal)
  120. {
  121. this.m_namespace = namespace;
  122. this.m_name = name;
  123. this.m_type = type;
  124. this.m_required = false;
  125. this.m_supportsAVT = supportsAVT;
  126. this.m_errorType = errorType;
  127. this.m_default = defaultVal;
  128. }
  129. /**
  130. * Construct an instance of XSLTAttributeDef that uses two
  131. * enumerated values.
  132. *
  133. * @param namespace The Namespace URI, or an empty string.
  134. * @param name The local name (without prefix), or empty string if not namespace processing.
  135. * @param required true if this attribute is required by the XSLT specification.
  136. * @param supportsAVT true if this attribute supports AVT's.
  137. * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
  138. * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING.
  139. * @param k1 The XSLT name of the enumerated value.
  140. * @param v1 An integer representation of k1.
  141. * @param k2 The XSLT name of the enumerated value.
  142. * @param v2 An integer representation of k2.
  143. */
  144. XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
  145. boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2)
  146. {
  147. this.m_namespace = namespace;
  148. this.m_name = name;
  149. this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;
  150. this.m_required = required;
  151. this.m_supportsAVT = supportsAVT;
  152. this.m_errorType = errorType;
  153. m_enums = new StringToIntTable(2);
  154. m_enums.put(k1, v1);
  155. m_enums.put(k2, v2);
  156. }
  157. /**
  158. * Construct an instance of XSLTAttributeDef that uses three
  159. * enumerated values.
  160. *
  161. * @param namespace The Namespace URI, or an empty string.
  162. * @param name The local name (without prefix), or empty string if not namespace processing.
  163. * @param required true if this attribute is required by the XSLT specification.
  164. * @param supportsAVT true if this attribute supports AVT's.
  165. * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
  166. * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING. *
  167. * @param k1 The XSLT name of the enumerated value.
  168. * @param v1 An integer representation of k1.
  169. * @param k2 The XSLT name of the enumerated value.
  170. * @param v2 An integer representation of k2.
  171. * @param k3 The XSLT name of the enumerated value.
  172. * @param v3 An integer representation of k3.
  173. */
  174. XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
  175. boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2, String k3, int v3)
  176. {
  177. this.m_namespace = namespace;
  178. this.m_name = name;
  179. this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;
  180. this.m_required = required;
  181. this.m_supportsAVT = supportsAVT;
  182. this.m_errorType = errorType;
  183. m_enums = new StringToIntTable(3);
  184. m_enums.put(k1, v1);
  185. m_enums.put(k2, v2);
  186. m_enums.put(k3, v3);
  187. }
  188. /**
  189. * Construct an instance of XSLTAttributeDef that uses three
  190. * enumerated values.
  191. *
  192. * @param namespace The Namespace URI, or an empty string.
  193. * @param name The local name (without prefix), or empty string if not namespace processing.
  194. * @param required true if this attribute is required by the XSLT specification.
  195. * @param supportsAVT true if this attribute supports AVT's.
  196. * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
  197. * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING. * @param k1 The XSLT name of the enumerated value.
  198. * @param v1 An integer representation of k1.
  199. * @param k2 The XSLT name of the enumerated value.
  200. * @param v2 An integer representation of k2.
  201. * @param k3 The XSLT name of the enumerated value.
  202. * @param v3 An integer representation of k3.
  203. * @param k4 The XSLT name of the enumerated value.
  204. * @param v4 An integer representation of k4.
  205. */
  206. XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
  207. boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2,
  208. String k3, int v3, String k4, int v4)
  209. {
  210. this.m_namespace = namespace;
  211. this.m_name = name;
  212. this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;
  213. this.m_required = required;
  214. this.m_supportsAVT = supportsAVT;
  215. this.m_errorType = errorType;
  216. m_enums = new StringToIntTable(4);
  217. m_enums.put(k1, v1);
  218. m_enums.put(k2, v2);
  219. m_enums.put(k3, v3);
  220. m_enums.put(k4, v4);
  221. }
  222. /** Type values that represent XSLT attribute types. */
  223. static final int T_CDATA = 1,
  224. // <!-- Used for the type of an attribute value that is a URI reference.-->
  225. T_URL = 2,
  226. // <!-- Used for the type of an attribute value that is an
  227. // attribute value template.-->
  228. T_AVT = 3, // Attribute Value Template
  229. // <!-- Used for the type of an attribute value that is a pattern.-->
  230. T_PATTERN = 4,
  231. // <!-- Used for the type of an attribute value that is an expression.-->
  232. T_EXPR = 5,
  233. // <!-- Used for the type of an attribute value that consists
  234. // of a single character.-->
  235. T_CHAR = 6,
  236. // <!-- Used for the type of an attribute value that is a number. -->
  237. T_NUMBER = 7,
  238. // Used for boolean values
  239. T_YESNO = 8,
  240. // <!-- Used for the type of an attribute value that is a QName; the prefix
  241. // gets expanded by the XSLT processor. -->
  242. T_QNAME = 9,
  243. // <!--Used for a whitespace-separated list of QNames where the non-prefixed
  244. // entries are not to be placed in the default namespace. -->
  245. T_QNAMES = 10,
  246. // <!-- Used for enumerated values -->
  247. T_ENUM = 11,
  248. // Used for simple match patterns, i.e. xsl:strip-space spec.
  249. T_SIMPLEPATTERNLIST = 12,
  250. // Used for a known token.
  251. T_NMTOKEN = 13,
  252. // Used for a list of white-space delimited strings.
  253. T_STRINGLIST = 14,
  254. // Used for a list of white-space delimited strings.
  255. T_PREFIX_URLLIST = 15,
  256. // Used for enumerated values, one of which could be a qname-but-not-ncname
  257. T_ENUM_OR_PQNAME = 16,
  258. // Used for the type of an attribute value that is a NCName
  259. T_NCNAME = 17,
  260. // Used for QName attributes that are always AVT. Prefix isn't resolved.
  261. T_AVT_QNAME = 18,
  262. // Used for a list of QNames where non-prefixed items are to be resolved
  263. // using the default namespace (This is only true for cdata-section-elements)
  264. T_QNAMES_RESOLVE_NULL = 19;
  265. /** Representation for an attribute in a foreign namespace. */
  266. static XSLTAttributeDef m_foreignAttr = new XSLTAttributeDef("*", "*",
  267. XSLTAttributeDef.T_CDATA,false, false, WARNING);
  268. /** Method name that objects may implement if they wish to have forein attributes set. */
  269. static String S_FOREIGNATTR_SETTER = "setForeignAttr";
  270. /**
  271. * The allowed namespace for this element.
  272. */
  273. private String m_namespace;
  274. /**
  275. * Get the allowed namespace for this attribute.
  276. *
  277. * @return The allowed namespace for this attribute, which may be null, or may be "*".
  278. */
  279. String getNamespace()
  280. {
  281. return m_namespace;
  282. }
  283. /**
  284. * The name of this element.
  285. */
  286. private String m_name;
  287. /**
  288. * Get the name of this attribute.
  289. *
  290. * @return non-null reference to the name of this attribute, which may be "*".
  291. */
  292. String getName()
  293. {
  294. return m_name;
  295. }
  296. /**
  297. * The type of this attribute value.
  298. */
  299. private int m_type;
  300. /**
  301. * Get the type of this attribute value.
  302. *
  303. * @return One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
  304. * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
  305. * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME.
  306. */
  307. int getType()
  308. {
  309. return m_type;
  310. }
  311. /**
  312. * If this element is of type T_ENUM, this will contain
  313. * a map from the attribute string to the Xalan integer
  314. * value.
  315. */
  316. private StringToIntTable m_enums;
  317. /**
  318. * If this element is of type T_ENUM, this will return
  319. * a map from the attribute string to the Xalan integer
  320. * value.
  321. * @param key The XSLT attribute value.
  322. *
  323. * @return The integer representation of the enumerated value for this attribute.
  324. * @throws Throws NullPointerException if m_enums is null.
  325. */
  326. private int getEnum(String key)
  327. {
  328. return m_enums.get(key);
  329. }
  330. /**
  331. * If this element is of type T_ENUM, this will return
  332. * an array of strings - the values in the enumeration
  333. *
  334. * @return An array of the enumerated values permitted for this attribute.
  335. *
  336. * @throws Throws NullPointerException if m_enums is null.
  337. */
  338. private String[] getEnumNames()
  339. {
  340. return m_enums.keys();
  341. }
  342. /**
  343. * The default value for this attribute.
  344. */
  345. private String m_default;
  346. /**
  347. * Get the default value for this attribute.
  348. *
  349. * @return The default value for this attribute, or null.
  350. */
  351. String getDefault()
  352. {
  353. return m_default;
  354. }
  355. /**
  356. * Set the default value for this attribute.
  357. *
  358. * @param def String representation of the default value for this attribute.
  359. */
  360. void setDefault(String def)
  361. {
  362. m_default = def;
  363. }
  364. /**
  365. * If true, this is a required attribute.
  366. */
  367. private boolean m_required;
  368. /**
  369. * Get whether or not this is a required attribute.
  370. *
  371. * @return true if this is a required attribute.
  372. */
  373. boolean getRequired()
  374. {
  375. return m_required;
  376. }
  377. /**
  378. * If true, this is attribute supports AVT's.
  379. */
  380. private boolean m_supportsAVT;
  381. /**
  382. * Get whether or not this attribute supports AVT's.
  383. *
  384. * @return true if this attribute supports AVT's.
  385. */
  386. boolean getSupportsAVT()
  387. {
  388. return m_supportsAVT;
  389. }
  390. int m_errorType = this.WARNING;
  391. /**
  392. * Get the type of error message to use if the attribute value is invalid.
  393. *
  394. * @return one of XSLAttributeDef.FATAL, XSLAttributeDef.ERROR, XSLAttributeDef.WARNING
  395. */
  396. int getErrorType()
  397. {
  398. return m_errorType;
  399. }
  400. /**
  401. * String that should represent the setter method which which
  402. * may be used on objects to set a value that represents this attribute
  403. */
  404. String m_setterString = null;
  405. /**
  406. * Return a string that should represent the setter method.
  407. * The setter method name will be created algorithmically the
  408. * first time this method is accessed, and then cached for return
  409. * by subsequent invocations of this method.
  410. *
  411. * @return String that should represent the setter method which which
  412. * may be used on objects to set a value that represents this attribute,
  413. * of null if no setter method should be called.
  414. */
  415. public String getSetterMethodName()
  416. {
  417. if (null == m_setterString)
  418. {
  419. if (m_foreignAttr == this)
  420. {
  421. return S_FOREIGNATTR_SETTER;
  422. }
  423. else if (m_name.equals("*"))
  424. {
  425. m_setterString = "addLiteralResultAttribute";
  426. return m_setterString;
  427. }
  428. StringBuffer outBuf = new StringBuffer();
  429. outBuf.append("set");
  430. if ((m_namespace != null)
  431. && m_namespace.equals(Constants.S_XMLNAMESPACEURI))
  432. {
  433. outBuf.append("Xml");
  434. }
  435. int n = m_name.length();
  436. for (int i = 0; i < n; i++)
  437. {
  438. char c = m_name.charAt(i);
  439. if ('-' == c)
  440. {
  441. i++;
  442. c = m_name.charAt(i);
  443. c = Character.toUpperCase(c);
  444. }
  445. else if (0 == i)
  446. {
  447. c = Character.toUpperCase(c);
  448. }
  449. outBuf.append(c);
  450. }
  451. m_setterString = outBuf.toString();
  452. }
  453. return m_setterString;
  454. }
  455. /**
  456. * Process an attribute string of type T_AVT into
  457. * a AVT value.
  458. *
  459. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  460. * @param uri The Namespace URI, or an empty string.
  461. * @param name The local name (without prefix), or empty string if not namespace processing.
  462. * @param rawName The qualified name (with prefix).
  463. * @param value Should be an Attribute Value Template string.
  464. *
  465. * @return An AVT object that may be used to evaluate the Attribute Value Template.
  466. *
  467. * @throws org.xml.sax.SAXException which will wrap a
  468. * {@link javax.xml.transform.TransformerException}, if there is a syntax error
  469. * in the attribute value template string.
  470. */
  471. AVT processAVT(
  472. StylesheetHandler handler, String uri, String name, String rawName, String value,
  473. ElemTemplateElement owner)
  474. throws org.xml.sax.SAXException
  475. {
  476. try
  477. {
  478. AVT avt = new AVT(handler, uri, name, rawName, value, owner);
  479. return avt;
  480. }
  481. catch (TransformerException te)
  482. {
  483. throw new org.xml.sax.SAXException(te);
  484. }
  485. }
  486. /**
  487. * Process an attribute string of type T_CDATA into
  488. * a String value.
  489. *
  490. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  491. * @param uri The Namespace URI, or an empty string.
  492. * @param name The local name (without prefix), or empty string if not namespace processing.
  493. * @param rawName The qualified name (with prefix).
  494. * @param value non-null string reference.
  495. *
  496. * @return The value argument.
  497. *
  498. * @throws org.xml.sax.SAXException.
  499. */
  500. Object processCDATA(StylesheetHandler handler, String uri, String name,
  501. String rawName, String value, ElemTemplateElement owner)
  502. throws org.xml.sax.SAXException
  503. {
  504. if (getSupportsAVT()) {
  505. try
  506. {
  507. AVT avt = new AVT(handler, uri, name, rawName, value, owner);
  508. return avt;
  509. }
  510. catch (TransformerException te)
  511. {
  512. throw new org.xml.sax.SAXException(te);
  513. }
  514. } else {
  515. return value;
  516. }
  517. }
  518. /**
  519. * Process an attribute string of type T_CHAR into
  520. * a Character value.
  521. *
  522. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  523. * @param uri The Namespace URI, or an empty string.
  524. * @param name The local name (without prefix), or empty string if not namespace processing.
  525. * @param rawName The qualified name (with prefix).
  526. * @param value Should be a string with a length of 1.
  527. *
  528. * @return Character object.
  529. *
  530. * @throws org.xml.sax.SAXException if the string is not a length of 1.
  531. */
  532. Object processCHAR(
  533. StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
  534. throws org.xml.sax.SAXException
  535. {
  536. if (getSupportsAVT()) {
  537. try
  538. {
  539. AVT avt = new AVT(handler, uri, name, rawName, value, owner);
  540. // If an AVT wasn't used, validate the value
  541. if ((avt.isSimple()) && (value.length() != 1)) {
  542. handleError(handler, XSLTErrorResources.INVALID_TCHAR, new Object[] {name, value},null);
  543. return null;
  544. }
  545. return avt;
  546. }
  547. catch (TransformerException te)
  548. {
  549. throw new org.xml.sax.SAXException(te);
  550. }
  551. } else {
  552. if (value.length() != 1)
  553. {
  554. handleError(handler, XSLTErrorResources.INVALID_TCHAR, new Object[] {name, value},null);
  555. return null;
  556. }
  557. return new Character(value.charAt(0));
  558. }
  559. }
  560. /**
  561. * Process an attribute string of type T_ENUM into a int value.
  562. *
  563. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  564. * @param uri The Namespace URI, or an empty string.
  565. * @param name The local name (without prefix), or empty string if not namespace processing.
  566. * @param rawName The qualified name (with prefix).
  567. * @param value non-null string that represents an enumerated value that is
  568. * valid for this element.
  569. * @param owner
  570. *
  571. * @return An Integer representation of the enumerated value if this attribute does not support
  572. * AVT. Otherwise, and AVT is returned.
  573. */
  574. Object processENUM(StylesheetHandler handler, String uri, String name,
  575. String rawName, String value, ElemTemplateElement owner)
  576. throws org.xml.sax.SAXException
  577. {
  578. AVT avt = null;
  579. if (getSupportsAVT()) {
  580. try
  581. {
  582. avt = new AVT(handler, uri, name, rawName, value, owner);
  583. // If this attribute used an avt, then we can't validate at this time.
  584. if (!avt.isSimple()) return avt;
  585. }
  586. catch (TransformerException te)
  587. {
  588. throw new org.xml.sax.SAXException(te);
  589. }
  590. }
  591. int retVal = this.getEnum(value);
  592. if (retVal == StringToIntTable.INVALID_KEY)
  593. {
  594. StringBuffer enumNamesList = getListOfEnums();
  595. handleError(handler, XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },null);
  596. return null;
  597. }
  598. if (getSupportsAVT()) return avt;
  599. else return new Integer(retVal);
  600. }
  601. /**
  602. * Process an attribute string of that is either an enumerated value or a qname-but-not-ncname.
  603. * Returns an AVT, if this attribute support AVT; otherwise returns int or qname.
  604. *
  605. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  606. * @param uri The Namespace URI, or an empty string.
  607. * @param name The local name (without prefix), or empty string if not namespace processing.
  608. * @param rawName The qualified name (with prefix).
  609. * @param value non-null string that represents an enumerated value that is
  610. * valid for this element.
  611. * @param owner
  612. *
  613. * @return AVT if attribute supports AVT. An Integer representation of the enumerated value if
  614. * attribute does not support AVT and an enumerated value was used. Otherwise a qname
  615. * is returned.
  616. */
  617. Object processENUM_OR_PQNAME(StylesheetHandler handler, String uri, String name,
  618. String rawName, String value, ElemTemplateElement owner)
  619. throws org.xml.sax.SAXException
  620. {
  621. Object objToReturn = null;
  622. if (getSupportsAVT()) {
  623. try
  624. {
  625. AVT avt = new AVT(handler, uri, name, rawName, value, owner);
  626. if (!avt.isSimple()) return avt;
  627. else objToReturn = avt;
  628. }
  629. catch (TransformerException te)
  630. {
  631. throw new org.xml.sax.SAXException(te);
  632. }
  633. }
  634. // An avt wasn't used.
  635. int enum = this.getEnum(value);
  636. if (enum != StringToIntTable.INVALID_KEY)
  637. {
  638. if (objToReturn == null) objToReturn = new Integer(enum);
  639. }
  640. // enum not used. Validate qname-but-not-ncname.
  641. else
  642. {
  643. try
  644. {
  645. QName qname = new QName(value, handler, true);
  646. if (objToReturn == null) objToReturn = qname;
  647. if (qname.getPrefix() == null) {
  648. StringBuffer enumNamesList = getListOfEnums();
  649. enumNamesList.append(" <qname-but-not-ncname>");
  650. handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },null);
  651. return null;
  652. }
  653. }
  654. catch (IllegalArgumentException ie)
  655. {
  656. StringBuffer enumNamesList = getListOfEnums();
  657. enumNamesList.append(" <qname-but-not-ncname>");
  658. handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },ie);
  659. return null;
  660. }
  661. catch (RuntimeException re)
  662. {
  663. StringBuffer enumNamesList = getListOfEnums();
  664. enumNamesList.append(" <qname-but-not-ncname>");
  665. handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },re);
  666. return null;
  667. }
  668. }
  669. return objToReturn;
  670. }
  671. /**
  672. * Process an attribute string of type T_EXPR into
  673. * an XPath value.
  674. *
  675. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  676. * @param uri The Namespace URI, or an empty string.
  677. * @param name The local name (without prefix), or empty string if not namespace processing.
  678. * @param rawName The qualified name (with prefix).
  679. * @param value An XSLT expression string.
  680. *
  681. * @return an XPath object that may be used for evaluation.
  682. *
  683. * @throws org.xml.sax.SAXException that wraps a
  684. * {@link javax.xml.transform.TransformerException} if the expression
  685. * string contains a syntax error.
  686. */
  687. Object processEXPR(
  688. StylesheetHandler handler, String uri, String name, String rawName, String value,
  689. ElemTemplateElement owner)
  690. throws org.xml.sax.SAXException
  691. {
  692. try
  693. {
  694. XPath expr = handler.createXPath(value, owner);
  695. return expr;
  696. }
  697. catch (TransformerException te)
  698. {
  699. org.xml.sax.SAXException se = new org.xml.sax.SAXException(te);
  700. throw new org.xml.sax.SAXException(te);
  701. }
  702. }
  703. /**
  704. * Process an attribute string of type T_NMTOKEN into
  705. * a String value.
  706. *
  707. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  708. * @param uri The Namespace URI, or an empty string.
  709. * @param name The local name (without prefix), or empty string if not namespace processing.
  710. * @param rawName The qualified name (with prefix).
  711. * @param value A NMTOKEN string.
  712. *
  713. * @return the value argument or an AVT if this attribute supports AVTs.
  714. *
  715. * @throws org.xml.sax.SAXException if the value is not a valid nmtoken
  716. */
  717. Object processNMTOKEN(StylesheetHandler handler, String uri, String name,
  718. String rawName, String value, ElemTemplateElement owner)
  719. throws org.xml.sax.SAXException
  720. {
  721. if (getSupportsAVT()) {
  722. try
  723. {
  724. AVT avt = new AVT(handler, uri, name, rawName, value, owner);
  725. // If an AVT wasn't used, validate the value
  726. if ((avt.isSimple()) && (!XMLChar.isValidNmtoken(value))) {
  727. handleError(handler,XSLTErrorResources.INVALID_NMTOKEN, new Object[] {name,value},null);
  728. return null;
  729. }
  730. return avt;
  731. }
  732. catch (TransformerException te)
  733. {
  734. throw new org.xml.sax.SAXException(te);
  735. }
  736. } else {
  737. if (!XMLChar.isValidNmtoken(value)) {
  738. handleError(handler,XSLTErrorResources.INVALID_NMTOKEN, new Object[] {name,value},null);
  739. return null;
  740. }
  741. }
  742. return value;
  743. }
  744. /**
  745. * Process an attribute string of type T_PATTERN into
  746. * an XPath match pattern value.
  747. *
  748. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  749. * @param uri The Namespace URI, or an empty string.
  750. * @param name The local name (without prefix), or empty string if not namespace processing.
  751. * @param rawName The qualified name (with prefix).
  752. * @param value A match pattern string.
  753. *
  754. * @return An XPath pattern that may be used to evaluate the XPath.
  755. *
  756. * @throws org.xml.sax.SAXException that wraps a
  757. * {@link javax.xml.transform.TransformerException} if the match pattern
  758. * string contains a syntax error.
  759. */
  760. Object processPATTERN(
  761. StylesheetHandler handler, String uri, String name, String rawName, String value,
  762. ElemTemplateElement owner)
  763. throws org.xml.sax.SAXException
  764. {
  765. try
  766. {
  767. XPath pattern = handler.createMatchPatternXPath(value, owner);
  768. return pattern;
  769. }
  770. catch (TransformerException te)
  771. {
  772. throw new org.xml.sax.SAXException(te);
  773. }
  774. }
  775. /**
  776. * Process an attribute string of type T_NUMBER into
  777. * a double value.
  778. *
  779. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  780. * @param uri The Namespace URI, or an empty string.
  781. * @param name The local name (without prefix), or empty string if not namespace processing.
  782. * @param rawName The qualified name (with prefix).
  783. * @param value A string that can be parsed into a double value.
  784. * @param number
  785. *
  786. * @return A Double object.
  787. *
  788. * @throws org.xml.sax.SAXException that wraps a
  789. * {@link javax.xml.transform.TransformerException}
  790. * if the string does not contain a parsable number.
  791. */
  792. Object processNUMBER(
  793. StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
  794. throws org.xml.sax.SAXException
  795. {
  796. if (getSupportsAVT())
  797. {
  798. Double val;
  799. AVT avt = null;
  800. try
  801. {
  802. avt = new AVT(handler, uri, name, rawName, value, owner);
  803. // If this attribute used an avt, then we can't validate at this time.
  804. if (avt.isSimple())
  805. {
  806. val = Double.valueOf(value);
  807. }
  808. }
  809. catch (TransformerException te)
  810. {
  811. throw new org.xml.sax.SAXException(te);
  812. }
  813. catch (NumberFormatException nfe)
  814. {
  815. handleError(handler,XSLTErrorResources.INVALID_NUMBER, new Object[] {name, value}, nfe);
  816. return null;
  817. }
  818. return avt;
  819. }
  820. else
  821. {
  822. try
  823. {
  824. return Double.valueOf(value);
  825. }
  826. catch (NumberFormatException nfe)
  827. {
  828. handleError(handler,XSLTErrorResources.INVALID_NUMBER, new Object[] {name, value}, nfe);
  829. return null;
  830. }
  831. }
  832. }
  833. /**
  834. * Process an attribute string of type T_QNAME into a QName value.
  835. *
  836. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  837. * @param uri The Namespace URI, or an empty string.
  838. * @param name The local name (without prefix), or empty string if not namespace processing.
  839. * @param rawName The qualified name (with prefix).
  840. * @param value A string that represents a potentially prefix qualified name.
  841. * @param owner
  842. *
  843. * @return A QName object if this attribute does not support AVT's. Otherwise, an AVT
  844. * is returned.
  845. *
  846. * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
  847. * resolved, or the string contains syntax that is invalid for a qualified name.
  848. */
  849. Object processQNAME(
  850. StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
  851. throws org.xml.sax.SAXException
  852. {
  853. try
  854. {
  855. QName qname = new QName(value, handler, true);
  856. return qname;
  857. }
  858. catch (IllegalArgumentException ie)
  859. {
  860. // thrown by QName constructor
  861. handleError(handler,XSLTErrorResources.INVALID_QNAME, new Object[] {name, value},ie);
  862. return null;
  863. }
  864. catch (RuntimeException re) {
  865. // thrown by QName constructor
  866. handleError(handler,XSLTErrorResources.INVALID_QNAME, new Object[] {name, value},re);
  867. return null;
  868. }
  869. }
  870. /**
  871. * Process an attribute string of type T_QNAME into a QName value.
  872. *
  873. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  874. * @param uri The Namespace URI, or an empty string.
  875. * @param name The local name (without prefix), or empty string if not namespace processing.
  876. * @param rawName The qualified name (with prefix).
  877. * @param value A string that represents a potentially prefix qualified name.
  878. * @param owner
  879. *
  880. * @return An AVT is returned.
  881. *
  882. * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
  883. * resolved, or the string contains syntax that is invalid for a qualified name.
  884. */
  885. Object processAVT_QNAME(
  886. StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
  887. throws org.xml.sax.SAXException
  888. {
  889. AVT avt = null;
  890. try
  891. {
  892. avt = new AVT(handler, uri, name, rawName, value, owner);
  893. // If an AVT wasn't used, validate the value
  894. if (avt.isSimple())
  895. {
  896. int indexOfNSSep = value.indexOf(':');
  897. if (indexOfNSSep >= 0)
  898. {
  899. String prefix = value.substring(0, indexOfNSSep);
  900. if (!XMLChar.isValidNCName(prefix))
  901. {
  902. handleError(handler,XSLTErrorResources.INVALID_QNAME,new Object[]{name,value },null);
  903. return null;
  904. }
  905. }
  906. String localName = (indexOfNSSep < 0)
  907. ? value : value.substring(indexOfNSSep + 1);
  908. if ((localName == null) || (localName.length() == 0) ||
  909. (!XMLChar.isValidNCName(localName)))
  910. {
  911. handleError(handler,XSLTErrorResources.INVALID_QNAME,new Object[]{name,value },null );
  912. return null;
  913. }
  914. }
  915. }
  916. catch (TransformerException te)
  917. {
  918. // thrown by AVT constructor
  919. throw new org.xml.sax.SAXException(te);
  920. }
  921. return avt;
  922. }
  923. /**
  924. * Process an attribute string of type NCName into a String
  925. *
  926. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  927. * @param uri The Namespace URI, or an empty string.
  928. * @param name The local name (without prefix), or empty string if not namespace processing.
  929. * @param rawName The qualified name (with prefix).
  930. * @param value A string that represents a potentially prefix qualified name.
  931. * @param owner
  932. *
  933. * @return A String object if this attribute does not support AVT's. Otherwise, an AVT
  934. * is returned.
  935. *
  936. * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
  937. * resolved, or the string contains syntax that is invalid for a NCName.
  938. */
  939. Object processNCNAME(
  940. StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
  941. throws org.xml.sax.SAXException
  942. {
  943. if (getSupportsAVT())
  944. {
  945. AVT avt = null;
  946. try
  947. {
  948. avt = new AVT(handler, uri, name, rawName, value, owner);
  949. // If an AVT wasn't used, validate the value
  950. if ((avt.isSimple()) && (!XMLChar.isValidNCName(value)))
  951. {
  952. handleError(handler,XSLTErrorResources.INVALID_NCNAME,new Object[] {name,value},null);
  953. return null;
  954. }
  955. return avt;
  956. }
  957. catch (TransformerException te)
  958. {
  959. // thrown by AVT constructor
  960. throw new org.xml.sax.SAXException(te);
  961. }
  962. } else {
  963. if (!XMLChar.isValidNCName(value))
  964. {
  965. handleError(handler,XSLTErrorResources.INVALID_NCNAME,new Object[] {name,value},null);
  966. return null;
  967. }
  968. return value;
  969. }
  970. }
  971. /**
  972. * Process an attribute string of type T_QNAMES into a vector of QNames where
  973. * the specification requires that non-prefixed elements not be placed in a
  974. * namespace. (See section 2.4 of XSLT 1.0.)
  975. *
  976. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  977. * @param uri The Namespace URI, or an empty string.
  978. * @param name The local name (without prefix), or empty string if not namespace processing.
  979. * @param rawName The qualified name (with prefix).
  980. * @param value A whitespace delimited list of qualified names.
  981. *
  982. * @return a Vector of QName objects.
  983. *
  984. * @throws org.xml.sax.SAXException if the one of the qualified name strings
  985. * contains a prefix that can not be
  986. * resolved, or a qualified name contains syntax that is invalid for a qualified name.
  987. */
  988. Vector processQNAMES(
  989. StylesheetHandler handler, String uri, String name, String rawName, String value)
  990. throws org.xml.sax.SAXException
  991. {
  992. StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
  993. int nQNames = tokenizer.countTokens();
  994. Vector qnames = new Vector(nQNames);
  995. for (int i = 0; i < nQNames; i++)
  996. {
  997. // Fix from Alexander Rudnev
  998. qnames.addElement(new QName(tokenizer.nextToken(), handler));
  999. }
  1000. return qnames;
  1001. }
  1002. /**
  1003. * Process an attribute string of type T_QNAMES_RESOLVE_NULL into a vector
  1004. * of QNames where the specification requires non-prefixed elements to be
  1005. * placed in the default namespace. (See section 16 of XSLT 1.0; the
  1006. * <em>only</em> time that this will get called is for the
  1007. * <code>cdata-section-elements</code> attribute on <code>xsl:output</code>.
  1008. *
  1009. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1010. * @param uri The Namespace URI, or an empty string.
  1011. * @param name The local name (without prefix), or empty string if not namespace processing.
  1012. * @param rawName The qualified name (with prefix).
  1013. * @param value A whitespace delimited list of qualified names.
  1014. *
  1015. * @return a Vector of QName objects.
  1016. *
  1017. * @throws org.xml.sax.SAXException if the one of the qualified name strings
  1018. * contains a prefix that can not be resolved, or a qualified name contains
  1019. * syntax that is invalid for a qualified name.
  1020. */
  1021. final Vector processQNAMESRNU(StylesheetHandler handler, String uri,
  1022. String name, String rawName, String value)
  1023. throws org.xml.sax.SAXException
  1024. {
  1025. StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
  1026. int nQNames = tokenizer.countTokens();
  1027. Vector qnames = new Vector(nQNames);
  1028. String defaultURI = handler.getNamespaceForPrefix("");
  1029. for (int i = 0; i < nQNames; i++)
  1030. {
  1031. String tok = tokenizer.nextToken();
  1032. if (tok.indexOf(':') == -1) {
  1033. qnames.addElement(new QName(defaultURI,tok));
  1034. } else {
  1035. qnames.addElement(new QName(tok, handler));
  1036. }
  1037. }
  1038. return qnames;
  1039. }
  1040. /**
  1041. * Process an attribute string of type T_SIMPLEPATTERNLIST into
  1042. * a vector of XPath match patterns.
  1043. *
  1044. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1045. * @param uri The Namespace URI, or an empty string.
  1046. * @param name The local name (without prefix), or empty string if not namespace processing.
  1047. * @param rawName The qualified name (with prefix).
  1048. * @param value A whitespace delimited list of simple match patterns.
  1049. *
  1050. * @return A Vector of XPath objects.
  1051. *
  1052. * @throws org.xml.sax.SAXException that wraps a
  1053. * {@link javax.xml.transform.TransformerException} if one of the match pattern
  1054. * strings contains a syntax error.
  1055. */
  1056. Vector processSIMPLEPATTERNLIST(
  1057. StylesheetHandler handler, String uri, String name, String rawName, String value,
  1058. ElemTemplateElement owner)
  1059. throws org.xml.sax.SAXException
  1060. {
  1061. try
  1062. {
  1063. StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
  1064. int nPatterns = tokenizer.countTokens();
  1065. Vector patterns = new Vector(nPatterns);
  1066. for (int i = 0; i < nPatterns; i++)
  1067. {
  1068. XPath pattern =
  1069. handler.createMatchPatternXPath(tokenizer.nextToken(), owner);
  1070. patterns.addElement(pattern);
  1071. }
  1072. return patterns;
  1073. }
  1074. catch (TransformerException te)
  1075. {
  1076. throw new org.xml.sax.SAXException(te);
  1077. }
  1078. }
  1079. /**
  1080. * Process an attribute string of type T_STRINGLIST into
  1081. * a vector of XPath match patterns.
  1082. *
  1083. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1084. * @param uri The Namespace URI, or an empty string.
  1085. * @param name The local name (without prefix), or empty string if not namespace processing.
  1086. * @param rawName The qualified name (with prefix).
  1087. * @param value a whitespace delimited list of string values.
  1088. *
  1089. * @return A StringVector of the tokenized strings.
  1090. */
  1091. StringVector processSTRINGLIST(StylesheetHandler handler, String uri,
  1092. String name, String rawName, String value)
  1093. {
  1094. StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
  1095. int nStrings = tokenizer.countTokens();
  1096. StringVector strings = new StringVector(nStrings);
  1097. for (int i = 0; i < nStrings; i++)
  1098. {
  1099. strings.addElement(tokenizer.nextToken());
  1100. }
  1101. return strings;
  1102. }
  1103. /**
  1104. * Process an attribute string of type T_URLLIST into
  1105. * a vector of prefixes that may be resolved to URLs.
  1106. *
  1107. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1108. * @param uri The Namespace URI, or an empty string.
  1109. * @param name The local name (without prefix), or empty string if not namespace processing.
  1110. * @param rawName The qualified name (with prefix).
  1111. * @param value A list of whitespace delimited prefixes.
  1112. *
  1113. * @return A vector of strings that may be resolved to URLs.
  1114. *
  1115. * @throws org.xml.sax.SAXException if one of the prefixes can not be resolved.
  1116. */
  1117. StringVector processPREFIX_URLLIST(
  1118. StylesheetHandler handler, String uri, String name, String rawName, String value)
  1119. throws org.xml.sax.SAXException
  1120. {
  1121. StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
  1122. int nStrings = tokenizer.countTokens();
  1123. StringVector strings = new StringVector(nStrings);
  1124. for (int i = 0; i < nStrings; i++)
  1125. {
  1126. String prefix = tokenizer.nextToken();
  1127. String url = handler.getNamespaceForPrefix(prefix);
  1128. if (url != null)
  1129. strings.addElement(url);
  1130. else
  1131. throw new org.xml.sax.SAXException(XSLMessages.createMessage(XSLTErrorResources.ER_CANT_RESOLVE_NSPREFIX, new Object[] {prefix}));
  1132. }
  1133. return strings;
  1134. }
  1135. /**
  1136. * Process an attribute string of type T_URL into
  1137. * a URL value.
  1138. *
  1139. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1140. * @param uri The Namespace URI, or an empty string.
  1141. * @param name The local name (without prefix), or empty string if not namespace processing.
  1142. * @param rawName The qualified name (with prefix).
  1143. * @param value non-null string that conforms to the URL syntax.
  1144. *
  1145. * @return The non-absolutized URL argument, in other words, the value argument. If this
  1146. * attribute supports AVT, an AVT is returned.
  1147. *
  1148. * @throws org.xml.sax.SAXException if the URL does not conform to the URL syntax.
  1149. */
  1150. Object processURL(
  1151. StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
  1152. throws org.xml.sax.SAXException
  1153. {
  1154. if (getSupportsAVT()) {
  1155. try
  1156. {
  1157. AVT avt = new AVT(handler, uri, name, rawName, value, owner);
  1158. // If an AVT wasn't used, validate the value
  1159. // if (avt.getSimpleString() != null) {
  1160. // TODO: syntax check URL value.
  1161. // return SystemIDResolver.getAbsoluteURI(value,
  1162. // handler.getBaseIdentifier());
  1163. //}
  1164. return avt;
  1165. }
  1166. catch (TransformerException te)
  1167. {
  1168. throw new org.xml.sax.SAXException(te);
  1169. }
  1170. } else {
  1171. // TODO: syntax check URL value.
  1172. // return SystemIDResolver.getAbsoluteURI(value,
  1173. // handler.getBaseIdentifier());
  1174. return value;
  1175. }
  1176. }
  1177. /**
  1178. * Process an attribute string of type T_YESNO into
  1179. * a Boolean value.
  1180. *
  1181. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1182. * @param uri The Namespace URI, or an empty string.
  1183. * @param name The local name (without prefix), or empty string if not namespace processing.
  1184. * @param rawName The qualified name (with prefix).
  1185. * @param value A string that should be "yes" or "no".
  1186. *
  1187. * @return Boolean object representation of the value.
  1188. *
  1189. * @throws org.xml.sax.SAXException
  1190. */
  1191. private Boolean processYESNO(
  1192. StylesheetHandler handler, String uri, String name, String rawName, String value)
  1193. throws org.xml.sax.SAXException
  1194. {
  1195. // Is this already checked somewhere else? -sb
  1196. if (!(value.equals("yes") || value.equals("no")))
  1197. {
  1198. handleError(handler, XSLTErrorResources.INVALID_BOOLEAN, new Object[] {name,value}, null);
  1199. return null;
  1200. }
  1201. return new Boolean(value.equals("yes") ? true : false);
  1202. }
  1203. /**
  1204. * Process an attribute value.
  1205. *
  1206. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1207. * @param uri The Namespace URI, or an empty string.
  1208. * @param name The local name (without prefix), or empty string if not namespace processing.
  1209. * @param rawName The qualified name (with prefix).
  1210. * @param value The unprocessed string value of the attribute.
  1211. *
  1212. * @return The processed Object representation of the attribute.
  1213. *
  1214. * @throws org.xml.sax.SAXException if the attribute value can not be processed.
  1215. */
  1216. Object processValue(
  1217. StylesheetHandler handler, String uri, String name, String rawName, String value,
  1218. ElemTemplateElement owner)
  1219. throws org.xml.sax.SAXException
  1220. {
  1221. int type = getType();
  1222. Object processedValue = null;
  1223. switch (type)
  1224. {
  1225. case T_AVT :
  1226. processedValue = processAVT(handler, uri, name, rawName, value, owner);
  1227. break;
  1228. case T_CDATA :
  1229. processedValue = processCDATA(handler, uri, name, rawName, value, owner);
  1230. break;
  1231. case T_CHAR :
  1232. processedValue = processCHAR(handler, uri, name, rawName, value, owner);
  1233. break;
  1234. case T_ENUM :
  1235. processedValue = processENUM(handler, uri, name, rawName, value, owner);
  1236. break;
  1237. case T_EXPR :
  1238. processedValue = processEXPR(handler, uri, name, rawName, value, owner);
  1239. break;
  1240. case T_NMTOKEN :
  1241. processedValue = processNMTOKEN(handler, uri, name, rawName, value, owner);
  1242. break;
  1243. case T_PATTERN :
  1244. processedValue = processPATTERN(handler, uri, name, rawName, value, owner);
  1245. break;
  1246. case T_NUMBER :
  1247. processedValue = processNUMBER(handler, uri, name, rawName, value, owner);
  1248. break;
  1249. case T_QNAME :
  1250. processedValue = processQNAME(handler, uri, name, rawName, value, owner);
  1251. break;
  1252. case T_QNAMES :
  1253. processedValue = processQNAMES(handler, uri, name, rawName, value);
  1254. break;
  1255. case T_QNAMES_RESOLVE_NULL:
  1256. processedValue = processQNAMESRNU(handler, uri, name, rawName, value);
  1257. break;
  1258. case T_SIMPLEPATTERNLIST :
  1259. processedValue = processSIMPLEPATTERNLIST(handler, uri, name, rawName,
  1260. value, owner);
  1261. break;
  1262. case T_URL :
  1263. processedValue = processURL(handler, uri, name, rawName, value, owner);
  1264. break;
  1265. case T_YESNO :
  1266. processedValue = processYESNO(handler, uri, name, rawName, value);
  1267. break;
  1268. case T_STRINGLIST :
  1269. processedValue = processSTRINGLIST(handler, uri, name, rawName, value);
  1270. break;
  1271. case T_PREFIX_URLLIST :
  1272. processedValue = processPREFIX_URLLIST(handler, uri, name, rawName,
  1273. value);
  1274. break;
  1275. case T_ENUM_OR_PQNAME :
  1276. processedValue = processENUM_OR_PQNAME(handler, uri, name, rawName, value, owner);
  1277. break;
  1278. case T_NCNAME :
  1279. processedValue = processNCNAME(handler, uri, name, rawName, value, owner);
  1280. break;
  1281. case T_AVT_QNAME :
  1282. processedValue = processAVT_QNAME(handler, uri, name, rawName, value, owner);
  1283. break;
  1284. default :
  1285. }
  1286. return processedValue;
  1287. }
  1288. /**
  1289. * Set the default value of an attribute.
  1290. *
  1291. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1292. * @param elem The object on which the property will be set.
  1293. *
  1294. * @throws org.xml.sax.SAXException wraps an invocation exception if the
  1295. * setter method can not be invoked on the object.
  1296. */
  1297. void setDefAttrValue(StylesheetHandler handler, ElemTemplateElement elem)
  1298. throws org.xml.sax.SAXException
  1299. {
  1300. setAttrValue(handler, this.getNamespace(), this.getName(),
  1301. this.getName(), this.getDefault(), elem);
  1302. }
  1303. /**
  1304. * Get the primative type for the class, if there
  1305. * is one. If the class is a Double, for instance,
  1306. * this will return double.class. If the class is not one
  1307. * of the 9 primative types, it will return the same
  1308. * class that was passed in.
  1309. *
  1310. * @param obj The object which will be resolved to a primative class object if possible.
  1311. *
  1312. * @return The most primative class representation possible for the object, never null.
  1313. */
  1314. private Class getPrimativeClass(Object obj)
  1315. {
  1316. if (obj instanceof XPath)
  1317. return XPath.class;
  1318. Class cl = obj.getClass();
  1319. if (cl == Double.class)
  1320. {
  1321. cl = double.class;
  1322. }
  1323. if (cl == Float.class)
  1324. {
  1325. cl = float.class;
  1326. }
  1327. else if (cl == Boolean.class)
  1328. {
  1329. cl = boolean.class;
  1330. }
  1331. else if (cl == Byte.class)
  1332. {
  1333. cl = byte.class;
  1334. }
  1335. else if (cl == Character.class)
  1336. {
  1337. cl = char.class;
  1338. }
  1339. else if (cl == Short.class)
  1340. {
  1341. cl = short.class;
  1342. }
  1343. else if (cl == Integer.class)
  1344. {
  1345. cl = int.class;
  1346. }
  1347. else if (cl == Long.class)
  1348. {
  1349. cl = long.class;
  1350. }
  1351. return cl;
  1352. }
  1353. /**
  1354. * StringBuffer containing comma delimited list of valid values for ENUM type.
  1355. * Used to build error message.
  1356. */
  1357. private StringBuffer getListOfEnums()
  1358. {
  1359. StringBuffer enumNamesList = new StringBuffer();
  1360. String [] enumValues = this.getEnumNames();
  1361. for (int i = 0; i < enumValues.length; i++)
  1362. {
  1363. if (i > 0)
  1364. {
  1365. enumNamesList.append(' ');
  1366. }
  1367. enumNamesList.append(enumValues[i]);
  1368. }
  1369. return enumNamesList;
  1370. }
  1371. /**
  1372. * Set a value on an attribute.
  1373. *
  1374. * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
  1375. * @param attrUri The Namespace URI of the attribute, or an empty string.
  1376. * @param attrLocalName The local name (without prefix), or empty string if not namespace processing.
  1377. * @param attrRawName The raw name of the attribute, including possible prefix.
  1378. * @param attrValue The attribute's value.
  1379. * @param elem The object that should contain a property that represents the attribute.
  1380. *
  1381. * @throws org.xml.sax.SAXException
  1382. */
  1383. boolean setAttrValue(
  1384. StylesheetHandler handler, String attrUri, String attrLocalName,
  1385. String attrRawName, String attrValue, ElemTemplateElement elem)
  1386. throws org.xml.sax.SAXException
  1387. {
  1388. if(attrRawName.equals("xmlns") || attrRawName.startsWith("xmlns:"))
  1389. return true;
  1390. String setterString = getSetterMethodName();
  1391. // If this is null, then it is a foreign namespace and we
  1392. // do not process it.
  1393. if (null != setterString)
  1394. {
  1395. try
  1396. {
  1397. Method meth;
  1398. Object[] args;
  1399. if(setterString.equals(S_FOREIGNATTR_SETTER))
  1400. {
  1401. // workaround for possible crimson bug
  1402. if( attrUri==null) attrUri="";
  1403. // First try to match with the primative value.
  1404. Class sclass = attrUri.getClass();
  1405. Class[] argTypes = new Class[]{ sclass, sclass,
  1406. sclass, sclass };
  1407. meth = elem.getClass().getMethod(setterString, argTypes);
  1408. args = new Object[]{ attrUri, attrLocalName,
  1409. attrRawName, attrValue };
  1410. }
  1411. else
  1412. {
  1413. Object value = processValue(handler, attrUri, attrLocalName,
  1414. attrRawName, attrValue, elem);
  1415. // If a warning was issued because the value for this attribute was
  1416. // invalid, then the value will be null. Just return
  1417. if (null == value) return false;
  1418. // First try to match with the primative value.
  1419. Class[] argTypes = new Class[]{ getPrimativeClass(value) };
  1420. try
  1421. {
  1422. meth = elem.getClass().getMethod(setterString, argTypes);
  1423. }
  1424. catch (NoSuchMethodException nsme)
  1425. {
  1426. Class cl = ((Object) value).getClass();
  1427. // If this doesn't work, try it with the non-primative value;
  1428. argTypes[0] = cl;
  1429. meth = elem.getClass().getMethod(setterString, argTypes);
  1430. }
  1431. args = new Object[]{ value };
  1432. }
  1433. meth.invoke(elem, args);
  1434. }
  1435. catch (NoSuchMethodException nsme)
  1436. {
  1437. if (!setterString.equals(S_FOREIGNATTR_SETTER))
  1438. {
  1439. handler.error(XSLTErrorResources.ER_FAILED_CALLING_METHOD, new Object[]{setterString}, nsme);//"Failed calling " + setterString + " method!", nsme);
  1440. return false;
  1441. }
  1442. }
  1443. catch (IllegalAccessException iae)
  1444. {
  1445. handler.error(XSLTErrorResources.ER_FAILED_CALLING_METHOD, new Object[]{setterString}, iae);//"Failed calling " + setterString + " method!", iae);
  1446. return false;
  1447. }
  1448. catch (InvocationTargetException nsme)
  1449. {
  1450. handleError(handler, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
  1451. new Object[]{ Constants.ATTRNAME_NAME, getName()}, nsme);
  1452. return false;
  1453. }
  1454. }
  1455. return true;
  1456. }
  1457. private void handleError(StylesheetHandler handler, String msg, Object [] args, Exception exc) throws org.xml.sax.SAXException
  1458. {
  1459. switch (getErrorType())
  1460. {
  1461. case (FATAL):
  1462. case (ERROR):
  1463. handler.error(msg, args, exc);
  1464. break;
  1465. case (WARNING):
  1466. handler.warn(msg, args);
  1467. default: break;
  1468. }
  1469. }
  1470. }