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 }