001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: XSLTAttributeDef.java 468640 2006-10-28 06:53:53Z minchau $
020 */
021 package org.apache.xalan.processor;
022
023 import java.lang.reflect.InvocationTargetException;
024 import java.lang.reflect.Method;
025 import java.util.StringTokenizer;
026 import java.util.Vector;
027
028 import javax.xml.transform.TransformerException;
029
030 import org.apache.xalan.res.XSLMessages;
031 import org.apache.xalan.res.XSLTErrorResources;
032 import org.apache.xalan.templates.AVT;
033 import org.apache.xalan.templates.Constants;
034 import org.apache.xalan.templates.ElemTemplateElement;
035 import org.apache.xml.utils.QName;
036 import org.apache.xml.utils.StringToIntTable;
037 import org.apache.xml.utils.StringVector;
038 import org.apache.xml.utils.XML11Char;
039 import org.apache.xpath.XPath;
040
041
042 /**
043 * This class defines an attribute for an element in a XSLT stylesheet,
044 * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
045 * mapping between Xalan classes and the markup attributes in the element.
046 */
047 public class XSLTAttributeDef
048 {
049 // How to handle invalid values for this attribute
050 static final int FATAL = 0;
051 static final int ERROR = 1;
052 static final int WARNING = 2;
053
054
055 /**
056 * Construct an instance of XSLTAttributeDef.
057 *
058 * @param namespace The Namespace URI, or an empty string.
059 * @param name The local name (without prefix), or empty string if not namespace processing.
060 * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
061 * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
062 * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME, T_NCNAME.
063 * @param required true if this is attribute is required by the XSLT specification.
064 * @param supportsAVT true if this attribute supports AVT's.
065 * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING.
066 */
067 XSLTAttributeDef(String namespace, String name, int type, boolean required, boolean supportsAVT, int errorType)
068 {
069 this.m_namespace = namespace;
070 this.m_name = name;
071 this.m_type = type;
072 this.m_required = required;
073 this.m_supportsAVT = supportsAVT;
074 this.m_errorType = errorType;
075 }
076
077 /**
078 * Construct an instance of XSLTAttributeDef.
079 *
080 * @param namespace The Namespace URI, or an empty string.
081 * @param name The local name (without prefix), or empty string if not namespace processing.
082 * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR,
083 * T_CHAR, T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM,
084 * T_SIMPLEPATTERNLIST, T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST,
085 * T_ENUM_OR_PQNAME, T_NCNAME.
086 * @param supportsAVT true if this attribute supports AVT's.
087 * @param errorType the type of error to issue if validation fails. One of FATAL, ERROR, WARNING.
088 * @param defaultVal The default value for this attribute.
089 */
090 XSLTAttributeDef(String namespace, String name, int type, boolean supportsAVT, int errorType, String defaultVal)
091 {
092
093 this.m_namespace = namespace;
094 this.m_name = name;
095 this.m_type = type;
096 this.m_required = false;
097 this.m_supportsAVT = supportsAVT;
098 this.m_errorType = errorType;
099 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 }