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