IIOMetadataFormatImpl.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package javax.imageio.metadata; 19 20import javax.imageio.ImageTypeSpecifier; 21import java.util.*; 22import java.security.AccessController; 23import java.security.PrivilegedAction; 24 25/** 26 * The IIOMetadataFormatImpl class provides an implementation of the 27 * IIOMetadataFormat interface. 28 * 29 * @since Android 1.0 30 */ 31public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat { 32 33 /** 34 * The Constant standardMetadataFormatName. 35 */ 36 @SuppressWarnings( { 37 "ConstantDeclaredInAbstractClass" 38 }) 39 public static final String standardMetadataFormatName = "javax_imageio_1.0"; 40 41 /** 42 * The standard format. 43 */ 44 @SuppressWarnings( { 45 "StaticNonFinalField" 46 }) 47 private static IIOMetadataFormatImpl standardFormat; 48 49 /** 50 * The root name. 51 */ 52 private String rootName; 53 54 /** 55 * The element hash. 56 */ 57 private HashMap<String, Element> elementHash = new HashMap<String, Element>(); 58 59 /** 60 * The resource base name. 61 */ 62 private String resourceBaseName = getClass().getName() + "Resources"; 63 64 /** 65 * Instantiates an IIOMetadataFormatImpl with the specified root name and 66 * child policy (not CHILD_POLICY_REPEAT). 67 * 68 * @param rootName 69 * the name of root element. 70 * @param childPolicy 71 * the child policy defined by one of the CHILD_POLICY_* 72 * constants (except CHILD_POLICY_REPEAT). 73 */ 74 public IIOMetadataFormatImpl(String rootName, int childPolicy) { 75 if (rootName == null) { 76 throw new IllegalArgumentException("rootName is null"); 77 } 78 if (childPolicy < CHILD_POLICY_EMPTY || childPolicy > CHILD_POLICY_MAX 79 || childPolicy == CHILD_POLICY_REPEAT) { 80 throw new IllegalArgumentException("childPolicy is not one of the predefined constants"); 81 } 82 83 this.rootName = rootName; 84 Element root = new Element(); 85 root.name = rootName; 86 root.childPolicy = childPolicy; 87 elementHash.put(rootName, root); 88 } 89 90 /** 91 * Instantiates an IIOMetadataFormatImpl with the specified root name and 92 * CHILD_POLICY_REPEAT child policy. 93 * 94 * @param rootName 95 * the name of root element. 96 * @param minChildren 97 * the minimum number of children. 98 * @param maxChildren 99 * the maximum number of children 100 */ 101 public IIOMetadataFormatImpl(String rootName, int minChildren, int maxChildren) { 102 if (rootName == null) { 103 throw new IllegalArgumentException("rootName is null"); 104 } 105 if (minChildren < 0) { 106 throw new IllegalArgumentException("minChildren < 0!"); 107 } 108 if (minChildren > maxChildren) { 109 throw new IllegalArgumentException("minChildren > maxChildren!"); 110 } 111 112 this.rootName = rootName; 113 Element root = new Element(); 114 root.name = rootName; 115 root.minChildren = minChildren; 116 root.maxChildren = maxChildren; 117 root.childPolicy = CHILD_POLICY_REPEAT; 118 elementHash.put(rootName, root); 119 } 120 121 @SuppressWarnings( { 122 "AbstractMethodOverridesAbstractMethod" 123 }) 124 public abstract boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType); 125 126 /** 127 * Adds a new attribute to an existing element. 128 * 129 * @param elementName 130 * the name of the element to which the new attribute will be 131 * added. 132 * @param attrName 133 * the attribute name. 134 * @param dataType 135 * the data type of the new attribute. 136 * @param required 137 * the flag which indicates whether this attribute must be 138 * present. 139 * @param listMinLength 140 * the minimum legal number of list items. 141 * @param listMaxLength 142 * the the maximum legal number of list items. 143 */ 144 protected void addAttribute(String elementName, String attrName, int dataType, 145 boolean required, int listMinLength, int listMaxLength) { 146 if (attrName == null) { 147 throw new IllegalArgumentException("attrName == null!"); 148 } 149 if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) { 150 throw new IllegalArgumentException("Invalid value for dataType!"); 151 } 152 if (listMinLength < 0 || listMinLength > listMaxLength) { 153 throw new IllegalArgumentException("Invalid list bounds!"); 154 } 155 156 Element element = findElement(elementName); 157 Attlist attr = new Attlist(); 158 attr.name = attrName; 159 attr.dataType = dataType; 160 attr.required = required; 161 attr.listMinLength = listMinLength; 162 attr.listMaxLength = listMaxLength; 163 attr.valueType = VALUE_LIST; 164 165 element.attributes.put(attrName, attr); 166 } 167 168 /** 169 * Adds a new attribute to an existing element. 170 * 171 * @param elementName 172 * the name of the element to which the new attribute will be 173 * added. 174 * @param attrName 175 * the attribute name. 176 * @param dataType 177 * the data type of the new attribute. 178 * @param required 179 * the flag which indicates whether this attribute must be 180 * present. 181 * @param defaultValue 182 * the default value of the attribute. 183 */ 184 protected void addAttribute(String elementName, String attrName, int dataType, 185 boolean required, String defaultValue) { 186 if (attrName == null) { 187 throw new IllegalArgumentException("attrName == null!"); 188 } 189 if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) { 190 throw new IllegalArgumentException("Invalid value for dataType!"); 191 } 192 193 Element element = findElement(elementName); 194 Attlist attr = new Attlist(); 195 attr.name = attrName; 196 attr.dataType = dataType; 197 attr.required = required; 198 attr.defaultValue = defaultValue; 199 attr.valueType = VALUE_ARBITRARY; 200 201 element.attributes.put(attrName, attr); 202 } 203 204 /** 205 * Adds a new attribute to an existing element. 206 * 207 * @param elementName 208 * the name of the element to which the new attribute will be 209 * added. 210 * @param attrName 211 * the attribute name. 212 * @param dataType 213 * the data type of the new attribute. 214 * @param required 215 * the flag which indicates whether this attribute must be 216 * present. 217 * @param defaultValue 218 * the default value of the attribute. 219 * @param enumeratedValues 220 * the legal values for the attribute as a list of strings. 221 */ 222 protected void addAttribute(String elementName, String attrName, int dataType, 223 boolean required, String defaultValue, List<String> enumeratedValues) { 224 if (attrName == null) { 225 throw new IllegalArgumentException("attrName == null!"); 226 } 227 if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) { 228 throw new IllegalArgumentException("Invalid value for dataType!"); 229 } 230 if (enumeratedValues == null || enumeratedValues.isEmpty()) { 231 throw new IllegalArgumentException("enumeratedValues is empty or null"); 232 } 233 234 try { 235 for (String enumeratedValue : enumeratedValues) { 236 if (enumeratedValue == null) { 237 throw new IllegalArgumentException("enumeratedValues contains a null!"); 238 } 239 } 240 } catch (ClassCastException e) { 241 throw new IllegalArgumentException("enumeratedValues contains a non-String value!"); 242 } 243 244 Element element = findElement(elementName); 245 Attlist attr = new Attlist(); 246 attr.name = attrName; 247 attr.dataType = dataType; 248 attr.required = required; 249 attr.defaultValue = defaultValue; 250 attr.enumeratedValues = enumeratedValues; 251 attr.valueType = VALUE_ENUMERATION; 252 253 element.attributes.put(attrName, attr); 254 } 255 256 /** 257 * Adds a new attribute to an existing element. 258 * 259 * @param elementName 260 * the name of the element to which the new attribute will be 261 * added. 262 * @param attrName 263 * the attribute name. 264 * @param dataType 265 * the data type of the new attribute. 266 * @param required 267 * the flag which indicates whether this attribute must be 268 * present. 269 * @param defaultValue 270 * the default value of attribute. 271 * @param minValue 272 * the minimum legal value of an attribute. 273 * @param maxValue 274 * the maximum legal value of an attribute. 275 * @param minInclusive 276 * the flag which indicates whether the minValue is inclusive. 277 * @param maxInclusive 278 * the flag which indicates whether the maxValue is inclusive. 279 */ 280 protected void addAttribute(String elementName, String attrName, int dataType, 281 boolean required, String defaultValue, String minValue, String maxValue, 282 boolean minInclusive, boolean maxInclusive) { 283 if (attrName == null) { 284 throw new IllegalArgumentException("attrName == null!"); 285 } 286 if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) { 287 throw new IllegalArgumentException("Invalid value for dataType!"); 288 } 289 290 Element element = findElement(elementName); 291 Attlist attr = new Attlist(); 292 attr.name = attrName; 293 attr.dataType = dataType; 294 attr.required = required; 295 attr.defaultValue = defaultValue; 296 attr.minValue = minValue; 297 attr.maxValue = maxValue; 298 attr.minInclusive = minInclusive; 299 attr.maxInclusive = maxInclusive; 300 301 attr.valueType = VALUE_RANGE; 302 attr.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0; 303 attr.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0; 304 305 element.attributes.put(attrName, attr); 306 } 307 308 /** 309 * Adds a new attribute with boolean data type to an existing element. 310 * 311 * @param elementName 312 * the name of the element to which the new attribute will be 313 * added. 314 * @param attrName 315 * the attribute name. 316 * @param hasDefaultValue 317 * the flag which indicates whether this attribute must have a 318 * default value. 319 * @param defaultValue 320 * the default value. 321 */ 322 protected void addBooleanAttribute(String elementName, String attrName, 323 boolean hasDefaultValue, boolean defaultValue) { 324 String defaultVal = hasDefaultValue ? (defaultValue ? "TRUE" : "FALSE") : null; 325 ArrayList<String> values = new ArrayList<String>(2); 326 values.add("TRUE"); 327 values.add("FALSE"); 328 329 addAttribute(elementName, attrName, DATATYPE_BOOLEAN, true, defaultVal, values); 330 } 331 332 /** 333 * Adds an existing element to the list of child elements of the specified 334 * parent element. 335 * 336 * @param elementName 337 * the name of the element to be added. 338 * @param parentName 339 * the parent element name. 340 */ 341 protected void addChildElement(String elementName, String parentName) { 342 Element parent = findElement(parentName); 343 Element element = findElement(elementName); 344 parent.children.add(element.name); 345 } 346 347 /** 348 * Adds a new element type to this IIOMetadataFormat with a child policy (if 349 * policy is not CHILD_POLICY_REPEAT). 350 * 351 * @param elementName 352 * the name of the element to be added. 353 * @param parentName 354 * the parent element name. 355 * @param childPolicy 356 * one of the CHILD_POLICY_* constants defined by 357 * IIOMetadataFormat. 358 */ 359 protected void addElement(String elementName, String parentName, int childPolicy) { 360 if (childPolicy < CHILD_POLICY_EMPTY || childPolicy > CHILD_POLICY_MAX 361 || childPolicy == CHILD_POLICY_REPEAT) { 362 throw new IllegalArgumentException("childPolicy is not one of the predefined constants"); 363 } 364 365 Element parent = findElement(parentName); 366 Element element = new Element(); 367 element.name = elementName; 368 element.childPolicy = childPolicy; 369 elementHash.put(elementName, element); 370 parent.children.add(elementName); 371 } 372 373 /** 374 * Adds a new element type to this IIOMetadataFormat with 375 * CHILD_POLICY_REPEAT and the specified minimum and maximum number of child 376 * elements. 377 * 378 * @param elementName 379 * the element name to be added. 380 * @param parentName 381 * the parent element name. 382 * @param minChildren 383 * the minimum number of child elements. 384 * @param maxChildren 385 * the maximum number of child elements. 386 */ 387 protected void addElement(String elementName, String parentName, int minChildren, 388 int maxChildren) { 389 if (minChildren < 0) { 390 throw new IllegalArgumentException("minChildren < 0!"); 391 } 392 if (minChildren > maxChildren) { 393 throw new IllegalArgumentException("minChildren > maxChildren!"); 394 } 395 396 Element parent = findElement(parentName); 397 Element element = new Element(); 398 element.name = elementName; 399 element.childPolicy = CHILD_POLICY_REPEAT; 400 element.minChildren = minChildren; 401 element.maxChildren = maxChildren; 402 elementHash.put(elementName, element); 403 parent.children.add(elementName); 404 } 405 406 /** 407 * Adds an Object reference with the specified class type to be stored as 408 * element's value. 409 * 410 * @param elementName 411 * the element name. 412 * @param classType 413 * the class indicates the legal types for the object's value. 414 * @param arrayMinLength 415 * the minimum legal length for the array. 416 * @param arrayMaxLength 417 * the maximum legal length for the array. 418 */ 419 protected void addObjectValue(String elementName, Class<?> classType, int arrayMinLength, 420 int arrayMaxLength) { 421 Element element = findElement(elementName); 422 423 ObjectValue objVal = new ObjectValue(); 424 objVal.classType = classType; 425 objVal.arrayMaxLength = arrayMaxLength; 426 objVal.arrayMinLength = arrayMinLength; 427 objVal.valueType = VALUE_LIST; 428 429 element.objectValue = objVal; 430 } 431 432 /** 433 * Adds an Object reference with the specified class type to be stored as an 434 * element's value. 435 * 436 * @param elementName 437 * the element name. 438 * @param classType 439 * the class indicates the legal types for the object's value. 440 * @param required 441 * a flag indicated that this object value must be present. 442 * @param defaultValue 443 * the default value, or null. 444 */ 445 protected <T> void addObjectValue(String elementName, Class<T> classType, boolean required, 446 T defaultValue) { 447 // note: reqired is an unused parameter 448 Element element = findElement(elementName); 449 450 ObjectValue<T> objVal = new ObjectValue<T>(); 451 objVal.classType = classType; 452 objVal.defaultValue = defaultValue; 453 objVal.valueType = VALUE_ARBITRARY; 454 455 element.objectValue = objVal; 456 } 457 458 /** 459 * Adds an Object reference with the specified class type to be stored as 460 * the element's value. 461 * 462 * @param elementName 463 * the element name. 464 * @param classType 465 * the class indicates the legal types for the object value. 466 * @param required 467 * a flag indicated that this object value must be present. 468 * @param defaultValue 469 * the default value, or null. 470 * @param enumeratedValues 471 * the list of legal values for the object. 472 */ 473 protected <T> void addObjectValue(String elementName, Class<T> classType, boolean required, 474 T defaultValue, List<? extends T> enumeratedValues) { 475 // note: reqired is an unused parameter 476 if (enumeratedValues == null || enumeratedValues.isEmpty()) { 477 throw new IllegalArgumentException("enumeratedValues is empty or null"); 478 } 479 480 try { 481 for (T enumeratedValue : enumeratedValues) { 482 if (enumeratedValue == null) { 483 throw new IllegalArgumentException("enumeratedValues contains a null!"); 484 } 485 } 486 } catch (ClassCastException e) { 487 throw new IllegalArgumentException( 488 "enumeratedValues contains a value not of class classType!"); 489 } 490 491 Element element = findElement(elementName); 492 493 ObjectValue<T> objVal = new ObjectValue<T>(); 494 objVal.classType = classType; 495 objVal.defaultValue = defaultValue; 496 objVal.enumeratedValues = enumeratedValues; 497 objVal.valueType = VALUE_ENUMERATION; 498 499 element.objectValue = objVal; 500 } 501 502 /** 503 * Adds an Object reference with the specified class type to be stored as 504 * the element's value. 505 * 506 * @param elementName 507 * the element name. 508 * @param classType 509 * the class indicates the legal types for the object value. 510 * @param defaultValue 511 * the default value, or null. 512 * @param minValue 513 * the minimum legal value for the object value. 514 * @param maxValue 515 * the maximum legal value for the object value. 516 * @param minInclusive 517 * the flag which indicates whether the minValue is inclusive. 518 * @param maxInclusive 519 * the flag which indicates whether the maxValue is inclusive. 520 */ 521 protected <T extends Object & Comparable<? super T>> void addObjectValue(String elementName, 522 Class<T> classType, T defaultValue, Comparable<? super T> minValue, 523 Comparable<? super T> maxValue, boolean minInclusive, boolean maxInclusive) { 524 Element element = findElement(elementName); 525 526 ObjectValue<T> objVal = new ObjectValue<T>(); 527 objVal.classType = classType; 528 objVal.defaultValue = defaultValue; 529 objVal.minValue = minValue; 530 objVal.maxValue = maxValue; 531 objVal.minInclusive = minInclusive; 532 objVal.maxInclusive = maxInclusive; 533 534 objVal.valueType = VALUE_RANGE; 535 objVal.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0; 536 objVal.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0; 537 538 element.objectValue = objVal; 539 } 540 541 public int getAttributeDataType(String elementName, String attrName) { 542 Attlist attr = findAttribute(elementName, attrName); 543 return attr.dataType; 544 } 545 546 public String getAttributeDefaultValue(String elementName, String attrName) { 547 Attlist attr = findAttribute(elementName, attrName); 548 return attr.defaultValue; 549 } 550 551 public String getAttributeDescription(String elementName, String attrName, Locale locale) { 552 findAttribute(elementName, attrName); 553 return getResourceString(elementName + "/" + attrName, locale); 554 } 555 556 public String[] getAttributeEnumerations(String elementName, String attrName) { 557 Attlist attr = findAttribute(elementName, attrName); 558 if (attr.valueType != VALUE_ENUMERATION) { 559 throw new IllegalArgumentException("Attribute is not an enumeration!"); 560 } 561 562 return attr.enumeratedValues.toArray(new String[attr.enumeratedValues.size()]); 563 } 564 565 public int getAttributeListMaxLength(String elementName, String attrName) { 566 Attlist attr = findAttribute(elementName, attrName); 567 if (attr.valueType != VALUE_LIST) { 568 throw new IllegalArgumentException("Attribute is not a list!"); 569 } 570 return attr.listMaxLength; 571 } 572 573 public int getAttributeListMinLength(String elementName, String attrName) { 574 Attlist attr = findAttribute(elementName, attrName); 575 if (attr.valueType != VALUE_LIST) { 576 throw new IllegalArgumentException("Attribute is not a list!"); 577 } 578 return attr.listMinLength; 579 } 580 581 public String getAttributeMaxValue(String elementName, String attrName) { 582 Attlist attr = findAttribute(elementName, attrName); 583 if ((attr.valueType & VALUE_RANGE) == 0) { 584 throw new IllegalArgumentException("Attribute is not a range!"); 585 } 586 return attr.maxValue; 587 } 588 589 public String getAttributeMinValue(String elementName, String attrName) { 590 Attlist attr = findAttribute(elementName, attrName); 591 if ((attr.valueType & VALUE_RANGE) == 0) { 592 throw new IllegalArgumentException("Attribute is not a range!"); 593 } 594 return attr.minValue; 595 } 596 597 public String[] getAttributeNames(String elementName) { 598 Element element = findElement(elementName); 599 return element.attributes.keySet().toArray(new String[element.attributes.size()]); 600 } 601 602 public int getAttributeValueType(String elementName, String attrName) { 603 Attlist attr = findAttribute(elementName, attrName); 604 return attr.valueType; 605 } 606 607 public String[] getChildNames(String elementName) { 608 Element element = findElement(elementName); 609 if (element.childPolicy == CHILD_POLICY_EMPTY) { // Element cannot have 610 // children 611 return null; 612 } 613 return element.children.toArray(new String[element.children.size()]); 614 } 615 616 public int getChildPolicy(String elementName) { 617 Element element = findElement(elementName); 618 return element.childPolicy; 619 } 620 621 public String getElementDescription(String elementName, Locale locale) { 622 findElement(elementName); // Check if there is such element 623 return getResourceString(elementName, locale); 624 } 625 626 public int getElementMaxChildren(String elementName) { 627 Element element = findElement(elementName); 628 if (element.childPolicy != CHILD_POLICY_REPEAT) { 629 throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!"); 630 } 631 return element.maxChildren; 632 } 633 634 public int getElementMinChildren(String elementName) { 635 Element element = findElement(elementName); 636 if (element.childPolicy != CHILD_POLICY_REPEAT) { 637 throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!"); 638 } 639 return element.minChildren; 640 } 641 642 public int getObjectArrayMaxLength(String elementName) { 643 Element element = findElement(elementName); 644 ObjectValue v = element.objectValue; 645 if (v == null || v.valueType != VALUE_LIST) { 646 throw new IllegalArgumentException("Not a list!"); 647 } 648 return v.arrayMaxLength; 649 } 650 651 public int getObjectArrayMinLength(String elementName) { 652 Element element = findElement(elementName); 653 ObjectValue v = element.objectValue; 654 if (v == null || v.valueType != VALUE_LIST) { 655 throw new IllegalArgumentException("Not a list!"); 656 } 657 return v.arrayMinLength; 658 } 659 660 public Class<?> getObjectClass(String elementName) { 661 ObjectValue v = findObjectValue(elementName); 662 return v.classType; 663 } 664 665 public Object getObjectDefaultValue(String elementName) { 666 ObjectValue v = findObjectValue(elementName); 667 return v.defaultValue; 668 } 669 670 public Object[] getObjectEnumerations(String elementName) { 671 Element element = findElement(elementName); 672 ObjectValue v = element.objectValue; 673 if (v == null || v.valueType != VALUE_ENUMERATION) { 674 throw new IllegalArgumentException("Not an enumeration!"); 675 } 676 return v.enumeratedValues.toArray(); 677 } 678 679 public Comparable<?> getObjectMaxValue(String elementName) { 680 Element element = findElement(elementName); 681 ObjectValue v = element.objectValue; 682 if (v == null || (v.valueType & VALUE_RANGE) == 0) { 683 throw new IllegalArgumentException("Not a range!"); 684 } 685 return v.maxValue; 686 } 687 688 public Comparable<?> getObjectMinValue(String elementName) { 689 Element element = findElement(elementName); 690 ObjectValue v = element.objectValue; 691 if (v == null || (v.valueType & VALUE_RANGE) == 0) { 692 throw new IllegalArgumentException("Not a range!"); 693 } 694 return v.minValue; 695 } 696 697 public int getObjectValueType(String elementName) { 698 Element element = findElement(elementName); 699 if (element.objectValue == null) { 700 return VALUE_NONE; 701 } 702 return element.objectValue.valueType; 703 } 704 705 /** 706 * Gets the resource base name for locating ResourceBundles. 707 * 708 * @return the current resource base name. 709 */ 710 protected String getResourceBaseName() { 711 return resourceBaseName; 712 } 713 714 public String getRootName() { 715 return rootName; 716 } 717 718 /** 719 * Gets the standard format instance. 720 * 721 * @return the IIOMetadataFormat instance. 722 */ 723 public static IIOMetadataFormat getStandardFormatInstance() { 724 if (standardFormat == null) { 725 standardFormat = new IIOStandardMetadataFormat(); 726 } 727 728 return standardFormat; 729 } 730 731 public boolean isAttributeRequired(String elementName, String attrName) { 732 return findAttribute(elementName, attrName).required; 733 } 734 735 /** 736 * Removes the specified attribute from the specified element. 737 * 738 * @param elementName 739 * the specified element name. 740 * @param attrName 741 * the specified attribute name. 742 */ 743 protected void removeAttribute(String elementName, String attrName) { 744 Element element = findElement(elementName); 745 element.attributes.remove(attrName); 746 } 747 748 /** 749 * Removes the specified element from this format. 750 * 751 * @param elementName 752 * the specified element name. 753 */ 754 protected void removeElement(String elementName) { 755 Element element; 756 if ((element = elementHash.get(elementName)) != null) { 757 elementHash.remove(elementName); 758 for (Element e : elementHash.values()) { 759 e.children.remove(element.name); 760 } 761 } 762 } 763 764 /** 765 * Removes the object value from the specified element. 766 * 767 * @param elementName 768 * the element name. 769 */ 770 protected void removeObjectValue(String elementName) { 771 Element element = findElement(elementName); 772 element.objectValue = null; 773 } 774 775 /** 776 * Sets a new base name for ResourceBundles containing descriptions of 777 * elements and attributes for this format. 778 * 779 * @param resourceBaseName 780 * the new resource base name. 781 */ 782 protected void setResourceBaseName(String resourceBaseName) { 783 if (resourceBaseName == null) { 784 throw new IllegalArgumentException("resourceBaseName == null!"); 785 } 786 this.resourceBaseName = resourceBaseName; 787 } 788 789 /** 790 * The Class Element. 791 */ 792 @SuppressWarnings( { 793 "ClassWithoutConstructor" 794 }) 795 private class Element { 796 797 /** 798 * The name. 799 */ 800 String name; 801 802 /** 803 * The children. 804 */ 805 ArrayList<String> children = new ArrayList<String>(); 806 807 /** 808 * The attributes. 809 */ 810 HashMap<String, Attlist> attributes = new HashMap<String, Attlist>(); 811 812 /** 813 * The min children. 814 */ 815 int minChildren; 816 817 /** 818 * The max children. 819 */ 820 int maxChildren; 821 822 /** 823 * The child policy. 824 */ 825 int childPolicy; 826 827 /** 828 * The object value. 829 */ 830 ObjectValue objectValue; 831 } 832 833 /** 834 * The Class Attlist. 835 */ 836 @SuppressWarnings( { 837 "ClassWithoutConstructor" 838 }) 839 private class Attlist { 840 841 /** 842 * The name. 843 */ 844 String name; 845 846 /** 847 * The data type. 848 */ 849 int dataType; 850 851 /** 852 * The required. 853 */ 854 boolean required; 855 856 /** 857 * The list min length. 858 */ 859 int listMinLength; 860 861 /** 862 * The list max length. 863 */ 864 int listMaxLength; 865 866 /** 867 * The default value. 868 */ 869 String defaultValue; 870 871 /** 872 * The enumerated values. 873 */ 874 List<String> enumeratedValues; 875 876 /** 877 * The min value. 878 */ 879 String minValue; 880 881 /** 882 * The max value. 883 */ 884 String maxValue; 885 886 /** 887 * The min inclusive. 888 */ 889 boolean minInclusive; 890 891 /** 892 * The max inclusive. 893 */ 894 boolean maxInclusive; 895 896 /** 897 * The value type. 898 */ 899 int valueType; 900 } 901 902 /** 903 * The Class ObjectValue. 904 */ 905 @SuppressWarnings( { 906 "ClassWithoutConstructor" 907 }) 908 private class ObjectValue<T> { 909 910 /** 911 * The class type. 912 */ 913 Class<T> classType; 914 915 /** 916 * The array min length. 917 */ 918 int arrayMinLength; 919 920 /** 921 * The array max length. 922 */ 923 int arrayMaxLength; 924 925 /** 926 * The default value. 927 */ 928 T defaultValue; 929 930 /** 931 * The enumerated values. 932 */ 933 List<? extends T> enumeratedValues; 934 935 /** 936 * The min value. 937 */ 938 Comparable<? super T> minValue; 939 940 /** 941 * The max value. 942 */ 943 Comparable<? super T> maxValue; 944 945 /** 946 * The min inclusive. 947 */ 948 boolean minInclusive; 949 950 /** 951 * The max inclusive. 952 */ 953 boolean maxInclusive; 954 955 /** 956 * The value type. 957 */ 958 int valueType; 959 } 960 961 /** 962 * Find element. 963 * 964 * @param name 965 * the name. 966 * @return the element. 967 */ 968 private Element findElement(String name) { 969 Element element; 970 if ((element = elementHash.get(name)) == null) { 971 throw new IllegalArgumentException("element name is null or no such element: " + name); 972 } 973 974 return element; 975 } 976 977 /** 978 * Find attribute. 979 * 980 * @param elementName 981 * the element name. 982 * @param attributeName 983 * the attribute name. 984 * @return the attlist. 985 */ 986 private Attlist findAttribute(String elementName, String attributeName) { 987 Element element = findElement(elementName); 988 Attlist attribute; 989 if ((attribute = element.attributes.get(attributeName)) == null) { 990 throw new IllegalArgumentException("attribute name is null or no such attribute: " 991 + attributeName); 992 } 993 994 return attribute; 995 } 996 997 /** 998 * Find object value. 999 * 1000 * @param elementName 1001 * the element name. 1002 * @return the object value. 1003 */ 1004 private ObjectValue findObjectValue(String elementName) { 1005 Element element = findElement(elementName); 1006 ObjectValue v = element.objectValue; 1007 if (v == null) { 1008 throw new IllegalArgumentException("No object within element"); 1009 } 1010 return v; 1011 } 1012 1013 /** 1014 * Gets the resource string. 1015 * 1016 * @param key 1017 * the key. 1018 * @param locale 1019 * the locale. 1020 * @return the resource string. 1021 */ 1022 private String getResourceString(String key, Locale locale) { 1023 if (locale == null) { 1024 locale = Locale.getDefault(); 1025 } 1026 1027 // Get the context class loader and try to locate the bundle with it 1028 // first 1029 ClassLoader contextClassloader = AccessController 1030 .doPrivileged(new PrivilegedAction<ClassLoader>() { 1031 public ClassLoader run() { 1032 return Thread.currentThread().getContextClassLoader(); 1033 } 1034 }); 1035 1036 // Now try to get the resource bundle 1037 ResourceBundle rb; 1038 try { 1039 rb = ResourceBundle.getBundle(resourceBaseName, locale, contextClassloader); 1040 } catch (MissingResourceException e) { 1041 try { 1042 rb = ResourceBundle.getBundle(resourceBaseName, locale); 1043 } catch (MissingResourceException e1) { 1044 return null; 1045 } 1046 } 1047 1048 try { 1049 return rb.getString(key); 1050 } catch (MissingResourceException e) { 1051 return null; 1052 } catch (ClassCastException e) { 1053 return null; // Not a string resource 1054 } 1055 } 1056} 1057