Home | History | Annotate | Download | only in processor
      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    */
     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    */
     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     */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
   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    */
   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    */
   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    */
   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    */
   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    */
   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     */
   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    */
   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    */
   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    */
   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    */
   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    */
   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    */
   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    */
   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 
   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