Source Code Cross Referenced for IIOMetadataFormatImpl.java in  » 6.0-JDK-Core » image » javax » imageio » metadata » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » image » javax.imageio.metadata 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.imageio.metadata;
0027
0028        import java.util.ArrayList;
0029        import java.util.Collection;
0030        import java.util.HashMap;
0031        import java.util.Iterator;
0032        import java.util.List;
0033        import java.util.Locale;
0034        import java.util.Map;
0035        import java.util.MissingResourceException;
0036        import java.util.ResourceBundle;
0037        import javax.imageio.ImageTypeSpecifier;
0038        import com.sun.imageio.plugins.common.StandardMetadataFormat;
0039
0040        /**
0041         * A concrete class providing a reusable implementation of the
0042         * <code>IIOMetadataFormat</code> interface.  In addition, a static
0043         * instance representing the standard, plug-in neutral
0044         * <code>javax_imageio_1.0</code> format is provided by the
0045         * <code>getStandardFormatInstance</code> method.
0046         *
0047         * <p> In order to supply localized descriptions of elements and
0048         * attributes, a <code>ResourceBundle</code> with a base name of
0049         * <code>this.getClass().getName() + "Resources"</code> should be
0050         * supplied via the usual mechanism used by
0051         * <code>ResourceBundle.getBundle</code>.  Briefly, the subclasser
0052         * supplies one or more additional classes according to a naming
0053         * convention (by default, the fully-qualified name of the subclass
0054         * extending <code>IIMetadataFormatImpl</code>, plus the string
0055         * "Resources", plus the country, language, and variant codes
0056         * separated by underscores).  At run time, calls to
0057         * <code>getElementDescription</code> or
0058         * <code>getAttributeDescription</code> will attempt to load such
0059         * classes dynamically according to the supplied locale, and will use
0060         * either the element name, or the element name followed by a '/'
0061         * character followed by the attribute name as a key.  This key will
0062         * be supplied to the <code>ResourceBundle</code>'s
0063         * <code>getString</code> method, and the resulting localized
0064         * description of the node or attribute is returned.
0065         *
0066         * <p> The subclass may supply a different base name for the resource
0067         * bundles using the <code>setResourceBaseName</code> method.
0068         *
0069         * <p> A subclass may choose its own localization mechanism, if so
0070         * desired, by overriding the supplied implementations of
0071         * <code>getElementDescription</code> and
0072         * <code>getAttributeDescription</code>.
0073         *
0074         * @see ResourceBundle#getBundle(String,Locale)
0075         *
0076         * @version 0.5
0077         */
0078        public abstract class IIOMetadataFormatImpl implements 
0079                IIOMetadataFormat {
0080
0081            /**
0082             * A <code>String</code> constant containing the standard format
0083             * name, <code>"javax_imageio_1.0"</code>.
0084             */
0085            public static final String standardMetadataFormatName = "javax_imageio_1.0";
0086
0087            private static IIOMetadataFormat standardFormat = null;
0088
0089            private String resourceBaseName = this .getClass().getName()
0090                    + "Resources";
0091
0092            private String rootName;
0093
0094            // Element name (String) -> Element
0095            private HashMap elementMap = new HashMap();
0096
0097            class Element {
0098                String elementName;
0099
0100                int childPolicy;
0101                int minChildren = 0;
0102                int maxChildren = 0;
0103
0104                // Child names (Strings)
0105                List childList = new ArrayList();
0106
0107                // Parent names (Strings)
0108                List parentList = new ArrayList();
0109
0110                // List of attribute names in the order they were added
0111                List attrList = new ArrayList();
0112                // Attr name (String) -> Attribute
0113                Map attrMap = new HashMap();
0114
0115                ObjectValue objectValue;
0116            }
0117
0118            class Attribute {
0119                String attrName;
0120
0121                int valueType = VALUE_ARBITRARY;
0122                int dataType;
0123                boolean required;
0124                String defaultValue = null;
0125
0126                // enumeration
0127                List enumeratedValues;
0128
0129                // range
0130                String minValue;
0131                String maxValue;
0132
0133                // list
0134                int listMinLength;
0135                int listMaxLength;
0136            }
0137
0138            class ObjectValue {
0139                int valueType = VALUE_NONE;
0140                Class classType = null;
0141                Object defaultValue = null;
0142
0143                // Meaningful only if valueType == VALUE_ENUMERATION
0144                List enumeratedValues = null;
0145
0146                // Meaningful only if valueType == VALUE_RANGE
0147                Comparable minValue = null;
0148                Comparable maxValue = null;
0149
0150                // Meaningful only if valueType == VALUE_LIST
0151                int arrayMinLength = 0;
0152                int arrayMaxLength = 0;
0153            }
0154
0155            /**
0156             * Constructs a blank <code>IIOMetadataFormatImpl</code> instance,
0157             * with a given root element name and child policy (other than
0158             * <code>CHILD_POLICY_REPEAT</code>).  Additional elements, and
0159             * their attributes and <code>Object</code> reference information
0160             * may be added using the various <code>add</code> methods.
0161             *
0162             * @param rootName the name of the root element.
0163             * @param childPolicy one of the <code>CHILD_POLICY_*</code> constants,
0164             * other than <code>CHILD_POLICY_REPEAT</code>.
0165             *
0166             * @exception IllegalArgumentException if <code>rootName</code> is
0167             * <code>null</code>.
0168             * @exception IllegalArgumentException if <code>childPolicy</code> is
0169             * not one of the predefined constants.
0170             */
0171            public IIOMetadataFormatImpl(String rootName, int childPolicy) {
0172                if (rootName == null) {
0173                    throw new IllegalArgumentException("rootName == null!");
0174                }
0175                if (childPolicy < CHILD_POLICY_EMPTY
0176                        || childPolicy > CHILD_POLICY_MAX
0177                        || childPolicy == CHILD_POLICY_REPEAT) {
0178                    throw new IllegalArgumentException(
0179                            "Invalid value for childPolicy!");
0180                }
0181
0182                this .rootName = rootName;
0183
0184                Element root = new Element();
0185                root.elementName = rootName;
0186                root.childPolicy = childPolicy;
0187
0188                elementMap.put(rootName, root);
0189            }
0190
0191            /**
0192             * Constructs a blank <code>IIOMetadataFormatImpl</code> instance,
0193             * with a given root element name and a child policy of
0194             * <code>CHILD_POLICY_REPEAT</code>.  Additional elements, and
0195             * their attributes and <code>Object</code> reference information
0196             * may be added using the various <code>add</code> methods.
0197             *
0198             * @param rootName the name of the root element.
0199             * @param minChildren the minimum number of children of the node.
0200             * @param maxChildren the maximum number of children of the node.
0201             *
0202             * @exception IllegalArgumentException if <code>rootName</code> is
0203             * <code>null</code>.
0204             * @exception IllegalArgumentException if <code>minChildren</code>
0205             * is negative or larger than <code>maxChildren</code>.
0206             */
0207            public IIOMetadataFormatImpl(String rootName, int minChildren,
0208                    int maxChildren) {
0209                if (rootName == null) {
0210                    throw new IllegalArgumentException("rootName == null!");
0211                }
0212                if (minChildren < 0) {
0213                    throw new IllegalArgumentException("minChildren < 0!");
0214                }
0215                if (minChildren > maxChildren) {
0216                    throw new IllegalArgumentException(
0217                            "minChildren > maxChildren!");
0218                }
0219
0220                Element root = new Element();
0221                root.elementName = rootName;
0222                root.childPolicy = CHILD_POLICY_REPEAT;
0223                root.minChildren = minChildren;
0224                root.maxChildren = maxChildren;
0225
0226                this .rootName = rootName;
0227                elementMap.put(rootName, root);
0228            }
0229
0230            /**
0231             * Sets a new base name for locating <code>ResourceBundle</code>s
0232             * containing descriptions of elements and attributes for this
0233             * format.
0234             *
0235             * <p> Prior to the first time this method is called, the base
0236             * name will be equal to <code>this.getClass().getName() +
0237             * "Resources"</code>.
0238             *
0239             * @param resourceBaseName a <code>String</code> containg the new
0240             * base name.
0241             *
0242             * @exception IllegalArgumentException if
0243             * <code>resourceBaseName</code> is <code>null</code>.
0244             *
0245             * @see #getResourceBaseName
0246             */
0247            protected void setResourceBaseName(String resourceBaseName) {
0248                if (resourceBaseName == null) {
0249                    throw new IllegalArgumentException(
0250                            "resourceBaseName == null!");
0251                }
0252                this .resourceBaseName = resourceBaseName;
0253            }
0254
0255            /**
0256             * Returns the currently set base name for locating
0257             * <code>ResourceBundle</code>s.
0258             *
0259             * @return a <code>String</code> containing the base name.
0260             *
0261             * @see #setResourceBaseName
0262             */
0263            protected String getResourceBaseName() {
0264                return resourceBaseName;
0265            }
0266
0267            /**
0268             * Utility method for locating an element.
0269             *
0270             * @param mustAppear if <code>true</code>, throw an
0271             * <code>IllegalArgumentException</code> if no such node exists;
0272             * if <code>false</code>, just return null.
0273             */
0274            private Element getElement(String elementName, boolean mustAppear) {
0275                if (mustAppear && (elementName == null)) {
0276                    throw new IllegalArgumentException("element name is null!");
0277                }
0278                Element element = (Element) elementMap.get(elementName);
0279                if (mustAppear && (element == null)) {
0280                    throw new IllegalArgumentException("No such element: "
0281                            + elementName);
0282                }
0283                return element;
0284            }
0285
0286            private Element getElement(String elementName) {
0287                return getElement(elementName, true);
0288            }
0289
0290            // Utility method for locating an attribute
0291            private Attribute getAttribute(String elementName, String attrName) {
0292                Element element = getElement(elementName);
0293                Attribute attr = (Attribute) element.attrMap.get(attrName);
0294                if (attr == null) {
0295                    throw new IllegalArgumentException("No such attribute \""
0296                            + attrName + "\"!");
0297                }
0298                return attr;
0299            }
0300
0301            // Setup
0302
0303            /**
0304             * Adds a new element type to this metadata document format with a
0305             * child policy other than <code>CHILD_POLICY_REPEAT</code>.
0306             *
0307             * @param elementName the name of the new element.
0308             * @param parentName the name of the element that will be the
0309             * parent of the new element.
0310             * @param childPolicy one of the <code>CHILD_POLICY_*</code>
0311             * constants, other than <code>CHILD_POLICY_REPEAT</code>,
0312             * indicating the child policy of the new element.
0313             *
0314             * @exception IllegalArgumentException if <code>parentName</code>
0315             * is <code>null</code>, or is not a legal element name for this
0316             * format.
0317             * @exception IllegalArgumentException if <code>childPolicy</code>
0318             * is not one of the predefined constants.
0319             */
0320            protected void addElement(String elementName, String parentName,
0321                    int childPolicy) {
0322                Element parent = getElement(parentName);
0323                if (childPolicy < CHILD_POLICY_EMPTY
0324                        || childPolicy > CHILD_POLICY_MAX
0325                        || childPolicy == CHILD_POLICY_REPEAT) {
0326                    throw new IllegalArgumentException(
0327                            "Invalid value for childPolicy!");
0328                }
0329
0330                Element element = new Element();
0331                element.elementName = elementName;
0332                element.childPolicy = childPolicy;
0333
0334                parent.childList.add(elementName);
0335                element.parentList.add(parentName);
0336
0337                elementMap.put(elementName, element);
0338            }
0339
0340            /**
0341             * Adds a new element type to this metadata document format with a
0342             * child policy of <code>CHILD_POLICY_REPEAT</code>.
0343             *
0344             * @param elementName the name of the new element.
0345             * @param parentName the name of the element that will be the
0346             * parent of the new element.
0347             * @param minChildren the minimum number of children of the node.
0348             * @param maxChildren the maximum number of children of the node.
0349             *
0350             * @exception IllegalArgumentException if <code>parentName</code>
0351             * is <code>null</code>, or is not a legal element name for this
0352             * format.
0353             * @exception IllegalArgumentException if <code>minChildren</code>
0354             * is negative or larger than <code>maxChildren</code>.
0355             */
0356            protected void addElement(String elementName, String parentName,
0357                    int minChildren, int maxChildren) {
0358                Element parent = getElement(parentName);
0359                if (minChildren < 0) {
0360                    throw new IllegalArgumentException("minChildren < 0!");
0361                }
0362                if (minChildren > maxChildren) {
0363                    throw new IllegalArgumentException(
0364                            "minChildren > maxChildren!");
0365                }
0366
0367                Element element = new Element();
0368                element.elementName = elementName;
0369                element.childPolicy = CHILD_POLICY_REPEAT;
0370                element.minChildren = minChildren;
0371                element.maxChildren = maxChildren;
0372
0373                parent.childList.add(elementName);
0374                element.parentList.add(parentName);
0375
0376                elementMap.put(elementName, element);
0377            }
0378
0379            /**
0380             * Adds an existing element to the list of legal children for a
0381             * given parent node type.
0382             *
0383             * @param parentName the name of the element that will be the
0384             * new parent of the element.
0385             * @param elementName the name of the element to be addded as a
0386             * child.
0387             *
0388             * @exception IllegalArgumentException if <code>elementName</code>
0389             * is <code>null</code>, or is not a legal element name for this
0390             * format.
0391             * @exception IllegalArgumentException if <code>parentName</code>
0392             * is <code>null</code>, or is not a legal element name for this
0393             * format.
0394             */
0395            protected void addChildElement(String elementName, String parentName) {
0396                Element parent = getElement(parentName);
0397                Element element = getElement(elementName);
0398                parent.childList.add(elementName);
0399                element.parentList.add(parentName);
0400            }
0401
0402            /**
0403             * Removes an element from the format.  If no element with the
0404             * given name was present, nothing happens and no exception is
0405             * thrown.
0406             *
0407             * @param elementName the name of the element to be removed.
0408             */
0409            protected void removeElement(String elementName) {
0410                Element element = getElement(elementName, false);
0411                if (element != null) {
0412                    Iterator iter = element.parentList.iterator();
0413                    while (iter.hasNext()) {
0414                        String parentName = (String) iter.next();
0415                        Element parent = getElement(parentName, false);
0416                        if (parent != null) {
0417                            parent.childList.remove(elementName);
0418                        }
0419                    }
0420                    elementMap.remove(elementName);
0421                }
0422            }
0423
0424            /**
0425             * Adds a new attribute to a previously defined element that may
0426             * be set to an arbitrary value.
0427             *
0428             * @param elementName the name of the element.
0429             * @param attrName the name of the attribute being added.
0430             * @param dataType the data type (string format) of the attribute,
0431             * one of the <code>DATATYPE_*</code> constants.
0432             * @param required <code>true</code> if the attribute must be present.
0433             * @param defaultValue the default value for the attribute, or
0434             * <code>null</code>.
0435             *
0436             * @exception IllegalArgumentException if <code>elementName</code>
0437             * is <code>null</code>, or is not a legal element name for this
0438             * format.
0439             * @exception IllegalArgumentException if <code>attrName</code> is
0440             * <code>null</code>.
0441             * @exception IllegalArgumentException if <code>dataType</code> is
0442             * not one of the predefined constants.
0443             */
0444            protected void addAttribute(String elementName, String attrName,
0445                    int dataType, boolean required, String defaultValue) {
0446                Element element = getElement(elementName);
0447                if (attrName == null) {
0448                    throw new IllegalArgumentException("attrName == null!");
0449                }
0450                if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
0451                    throw new IllegalArgumentException(
0452                            "Invalid value for dataType!");
0453                }
0454
0455                Attribute attr = new Attribute();
0456                attr.attrName = attrName;
0457                attr.valueType = VALUE_ARBITRARY;
0458                attr.dataType = dataType;
0459                attr.required = required;
0460                attr.defaultValue = defaultValue;
0461
0462                element.attrList.add(attrName);
0463                element.attrMap.put(attrName, attr);
0464            }
0465
0466            /**
0467             * Adds a new attribute to a previously defined element that will
0468             * be defined by a set of enumerated values.
0469             *
0470             * @param elementName the name of the element.
0471             * @param attrName the name of the attribute being added.
0472             * @param dataType the data type (string format) of the attribute,
0473             * one of the <code>DATATYPE_*</code> constants.
0474             * @param required <code>true</code> if the attribute must be present.
0475             * @param defaultValue the default value for the attribute, or
0476             * <code>null</code>.
0477             * @param enumeratedValues a <code>List</code> of
0478             * <code>String</code>s containing the legal values for the
0479             * attribute.
0480             *
0481             * @exception IllegalArgumentException if <code>elementName</code>
0482             * is <code>null</code>, or is not a legal element name for this
0483             * format.
0484             * @exception IllegalArgumentException if <code>attrName</code> is
0485             * <code>null</code>.
0486             * @exception IllegalArgumentException if <code>dataType</code> is
0487             * not one of the predefined constants.
0488             * @exception IllegalArgumentException if
0489             * <code>enumeratedValues</code> is <code>null</code>.
0490             * @exception IllegalArgumentException if
0491             * <code>enumeratedValues</code> does not contain at least one
0492             * entry.
0493             * @exception IllegalArgumentException if
0494             * <code>enumeratedValues</code> contains an element that is not a
0495             * <code>String</code> or is <code>null</code>.
0496             */
0497            protected void addAttribute(String elementName, String attrName,
0498                    int dataType, boolean required, String defaultValue,
0499                    List<String> enumeratedValues) {
0500                Element element = getElement(elementName);
0501                if (attrName == null) {
0502                    throw new IllegalArgumentException("attrName == null!");
0503                }
0504                if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
0505                    throw new IllegalArgumentException(
0506                            "Invalid value for dataType!");
0507                }
0508                if (enumeratedValues == null) {
0509                    throw new IllegalArgumentException(
0510                            "enumeratedValues == null!");
0511                }
0512                if (enumeratedValues.size() == 0) {
0513                    throw new IllegalArgumentException(
0514                            "enumeratedValues is empty!");
0515                }
0516                Iterator iter = enumeratedValues.iterator();
0517                while (iter.hasNext()) {
0518                    Object o = iter.next();
0519                    if (o == null) {
0520                        throw new IllegalArgumentException(
0521                                "enumeratedValues contains a null!");
0522                    }
0523                    if (!(o instanceof  String)) {
0524                        throw new IllegalArgumentException(
0525                                "enumeratedValues contains a non-String value!");
0526                    }
0527                }
0528
0529                Attribute attr = new Attribute();
0530                attr.attrName = attrName;
0531                attr.valueType = VALUE_ENUMERATION;
0532                attr.dataType = dataType;
0533                attr.required = required;
0534                attr.defaultValue = defaultValue;
0535                attr.enumeratedValues = enumeratedValues;
0536
0537                element.attrList.add(attrName);
0538                element.attrMap.put(attrName, attr);
0539            }
0540
0541            /**
0542             * Adds a new attribute to a previously defined element that will
0543             * be defined by a range of values.
0544             *
0545             * @param elementName the name of the element.
0546             * @param attrName the name of the attribute being added.
0547             * @param dataType the data type (string format) of the attribute,
0548             * one of the <code>DATATYPE_*</code> constants.
0549             * @param required <code>true</code> if the attribute must be present.
0550             * @param defaultValue the default value for the attribute, or
0551             * <code>null</code>.
0552             * @param minValue the smallest (inclusive or exclusive depending
0553             * on the value of <code>minInclusive</code>) legal value for the
0554             * attribute, as a <code>String</code>.
0555             * @param maxValue the largest (inclusive or exclusive depending
0556             * on the value of <code>minInclusive</code>) legal value for the
0557             * attribute, as a <code>String</code>.
0558             * @param minInclusive <code>true</code> if <code>minValue</code>
0559             * is inclusive.
0560             * @param maxInclusive <code>true</code> if <code>maxValue</code>
0561             * is inclusive.
0562             *
0563             * @exception IllegalArgumentException if <code>elementName</code>
0564             * is <code>null</code>, or is not a legal element name for this
0565             * format.
0566             * @exception IllegalArgumentException if <code>attrName</code> is
0567             * <code>null</code>.
0568             * @exception IllegalArgumentException if <code>dataType</code> is
0569             * not one of the predefined constants.
0570             */
0571            protected void addAttribute(String elementName, String attrName,
0572                    int dataType, boolean required, String defaultValue,
0573                    String minValue, String maxValue, boolean minInclusive,
0574                    boolean maxInclusive) {
0575                Element element = getElement(elementName);
0576                if (attrName == null) {
0577                    throw new IllegalArgumentException("attrName == null!");
0578                }
0579                if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
0580                    throw new IllegalArgumentException(
0581                            "Invalid value for dataType!");
0582                }
0583
0584                Attribute attr = new Attribute();
0585                attr.attrName = attrName;
0586                attr.valueType = VALUE_RANGE;
0587                if (minInclusive) {
0588                    attr.valueType |= VALUE_RANGE_MIN_INCLUSIVE_MASK;
0589                }
0590                if (maxInclusive) {
0591                    attr.valueType |= VALUE_RANGE_MAX_INCLUSIVE_MASK;
0592                }
0593                attr.dataType = dataType;
0594                attr.required = required;
0595                attr.defaultValue = defaultValue;
0596                attr.minValue = minValue;
0597                attr.maxValue = maxValue;
0598
0599                element.attrList.add(attrName);
0600                element.attrMap.put(attrName, attr);
0601            }
0602
0603            /**
0604             * Adds a new attribute to a previously defined element that will
0605             * be defined by a list of values.
0606             *
0607             * @param elementName the name of the element.
0608             * @param attrName the name of the attribute being added.
0609             * @param dataType the data type (string format) of the attribute,
0610             * one of the <code>DATATYPE_*</code> constants.
0611             * @param required <code>true</code> if the attribute must be present.
0612             * @param listMinLength the smallest legal number of list items.
0613             * @param listMaxLength the largest legal number of list items.
0614             *
0615             * @exception IllegalArgumentException if <code>elementName</code>
0616             * is <code>null</code>, or is not a legal element name for this
0617             * format.
0618             * @exception IllegalArgumentException if <code>attrName</code> is
0619             * <code>null</code>.
0620             * @exception IllegalArgumentException if <code>dataType</code> is
0621             * not one of the predefined constants.
0622             * @exception IllegalArgumentException if
0623             * <code>listMinLength</code> is negative or larger than
0624             * <code>listMaxLength</code>.
0625             */
0626            protected void addAttribute(String elementName, String attrName,
0627                    int dataType, boolean required, int listMinLength,
0628                    int listMaxLength) {
0629                Element element = getElement(elementName);
0630                if (attrName == null) {
0631                    throw new IllegalArgumentException("attrName == null!");
0632                }
0633                if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
0634                    throw new IllegalArgumentException(
0635                            "Invalid value for dataType!");
0636                }
0637                if (listMinLength < 0 || listMinLength > listMaxLength) {
0638                    throw new IllegalArgumentException("Invalid list bounds!");
0639                }
0640
0641                Attribute attr = new Attribute();
0642                attr.attrName = attrName;
0643                attr.valueType = VALUE_LIST;
0644                attr.dataType = dataType;
0645                attr.required = required;
0646                attr.listMinLength = listMinLength;
0647                attr.listMaxLength = listMaxLength;
0648
0649                element.attrList.add(attrName);
0650                element.attrMap.put(attrName, attr);
0651            }
0652
0653            /**
0654             * Adds a new attribute to a previously defined element that will
0655             * be defined by the enumerated values <code>TRUE</code> and
0656             * <code>FALSE</code>, with a datatype of
0657             * <code>DATATYPE_BOOLEAN</code>.
0658             *
0659             * @param elementName the name of the element.
0660             * @param attrName the name of the attribute being added.
0661             * @param hasDefaultValue <code>true</code> if a default value
0662             * should be present.
0663             * @param defaultValue the default value for the attribute as a
0664             * <code>boolean</code>, ignored if <code>hasDefaultValue</code>
0665             * is <code>false</code>.
0666             *
0667             * @exception IllegalArgumentException if <code>elementName</code>
0668             * is <code>null</code>, or is not a legal element name for this
0669             * format.
0670             * @exception IllegalArgumentException if <code>attrName</code> is
0671             * <code>null</code>.
0672             */
0673            protected void addBooleanAttribute(String elementName,
0674                    String attrName, boolean hasDefaultValue,
0675                    boolean defaultValue) {
0676                List values = new ArrayList();
0677                values.add("TRUE");
0678                values.add("FALSE");
0679
0680                String dval = null;
0681                if (hasDefaultValue) {
0682                    dval = defaultValue ? "TRUE" : "FALSE";
0683                }
0684                addAttribute(elementName, attrName, DATATYPE_BOOLEAN, true,
0685                        dval, values);
0686            }
0687
0688            /**
0689             * Removes an attribute from a previously defined element.  If no
0690             * attribute with the given name was present in the given element,
0691             * nothing happens and no exception is thrown.
0692             *
0693             * @param elementName the name of the element.
0694             * @param attrName the name of the attribute being removed.
0695             *
0696             * @exception IllegalArgumentException if <code>elementName</code>
0697             * is <code>null</code>, or is not a legal element name for this format.
0698             */
0699            protected void removeAttribute(String elementName, String attrName) {
0700                Element element = getElement(elementName);
0701                element.attrList.remove(attrName);
0702                element.attrMap.remove(attrName);
0703            }
0704
0705            /**
0706             * Allows an <code>Object</code> reference of a given class type
0707             * to be stored in nodes implementing the named element.  The
0708             * value of the <code>Object</code> is unconstrained other than by
0709             * its class type.
0710             *
0711             * <p> If an <code>Object</code> reference was previously allowed,
0712             * the previous settings are overwritten.
0713             *
0714             * @param elementName the name of the element.
0715             * @param classType a <code>Class</code> variable indicating the
0716             * legal class type for the object value.
0717             * @param required <code>true</code> if an object value must be present.
0718             * @param defaultValue the default value for the
0719             * <code>Object</code> reference, or <code>null</code>.
0720             * 
0721             * @exception IllegalArgumentException if <code>elementName</code>
0722             * is <code>null</code>, or is not a legal element name for this format.
0723             */
0724            protected <T> void addObjectValue(String elementName,
0725                    Class<T> classType, boolean required, T defaultValue) {
0726                Element element = getElement(elementName);
0727                ObjectValue obj = new ObjectValue();
0728                obj.valueType = VALUE_ARBITRARY;
0729                obj.classType = classType;
0730                obj.defaultValue = defaultValue;
0731
0732                element.objectValue = obj;
0733            }
0734
0735            /**
0736             * Allows an <code>Object</code> reference of a given class type
0737             * to be stored in nodes implementing the named element.  The
0738             * value of the <code>Object</code> must be one of the values
0739             * given by <code>enumeratedValues</code>.
0740             *
0741             * <p> If an <code>Object</code> reference was previously allowed,
0742             * the previous settings are overwritten.
0743             *
0744             * @param elementName the name of the element.
0745             * @param classType a <code>Class</code> variable indicating the
0746             * legal class type for the object value.
0747             * @param required <code>true</code> if an object value must be present.
0748             * @param defaultValue the default value for the
0749             * <code>Object</code> reference, or <code>null</code>.
0750             * @param enumeratedValues a <code>List</code> of
0751             * <code>Object</code>s containing the legal values for the
0752             * object reference.
0753             * 
0754             * @exception IllegalArgumentException if <code>elementName</code>
0755             * is <code>null</code>, or is not a legal element name for this format.
0756             * @exception IllegalArgumentException if
0757             * <code>enumeratedValues</code> is <code>null</code>.
0758             * @exception IllegalArgumentException if
0759             * <code>enumeratedValues</code> does not contain at least one
0760             * entry.
0761             * @exception IllegalArgumentException if
0762             * <code>enumeratedValues</code> contains an element that is not
0763             * an instance of the class type denoted by <code>classType</code>
0764             * or is <code>null</code>.
0765             */
0766            protected <T> void addObjectValue(String elementName,
0767                    Class<T> classType, boolean required, T defaultValue,
0768                    List<? extends T> enumeratedValues) {
0769                Element element = getElement(elementName);
0770                if (enumeratedValues == null) {
0771                    throw new IllegalArgumentException(
0772                            "enumeratedValues == null!");
0773                }
0774                if (enumeratedValues.size() == 0) {
0775                    throw new IllegalArgumentException(
0776                            "enumeratedValues is empty!");
0777                }
0778                Iterator iter = enumeratedValues.iterator();
0779                while (iter.hasNext()) {
0780                    Object o = iter.next();
0781                    if (o == null) {
0782                        throw new IllegalArgumentException(
0783                                "enumeratedValues contains a null!");
0784                    }
0785                    if (!classType.isInstance(o)) {
0786                        throw new IllegalArgumentException(
0787                                "enumeratedValues contains a value not of class classType!");
0788                    }
0789                }
0790
0791                ObjectValue obj = new ObjectValue();
0792                obj.valueType = VALUE_ENUMERATION;
0793                obj.classType = classType;
0794                obj.defaultValue = defaultValue;
0795                obj.enumeratedValues = enumeratedValues;
0796
0797                element.objectValue = obj;
0798            }
0799
0800            /**
0801             * Allows an <code>Object</code> reference of a given class type
0802             * to be stored in nodes implementing the named element.  The
0803             * value of the <code>Object</code> must be within the range given
0804             * by <code>minValue</code> and <code>maxValue</code>.
0805             * Furthermore, the class type must implement the
0806             * <code>Comparable</code> interface.
0807             *
0808             * <p> If an <code>Object</code> reference was previously allowed,
0809             * the previous settings are overwritten.
0810             *
0811             * @param elementName the name of the element.
0812             * @param classType a <code>Class</code> variable indicating the
0813             * legal class type for the object value.
0814             * @param defaultValue the default value for the
0815             * @param minValue the smallest (inclusive or exclusive depending
0816             * on the value of <code>minInclusive</code>) legal value for the
0817             * object value, as a <code>String</code>.
0818             * @param maxValue the largest (inclusive or exclusive depending
0819             * on the value of <code>minInclusive</code>) legal value for the
0820             * object value, as a <code>String</code>. 
0821             * @param minInclusive <code>true</code> if <code>minValue</code>
0822             * is inclusive.
0823             * @param maxInclusive <code>true</code> if <code>maxValue</code>
0824             * is inclusive.
0825             *
0826             * @exception IllegalArgumentException if <code>elementName</code>
0827             * is <code>null</code>, or is not a legal element name for this
0828             * format.
0829             */
0830            protected <T extends Object & Comparable<? super  T>> void addObjectValue(
0831                    String elementName, Class<T> classType, T defaultValue,
0832                    Comparable<? super  T> minValue,
0833                    Comparable<? super  T> maxValue, boolean minInclusive,
0834                    boolean maxInclusive) {
0835                Element element = getElement(elementName);
0836                ObjectValue obj = new ObjectValue();
0837                obj.valueType = VALUE_RANGE;
0838                if (minInclusive) {
0839                    obj.valueType |= VALUE_RANGE_MIN_INCLUSIVE_MASK;
0840                }
0841                if (maxInclusive) {
0842                    obj.valueType |= VALUE_RANGE_MAX_INCLUSIVE_MASK;
0843                }
0844                obj.classType = classType;
0845                obj.defaultValue = defaultValue;
0846                obj.minValue = minValue;
0847                obj.maxValue = maxValue;
0848
0849                element.objectValue = obj;
0850            }
0851
0852            /**
0853             * Allows an <code>Object</code> reference of a given class type
0854             * to be stored in nodes implementing the named element.  The
0855             * value of the <code>Object</code> must an array of objects of
0856             * class type given by <code>classType</code>, with at least
0857             * <code>arrayMinLength</code> and at most
0858             * <code>arrayMaxLength</code> elements.
0859             *
0860             * <p> If an <code>Object</code> reference was previously allowed,
0861             * the previous settings are overwritten.
0862             *
0863             * @param elementName the name of the element.
0864             * @param classType a <code>Class</code> variable indicating the
0865             * legal class type for the object value.
0866             * @param arrayMinLength the smallest legal length for the array.
0867             * @param arrayMaxLength the largest legal length for the array.
0868             *
0869             * @exception IllegalArgumentException if <code>elementName</code> is
0870             * not a legal element name for this format.
0871             */
0872            protected void addObjectValue(String elementName,
0873                    Class<?> classType, int arrayMinLength, int arrayMaxLength) {
0874                Element element = getElement(elementName);
0875                ObjectValue obj = new ObjectValue();
0876                obj.valueType = VALUE_LIST;
0877                obj.classType = classType;
0878                obj.arrayMinLength = arrayMinLength;
0879                obj.arrayMaxLength = arrayMaxLength;
0880
0881                element.objectValue = obj;
0882            }
0883
0884            /**
0885             * Disallows an <code>Object</code> reference from being stored in
0886             * nodes implementing the named element.
0887             *
0888             * @param elementName the name of the element.
0889             * 
0890             * @exception IllegalArgumentException if <code>elementName</code> is
0891             * not a legal element name for this format.
0892             */
0893            protected void removeObjectValue(String elementName) {
0894                Element element = getElement(elementName);
0895                element.objectValue = null;
0896            }
0897
0898            // Utility method
0899
0900            // Methods from IIOMetadataFormat
0901
0902            // Root
0903
0904            public String getRootName() {
0905                return rootName;
0906            }
0907
0908            // Multiplicity
0909
0910            public abstract boolean canNodeAppear(String elementName,
0911                    ImageTypeSpecifier imageType);
0912
0913            public int getElementMinChildren(String elementName) {
0914                Element element = getElement(elementName);
0915                if (element.childPolicy != CHILD_POLICY_REPEAT) {
0916                    throw new IllegalArgumentException(
0917                            "Child policy not CHILD_POLICY_REPEAT!");
0918                }
0919                return element.minChildren;
0920            }
0921
0922            public int getElementMaxChildren(String elementName) {
0923                Element element = getElement(elementName);
0924                if (element.childPolicy != CHILD_POLICY_REPEAT) {
0925                    throw new IllegalArgumentException(
0926                            "Child policy not CHILD_POLICY_REPEAT!");
0927                }
0928                return element.maxChildren;
0929            }
0930
0931            private String getResource(String key, Locale locale) {
0932                if (locale == null) {
0933                    locale = Locale.getDefault();
0934                }
0935
0936                /**
0937                 * If an applet supplies an implementation of IIOMetadataFormat and
0938                 * resource bundles, then the resource bundle will need to be
0939                 * accessed via the applet class loader. So first try the context
0940                 * class loader to locate the resource bundle.
0941                 * If that throws MissingResourceException, then try the
0942                 * system class loader.
0943                 */
0944                ClassLoader loader = (ClassLoader) java.security.AccessController
0945                        .doPrivileged(new java.security.PrivilegedAction() {
0946                            public Object run() {
0947                                return Thread.currentThread()
0948                                        .getContextClassLoader();
0949                            }
0950                        });
0951
0952                ResourceBundle bundle = null;
0953                try {
0954                    bundle = ResourceBundle.getBundle(resourceBaseName, locale,
0955                            loader);
0956                } catch (MissingResourceException mre) {
0957                    try {
0958                        bundle = ResourceBundle.getBundle(resourceBaseName,
0959                                locale);
0960                    } catch (MissingResourceException mre1) {
0961                        return null;
0962                    }
0963                }
0964
0965                try {
0966                    return bundle.getString(key);
0967                } catch (MissingResourceException e) {
0968                    return null;
0969                }
0970            }
0971
0972            /**
0973             * Returns a <code>String</code> containing a description of the
0974             * named element, or <code>null</code>.  The desciption will be
0975             * localized for the supplied <code>Locale</code> if possible.
0976             *
0977             * <p> The default implementation will first locate a
0978             * <code>ResourceBundle</code> using the current resource base
0979             * name set by <code>setResourceBaseName</code> and the supplied
0980             * <code>Locale</code>, using the fallback mechanism described in
0981             * the comments for <code>ResourceBundle.getBundle</code>.  If a
0982             * <code>ResourceBundle</code> is found, the element name will be
0983             * used as a key to its <code>getString</code> method, and the
0984             * result returned.  If no <code>ResourceBundle</code> is found,
0985             * or no such key is present, <code>null</code> will be returned.
0986             * 
0987             * <p> If <code>locale</code> is <code>null</code>, the current
0988             * default <code>Locale</code> returned by <code>Locale.getLocale</code>
0989             * will be used.
0990             *
0991             * @param elementName the name of the element.
0992             * @param locale the <code>Locale</code> for which localization
0993             * will be attempted.
0994             *
0995             * @return the element description.
0996             *
0997             * @exception IllegalArgumentException if <code>elementName</code>
0998             * is <code>null</code>, or is not a legal element name for this format.
0999             *
1000             * @see #setResourceBaseName
1001             */
1002            public String getElementDescription(String elementName,
1003                    Locale locale) {
1004                Element element = getElement(elementName);
1005                return getResource(elementName, locale);
1006            }
1007
1008            // Children
1009
1010            public int getChildPolicy(String elementName) {
1011                Element element = getElement(elementName);
1012                return element.childPolicy;
1013            }
1014
1015            public String[] getChildNames(String elementName) {
1016                Element element = getElement(elementName);
1017                if (element.childPolicy == CHILD_POLICY_EMPTY) {
1018                    return null;
1019                }
1020                return (String[]) element.childList.toArray(new String[0]);
1021            }
1022
1023            // Attributes
1024
1025            public String[] getAttributeNames(String elementName) {
1026                Element element = getElement(elementName);
1027                List names = element.attrList;
1028
1029                String[] result = new String[names.size()];
1030                return (String[]) names.toArray(result);
1031            }
1032
1033            public int getAttributeValueType(String elementName, String attrName) {
1034                Attribute attr = getAttribute(elementName, attrName);
1035                return attr.valueType;
1036            }
1037
1038            public int getAttributeDataType(String elementName, String attrName) {
1039                Attribute attr = getAttribute(elementName, attrName);
1040                return attr.dataType;
1041            }
1042
1043            public boolean isAttributeRequired(String elementName,
1044                    String attrName) {
1045                Attribute attr = getAttribute(elementName, attrName);
1046                return attr.required;
1047            }
1048
1049            public String getAttributeDefaultValue(String elementName,
1050                    String attrName) {
1051                Attribute attr = getAttribute(elementName, attrName);
1052                return attr.defaultValue;
1053            }
1054
1055            public String[] getAttributeEnumerations(String elementName,
1056                    String attrName) {
1057                Attribute attr = getAttribute(elementName, attrName);
1058                if (attr.valueType != VALUE_ENUMERATION) {
1059                    throw new IllegalArgumentException(
1060                            "Attribute not an enumeration!");
1061                }
1062
1063                List values = attr.enumeratedValues;
1064                Iterator iter = values.iterator();
1065                String[] result = new String[values.size()];
1066                return (String[]) values.toArray(result);
1067            }
1068
1069            public String getAttributeMinValue(String elementName,
1070                    String attrName) {
1071                Attribute attr = getAttribute(elementName, attrName);
1072                if (attr.valueType != VALUE_RANGE
1073                        && attr.valueType != VALUE_RANGE_MIN_INCLUSIVE
1074                        && attr.valueType != VALUE_RANGE_MAX_INCLUSIVE
1075                        && attr.valueType != VALUE_RANGE_MIN_MAX_INCLUSIVE) {
1076                    throw new IllegalArgumentException("Attribute not a range!");
1077                }
1078
1079                return attr.minValue;
1080            }
1081
1082            public String getAttributeMaxValue(String elementName,
1083                    String attrName) {
1084                Attribute attr = getAttribute(elementName, attrName);
1085                if (attr.valueType != VALUE_RANGE
1086                        && attr.valueType != VALUE_RANGE_MIN_INCLUSIVE
1087                        && attr.valueType != VALUE_RANGE_MAX_INCLUSIVE
1088                        && attr.valueType != VALUE_RANGE_MIN_MAX_INCLUSIVE) {
1089                    throw new IllegalArgumentException("Attribute not a range!");
1090                }
1091
1092                return attr.maxValue;
1093            }
1094
1095            public int getAttributeListMinLength(String elementName,
1096                    String attrName) {
1097                Attribute attr = getAttribute(elementName, attrName);
1098                if (attr.valueType != VALUE_LIST) {
1099                    throw new IllegalArgumentException("Attribute not a list!");
1100                }
1101
1102                return attr.listMinLength;
1103            }
1104
1105            public int getAttributeListMaxLength(String elementName,
1106                    String attrName) {
1107                Attribute attr = getAttribute(elementName, attrName);
1108                if (attr.valueType != VALUE_LIST) {
1109                    throw new IllegalArgumentException("Attribute not a list!");
1110                }
1111
1112                return attr.listMaxLength;
1113            }
1114
1115            /**
1116             * Returns a <code>String</code> containing a description of the
1117             * named attribute, or <code>null</code>.  The desciption will be
1118             * localized for the supplied <code>Locale</code> if possible.
1119             *
1120             * <p> The default implementation will first locate a
1121             * <code>ResourceBundle</code> using the current resource base
1122             * name set by <code>setResourceBaseName</code> and the supplied
1123             * <code>Locale</code>, using the fallback mechanism described in
1124             * the comments for <code>ResourceBundle.getBundle</code>.  If a
1125             * <code>ResourceBundle</code> is found, the element name followed
1126             * by a "/" character followed by the attribute name
1127             * (<code>elementName + "/" + attrName</code>) will be used as a
1128             * key to its <code>getString</code> method, and the result
1129             * returned.  If no <code>ResourceBundle</code> is found, or no
1130             * such key is present, <code>null</code> will be returned.
1131             * 
1132             * <p> If <code>locale</code> is <code>null</code>, the current
1133             * default <code>Locale</code> returned by <code>Locale.getLocale</code>
1134             * will be used.
1135             *
1136             * @param elementName the name of the element.
1137             * @param attrName the name of the attribute.
1138             * @param locale the <code>Locale</code> for which localization
1139             * will be attempted, or <code>null</code>.
1140             *
1141             * @return the attribute description.
1142             *
1143             * @exception IllegalArgumentException if <code>elementName</code>
1144             * is <code>null</code>, or is not a legal element name for this format.
1145             * @exception IllegalArgumentException if <code>attrName</code> is
1146             * <code>null</code> or is not a legal attribute name for this
1147             * element.
1148             *
1149             * @see #setResourceBaseName
1150             */
1151            public String getAttributeDescription(String elementName,
1152                    String attrName, Locale locale) {
1153                Element element = getElement(elementName);
1154                if (attrName == null) {
1155                    throw new IllegalArgumentException("attrName == null!");
1156                }
1157                Attribute attr = (Attribute) element.attrMap.get(attrName);
1158                if (attr == null) {
1159                    throw new IllegalArgumentException("No such attribute!");
1160                }
1161
1162                String key = elementName + "/" + attrName;
1163                return getResource(key, locale);
1164            }
1165
1166            private ObjectValue getObjectValue(String elementName) {
1167                Element element = getElement(elementName);
1168                ObjectValue objv = (ObjectValue) element.objectValue;
1169                if (objv == null) {
1170                    throw new IllegalArgumentException(
1171                            "No object within element " + elementName + "!");
1172                }
1173                return objv;
1174            }
1175
1176            public int getObjectValueType(String elementName) {
1177                Element element = getElement(elementName);
1178                ObjectValue objv = (ObjectValue) element.objectValue;
1179                if (objv == null) {
1180                    return VALUE_NONE;
1181                }
1182                return objv.valueType;
1183            }
1184
1185            public Class<?> getObjectClass(String elementName) {
1186                ObjectValue objv = getObjectValue(elementName);
1187                return objv.classType;
1188            }
1189
1190            public Object getObjectDefaultValue(String elementName) {
1191                ObjectValue objv = getObjectValue(elementName);
1192                return objv.defaultValue;
1193            }
1194
1195            public Object[] getObjectEnumerations(String elementName) {
1196                ObjectValue objv = getObjectValue(elementName);
1197                if (objv.valueType != VALUE_ENUMERATION) {
1198                    throw new IllegalArgumentException("Not an enumeration!");
1199                }
1200                List vlist = objv.enumeratedValues;
1201                Object[] values = new Object[vlist.size()];
1202                return vlist.toArray(values);
1203            }
1204
1205            public Comparable<?> getObjectMinValue(String elementName) {
1206                ObjectValue objv = getObjectValue(elementName);
1207                if ((objv.valueType & VALUE_RANGE) != VALUE_RANGE) {
1208                    throw new IllegalArgumentException("Not a range!");
1209                }
1210                return objv.minValue;
1211            }
1212
1213            public Comparable<?> getObjectMaxValue(String elementName) {
1214                ObjectValue objv = getObjectValue(elementName);
1215                if ((objv.valueType & VALUE_RANGE) != VALUE_RANGE) {
1216                    throw new IllegalArgumentException("Not a range!");
1217                }
1218                return objv.maxValue;
1219            }
1220
1221            public int getObjectArrayMinLength(String elementName) {
1222                ObjectValue objv = getObjectValue(elementName);
1223                if (objv.valueType != VALUE_LIST) {
1224                    throw new IllegalArgumentException("Not a list!");
1225                }
1226                return objv.arrayMinLength;
1227            }
1228
1229            public int getObjectArrayMaxLength(String elementName) {
1230                ObjectValue objv = getObjectValue(elementName);
1231                if (objv.valueType != VALUE_LIST) {
1232                    throw new IllegalArgumentException("Not a list!");
1233                }
1234                return objv.arrayMaxLength;
1235            }
1236
1237            // Standard format descriptor
1238
1239            private synchronized static void createStandardFormat() {
1240                if (standardFormat == null) {
1241                    standardFormat = new StandardMetadataFormat();
1242                }
1243            }
1244
1245            /**
1246             * Returns an <code>IIOMetadataFormat</code> object describing the
1247             * standard, plug-in neutral <code>javax.imageio_1.0</code>
1248             * metadata document format described in the comment of the
1249             * <code>javax.imageio.metadata</code> package.
1250             *
1251             * @return a predefined <code>IIOMetadataFormat</code> instance.
1252             */
1253            public static IIOMetadataFormat getStandardFormatInstance() {
1254                createStandardFormat();
1255                return standardFormat;
1256            }
1257        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.