You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/11/24 23:29:44 UTC

svn commit: r479027 - in /harmony/enhanced/classlib/trunk/modules/imageio/src/main/java: javax/imageio/metadata/ javax/imageio/spi/ javax/imageio/stream/ org/apache/harmony/x/imageio/metadata/

Author: tellison
Date: Fri Nov 24 14:29:43 2006
New Revision: 479027

URL: http://svn.apache.org/viewvc?view=rev&rev=479027
Log:
Apply patch HARMONY-2309 ([classlib][imageio] Missing javax.imageio.metadata API and more)

Added:
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadataFormatImpl.java   (with props)
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormat.java   (with props)
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties   (with props)
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadata.java
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/spi/ImageReaderWriterSpi.java
    harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/stream/MemoryCacheImageInputStream.java

Modified: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadata.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadata.java?view=diff&rev=479027&r1=479026&r2=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadata.java (original)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadata.java Fri Nov 24 14:29:43 2006
@@ -14,18 +14,13 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
 package javax.imageio.metadata;
 
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- * 
- * TODO add all the methods from the spec
- */
+import java.util.ArrayList;
+
+import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
+import org.w3c.dom.Node;
+
 public abstract class IIOMetadata {
 
     protected boolean standardFormatSupported;
@@ -36,18 +31,179 @@
     protected IIOMetadataController defaultController;
     protected IIOMetadataController controller;
 
-    protected IIOMetadata() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
+    protected IIOMetadata() {}
 
     protected IIOMetadata(boolean standardMetadataFormatSupported,
                           String nativeMetadataFormatName,
                           String nativeMetadataFormatClassName,
                           String[] extraMetadataFormatNames,
                           String[] extraMetadataFormatClassNames) {
-        // TODO implement for SpecJBB
-        throw new UnsupportedOperationException("Not supported yet");
+        standardFormatSupported = standardMetadataFormatSupported;
+        this.nativeMetadataFormatName = nativeMetadataFormatName;
+        this.nativeMetadataFormatClassName = nativeMetadataFormatClassName;
+        if (extraMetadataFormatNames == null) {
+            if (extraMetadataFormatClassNames != null) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!"
+                );
+            }
+        } else {
+            if (extraMetadataFormatClassNames == null) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatNames != null && extraMetadataFormatClassNames == null!"
+                );
+            }
+            if (extraMetadataFormatNames.length == 0) {
+                throw new IllegalArgumentException("extraMetadataFormatNames.length == 0!");
+            }
+            if (extraMetadataFormatClassNames.length != extraMetadataFormatNames.length) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatClassNames.length != extraMetadataFormatNames.length!"
+                );
+            }
+            this.extraMetadataFormatNames = extraMetadataFormatNames.clone();
+            this.extraMetadataFormatClassNames = extraMetadataFormatClassNames.clone();
+        }
+    }
+
+    public abstract Node getAsTree(String formatName);
+    public abstract boolean isReadOnly();
+    public abstract void mergeTree(String formatName, Node root) throws IIOInvalidTreeException;
+    public abstract void reset();
+
+    public IIOMetadataController getController() {
+        return controller;
+    }
+
+    public boolean hasController() {
+        return getController() != null;
+    }
+
+    public boolean activateController() {
+        if (!hasController()) {
+            throw new IllegalStateException("hasController() == false!");
+        }
+        return getController().activate(this);
+    }
+
+    public IIOMetadataController getDefaultController() {
+        return defaultController;
     }
 
-    //-- TODO add all the methods from the spec
+    public String[] getExtraMetadataFormatNames() {
+        return extraMetadataFormatNames == null ? null : extraMetadataFormatNames.clone();
+    }
+
+    public IIOMetadataFormat getMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName,
+                standardFormatSupported,
+                nativeMetadataFormatName, nativeMetadataFormatClassName,
+                extraMetadataFormatNames, extraMetadataFormatClassNames
+        );
+    }
+
+    public String getNativeMetadataFormatName() {
+        return nativeMetadataFormatName;
+    }
+
+    public boolean isStandardMetadataFormatSupported() {
+        return standardFormatSupported;
+    }
+
+    public String[] getMetadataFormatNames() {
+        ArrayList<String> res = new ArrayList<String>();
+
+        String nativeMetadataFormatName = getNativeMetadataFormatName();
+        boolean standardFormatSupported = isStandardMetadataFormatSupported();
+        String extraMetadataFormatNames[] = getExtraMetadataFormatNames();
+
+        if (standardFormatSupported) {
+            res.add(IIOMetadataFormatImpl.standardMetadataFormatName);
+        }
+        if (nativeMetadataFormatName != null) {
+            res.add(nativeMetadataFormatName);
+        }
+        if (extraMetadataFormatNames != null) {
+            for (String extraMetadataFormatName : extraMetadataFormatNames) {
+                res.add(extraMetadataFormatName);
+            }
+        }
+
+        return res.size() > 0 ? res.toArray(new String[0]) : null;
+    }
+
+    protected IIOMetadataNode getStandardChromaNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardCompressionNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardDataNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardDimensionNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardDocumentNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardTextNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardTileNode() {
+        return null;
+    }
+
+    protected IIOMetadataNode getStandardTransparencyNode() {
+        return null;
+    }
+
+    protected final IIOMetadataNode getStandardTree() {
+        // Create root node
+        IIOMetadataNode root = new IIOMetadataNode(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+        Node node;
+        if ((node = getStandardChromaNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardCompressionNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDataNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDimensionNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDocumentNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTextNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTileNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTransparencyNode()) != null) {
+            root.appendChild(node);
+        }
+        
+        return root;
+    }
+
+    public void setController(IIOMetadataController controller) {
+        this.controller = controller;
+    }
+
+    public void setFromTree(String formatName, Node root) throws IIOInvalidTreeException {
+        reset();
+        mergeTree(formatName, root);
+    }
 }

Added: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadataFormatImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadataFormatImpl.java?view=auto&rev=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadataFormatImpl.java (added)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadataFormatImpl.java Fri Nov 24 14:29:43 2006
@@ -0,0 +1,651 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat {
+    @SuppressWarnings({"ConstantDeclaredInAbstractClass"})
+    public static final String standardMetadataFormatName = "javax_imageio_1.0";
+
+    @SuppressWarnings({"StaticNonFinalField"})
+    private static IIOMetadataFormatImpl standardFormat;
+
+    private String rootName;
+    private HashMap<String, Element> elementHash = new HashMap<String, Element>();
+
+    private String resourceBaseName = getClass().getName() + "Resources";
+
+    public IIOMetadataFormatImpl(String rootName, int childPolicy) {
+        if (rootName == null) {
+            throw new IllegalArgumentException("rootName is null");
+        }
+        if (
+                childPolicy < CHILD_POLICY_EMPTY ||
+                childPolicy > CHILD_POLICY_MAX ||
+                childPolicy == CHILD_POLICY_REPEAT
+        ) {
+            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
+        }
+
+        this.rootName = rootName;
+        Element root = new Element();
+        root.name = rootName;
+        root.childPolicy = childPolicy;
+        elementHash.put(rootName, root);
+    }
+
+    public IIOMetadataFormatImpl(String rootName, int minChildren, int maxChildren) {
+        if (rootName == null) {
+            throw new IllegalArgumentException("rootName is null");
+        }
+        if (minChildren < 0) {
+            throw new IllegalArgumentException("minChildren < 0!");
+        }
+        if (minChildren > maxChildren) {
+            throw new IllegalArgumentException("minChildren > maxChildren!");
+        }
+
+        this.rootName = rootName;
+        Element root = new Element();
+        root.name = rootName;
+        root.minChildren = minChildren;
+        root.maxChildren = maxChildren;
+        root.childPolicy = CHILD_POLICY_REPEAT;
+        elementHash.put(rootName, root);
+    }
+
+    @SuppressWarnings({"AbstractMethodOverridesAbstractMethod"})
+    public abstract boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
+
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, int listMinLength, int listMaxLength
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+        if (listMinLength < 0 || listMinLength > listMaxLength) {
+            throw new IllegalArgumentException("Invalid list bounds!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.listMinLength = listMinLength;
+        attr.listMaxLength = listMaxLength;
+        attr.valueType = VALUE_LIST;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.valueType = VALUE_ARBITRARY;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue, List<String> enumeratedValues
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
+            throw new IllegalArgumentException("enumeratedValues is empty or null");
+        }
+
+        try {
+            for (String enumeratedValue : enumeratedValues) {
+                if (enumeratedValue == null) {
+                    throw new IllegalArgumentException("enumeratedValues contains a null!");
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("enumeratedValues contains a non-String value!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.enumeratedValues = enumeratedValues;
+        attr.valueType = VALUE_ENUMERATION;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue,
+            String minValue, String maxValue,
+            boolean minInclusive, boolean maxInclusive
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.minValue = minValue;
+        attr.maxValue = maxValue;
+        attr.minInclusive = minInclusive;
+        attr.maxInclusive = maxInclusive;
+
+        attr.valueType = VALUE_RANGE;
+        attr.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
+        attr.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    protected void addBooleanAttribute(
+            String elementName, String attrName,
+            boolean hasDefaultValue, boolean defaultValue
+    ) {
+        String defaultVal = hasDefaultValue ? (defaultValue ? "TRUE" : "FALSE") : null;
+        ArrayList<String> values = new ArrayList<String>(2);
+        values.add("TRUE");
+        values.add("FALSE");
+
+        addAttribute(elementName, attrName, DATATYPE_BOOLEAN, true, defaultVal, values);
+    }
+
+    protected void addChildElement(String elementName, String parentName) {
+        Element parent = findElement(parentName);
+        Element element = findElement(elementName);
+        parent.children.add(element.name);
+    }
+
+    protected void addElement(String elementName, String parentName, int childPolicy) {
+        if (
+                childPolicy < CHILD_POLICY_EMPTY ||
+                childPolicy > CHILD_POLICY_MAX ||
+                childPolicy == CHILD_POLICY_REPEAT
+        ) {
+            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
+        }
+        
+        Element parent = findElement(parentName);
+        Element element = new Element();
+        element.name = elementName;
+        element.childPolicy = childPolicy;
+        elementHash.put(elementName, element);
+        parent.children.add(elementName);
+    }
+
+    protected void addElement(
+            String elementName, String parentName,
+            int minChildren, int maxChildren
+    ) {
+        if (minChildren < 0) {
+            throw new IllegalArgumentException("minChildren < 0!");
+        }
+        if (minChildren > maxChildren) {
+            throw new IllegalArgumentException("minChildren > maxChildren!");
+        }
+
+        Element parent = findElement(parentName);
+        Element element = new Element();
+        element.name = elementName;
+        element.childPolicy = CHILD_POLICY_REPEAT;
+        element.minChildren = minChildren;
+        element.maxChildren = maxChildren;
+        elementHash.put(elementName, element);
+        parent.children.add(elementName);
+    }
+
+    protected void addObjectValue(
+            String elementName, Class<?> classType,
+            int arrayMinLength, int arrayMaxLength
+    ) {
+        Element element = findElement(elementName);
+
+        ObjectValue objVal = new ObjectValue();
+        objVal.classType = classType;
+        objVal.arrayMaxLength = arrayMaxLength;
+        objVal.arrayMinLength = arrayMinLength;
+        objVal.valueType = VALUE_LIST;
+
+        element.objectValue = objVal;
+    }
+
+    protected <T> void addObjectValue(
+            String elementName, Class<T> classType,
+            boolean required, T defaultValue
+    ) {
+        // note: reqired is an unused parameter
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.valueType = VALUE_ARBITRARY;
+
+        element.objectValue = objVal;
+    }
+
+    protected <T> void addObjectValue(
+            String elementName, Class<T> classType,
+            boolean required, T defaultValue,
+            List<? extends T> enumeratedValues
+    ) {
+        // note: reqired is an unused parameter
+        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
+            throw new IllegalArgumentException("enumeratedValues is empty or null");
+        }
+
+        try {
+            for (T enumeratedValue : enumeratedValues) {
+                if (enumeratedValue == null) {
+                    throw new IllegalArgumentException("enumeratedValues contains a null!");
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("enumeratedValues contains a value not of class classType!");
+        }
+
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.enumeratedValues = enumeratedValues;
+        objVal.valueType = VALUE_ENUMERATION;
+
+        element.objectValue = objVal;
+    }
+
+    protected <T extends Object & Comparable<? super T>> void addObjectValue(
+            String elementName, Class<T> classType,
+            T defaultValue, Comparable<? super T> minValue, Comparable<? super T> maxValue,
+            boolean minInclusive, boolean maxInclusive
+    ) {
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.minValue = minValue;
+        objVal.maxValue = maxValue;
+        objVal.minInclusive = minInclusive;
+        objVal.maxInclusive = maxInclusive;
+
+        objVal.valueType = VALUE_RANGE;
+        objVal.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
+        objVal.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
+
+        element.objectValue = objVal;
+    }
+
+    public int getAttributeDataType(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.dataType;
+    }
+
+    public String getAttributeDefaultValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.defaultValue;
+    }
+
+    public String getAttributeDescription(String elementName, String attrName, Locale locale) {
+        findAttribute(elementName, attrName);
+        return getResourceString(elementName + "/" + attrName, locale);
+    }
+
+    public String[] getAttributeEnumerations(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_ENUMERATION) {
+            throw new IllegalArgumentException("Attribute is not an enumeration!");
+        }
+
+        return attr.enumeratedValues.toArray(new String[attr.enumeratedValues.size()]);
+    }
+
+    public int getAttributeListMaxLength(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Attribute is not a list!");
+        }
+        return attr.listMaxLength;
+    }
+
+    public int getAttributeListMinLength(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Attribute is not a list!");
+        }
+        return attr.listMinLength;
+    }
+
+    public String getAttributeMaxValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if ((attr.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Attribute is not a range!");
+        }
+        return attr.maxValue;        
+    }
+
+    public String getAttributeMinValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if ((attr.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Attribute is not a range!");
+        }
+        return attr.minValue;
+    }
+
+    public String[] getAttributeNames(String elementName) {
+        Element element = findElement(elementName);
+        return element.attributes.keySet().toArray(new String[element.attributes.size()]);
+    }
+
+    public int getAttributeValueType(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.valueType;                
+    }
+
+    public String[] getChildNames(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy == CHILD_POLICY_EMPTY) { // Element cannot have children
+            return null;
+        }
+        return element.children.toArray(new String[element.children.size()]);
+    }
+
+    public int getChildPolicy(String elementName) {
+        Element element = findElement(elementName);
+        return element.childPolicy;
+    }
+
+    public String getElementDescription(String elementName, Locale locale) {
+        findElement(elementName); // Check if there is such element
+        return getResourceString(elementName, locale);
+    }
+
+    public int getElementMaxChildren(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy != CHILD_POLICY_REPEAT) {
+            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
+        }
+        return element.maxChildren;
+    }
+
+    public int getElementMinChildren(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy != CHILD_POLICY_REPEAT) {
+            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
+        }
+        return element.minChildren;
+    }
+
+    public int getObjectArrayMaxLength(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Not a list!");
+        }
+        return v.arrayMaxLength;
+    }
+
+    public int getObjectArrayMinLength(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Not a list!");
+        }
+        return v.arrayMinLength;
+    }
+
+    public Class<?> getObjectClass(String elementName) {
+        ObjectValue v = findObjectValue(elementName);
+        return v.classType;
+    }
+
+    public Object getObjectDefaultValue(String elementName) {
+        ObjectValue v = findObjectValue(elementName);
+        return v.defaultValue;
+    }
+
+    public Object[] getObjectEnumerations(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_ENUMERATION) {
+            throw new IllegalArgumentException("Not an enumeration!");
+        }
+        return v.enumeratedValues.toArray();
+    }
+
+    public Comparable<?> getObjectMaxValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Not a range!");
+        }
+        return v.maxValue;
+    }
+
+    public Comparable<?> getObjectMinValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Not a range!");
+        }
+        return v.minValue;
+    }
+
+    public int getObjectValueType(String elementName) {
+        Element element = findElement(elementName);
+        if (element.objectValue == null) {
+            return VALUE_NONE;
+        }
+        return element.objectValue.valueType;
+    }
+
+    protected String getResourceBaseName() {
+        return resourceBaseName;
+    }
+
+    public String getRootName() {
+        return rootName;
+    }
+
+    public static IIOMetadataFormat getStandardFormatInstance() {
+        if (standardFormat == null) {
+            standardFormat = new IIOStandardMetadataFormat();
+        }
+
+        return standardFormat;
+    }
+
+    public boolean isAttributeRequired(String elementName, String attrName) {
+        return findAttribute(elementName, attrName).required;
+    }
+
+    protected void removeAttribute(String elementName, String attrName) {
+        Element element = findElement(elementName);
+        element.attributes.remove(attrName);
+    }
+
+    protected void removeElement(String elementName) {
+        Element element;
+        if ((element = elementHash.get(elementName)) != null) {
+            elementHash.remove(elementName);
+            for (Element e : elementHash.values()) {
+                e.children.remove(element.name);
+            }
+        }
+    }
+
+    protected void removeObjectValue(String elementName) {
+        Element element = findElement(elementName);
+        element.objectValue = null;
+    }
+    
+    protected void setResourceBaseName(String resourceBaseName) {
+        if (resourceBaseName == null) {
+            throw new IllegalArgumentException("resourceBaseName == null!");
+        }
+        this.resourceBaseName = resourceBaseName;
+    }
+
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class Element {
+        String name;
+
+        ArrayList<String> children = new ArrayList<String>();
+        HashMap<String, Attlist> attributes = new HashMap<String, Attlist>();
+
+        int minChildren;
+        int maxChildren;
+        int childPolicy;
+
+        ObjectValue objectValue;
+    }
+
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class Attlist {
+        String name;
+
+        int dataType;
+        boolean required;
+        int listMinLength;
+        int listMaxLength;
+        String defaultValue;
+        List<String> enumeratedValues;
+        String minValue;
+        String maxValue;
+        boolean minInclusive;
+        boolean maxInclusive;
+
+        int valueType;
+    }
+
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class ObjectValue<T> {
+        Class<T> classType;
+        int arrayMinLength;
+        int arrayMaxLength;
+        T defaultValue;
+        List<? extends T> enumeratedValues;
+        Comparable<? super T> minValue;
+        Comparable<? super T> maxValue;
+        boolean minInclusive;
+        boolean maxInclusive;
+
+        int valueType;
+    }
+
+    private Element findElement(String name) {
+        Element element;
+        if ((element = elementHash.get(name)) == null) {
+            throw new IllegalArgumentException("element name is null or no such element: " + name);
+        }
+
+        return element;
+    }
+
+    private Attlist findAttribute(String elementName, String attributeName) {
+        Element element = findElement(elementName);
+        Attlist attribute;
+        if ((attribute = element.attributes.get(attributeName)) == null) {
+            throw new IllegalArgumentException("attribute name is null or no such attribute: " + attributeName);
+        }
+
+        return attribute;
+    }
+
+    private ObjectValue findObjectValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null) {
+            throw new IllegalArgumentException("No object within element");
+        }
+        return v;
+    }
+
+    private String getResourceString(String key, Locale locale) {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+
+        // Get the context class loader and try to locate the bundle with it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        // Now try to get the resource bundle
+        ResourceBundle rb;
+        try {
+            rb = ResourceBundle.getBundle(resourceBaseName, locale, contextClassloader);
+        } catch (MissingResourceException e) {
+            try {
+                rb = ResourceBundle.getBundle(resourceBaseName, locale);
+            } catch (MissingResourceException e1) {
+                return null;
+            }
+        }
+
+        try {
+            return rb.getString(key);
+        } catch (MissingResourceException e) {
+            return null;
+        } catch (ClassCastException e) {
+            return null; // Not a string resource
+        }
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOMetadataFormatImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormat.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormat.java?view=auto&rev=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormat.java (added)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormat.java Fri Nov 24 14:29:43 2006
@@ -0,0 +1,305 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.ArrayList;
+
+class IIOStandardMetadataFormat  extends IIOMetadataFormatImpl {
+    public IIOStandardMetadataFormat() {
+        super(standardMetadataFormatName, CHILD_POLICY_SOME);
+        buildDTD();
+    }
+
+    @Override
+    public boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType) {
+        return true;
+    }
+
+    private void buildDTD() {
+        // CHROMA
+        addElement("Chroma", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("ColorSpaceType", "Chroma", CHILD_POLICY_EMPTY);
+
+        ArrayList<String> values = new ArrayList<String>(27);
+        values.add("XYZ");
+        values.add("Lab");
+        values.add("Luv");
+        values.add("YCbCr");
+        values.add("Yxy");
+        values.add("YCCK");
+        values.add("PhotoYCC");
+        values.add("RGB");
+        values.add("GRAY");
+        values.add("HSV");
+        values.add("HLS");
+        values.add("CMYK");
+        values.add("CMY");
+        values.add("2CLR");
+        values.add("3CLR");
+        values.add("4CLR");
+        values.add("5CLR");
+        values.add("6CLR");
+        values.add("7CLR");
+        values.add("8CLR");
+        values.add("9CLR");
+        values.add("ACLR");
+        values.add("BCLR");
+        values.add("CCLR");
+        values.add("DCLR");
+        values.add("ECLR");
+        values.add("FCLR");
+        addAttribute("ColorSpaceType", "name", DATATYPE_STRING, true, null, values);
+
+        addElement("NumChannels", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("NumChannels", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE); // list - why?
+
+        addElement("Gamma", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("Gamma", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("BlackIsZero", "Chroma", CHILD_POLICY_EMPTY);
+        addBooleanAttribute("BlackIsZero", "value", true, true);
+
+        addElement("Palette", "Chroma", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+        addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY);
+        addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "blue", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "alpha", DATATYPE_INTEGER, false, "255");
+
+        addElement("BackgroundIndex", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("BackgroundIndex", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("BackgroundColor", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("BackgroundColor", "red", DATATYPE_INTEGER, true, null);
+        addAttribute("BackgroundColor", "green", DATATYPE_INTEGER, true, null);
+        addAttribute("BackgroundColor", "blue", DATATYPE_INTEGER, true, null);
+
+        // COMPRESSION
+        addElement("Compression", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("CompressionTypeName", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("CompressionTypeName", "value", DATATYPE_STRING, true, null);
+
+        addElement("Lossless", "Compression", CHILD_POLICY_EMPTY);
+        addBooleanAttribute("Lossless", "value", true, true);
+
+        addElement("NumProgressiveScans", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("NumProgressiveScans", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("BitRate", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("BitRate", "value", DATATYPE_FLOAT, true, null);
+
+        // DATA
+        addElement("Data", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("PlanarConfiguration", "Data", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(4);
+        values.add("PixelInterleaved");
+        values.add("PlaneInterleaved");
+        values.add("LineInterleaved");
+        values.add("TileInterleaved");
+        addAttribute("PlanarConfiguration", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("SampleFormat", "Data", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(4);
+        values.add("SignedIntegral");
+        values.add("UnsignedIntegral");
+        values.add("Real");
+        values.add("Index");
+        addAttribute("SampleFormat", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("BitsPerSample", "Data", CHILD_POLICY_EMPTY);
+        addAttribute("BitsPerSample", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
+
+        addElement("SignificantBitsPerSample", "Data", CHILD_POLICY_EMPTY);
+        addAttribute(
+                "SignificantBitsPerSample", "value",
+                DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE
+        ); // list
+
+        addElement("SampleMSB", "Data", CHILD_POLICY_EMPTY);
+        addAttribute("SampleMSB", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
+
+        // DIMENSION
+        addElement("Dimension", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("PixelAspectRatio", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("PixelAspectRatio", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("ImageOrientation", "Dimension", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(8);
+        values.add("Normal");
+        values.add("Rotate90");
+        values.add("Rotate180");
+        values.add("Rotate270");
+        values.add("FlipH");
+        values.add("FlipV");
+        values.add("FlipHRotate90");
+        values.add("FlipVRotate90");
+        addAttribute("ImageOrientation", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("HorizontalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPixelSize", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPixelSize", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPosition", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPosition", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPosition", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPosition", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPixelOffset", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("VerticalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPixelOffset", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("HorizontalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalScreenSize", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("VerticalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalScreenSize", "value", DATATYPE_INTEGER, true, null);
+
+        // DOCUMENT
+        addElement("Document", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("FormatVersion", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("FormatVersion", "value", DATATYPE_STRING, true, null);
+
+        addElement("SubimageInterpretation", "Document", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(14);
+        values.add("Standalone");
+        values.add("SinglePage");
+        values.add("FullResolution");
+        values.add("ReducedResolution");
+        values.add("PyramidLayer");
+        values.add("Preview");
+        values.add("VolumeSlice");
+        values.add("ObjectView");
+        values.add("Panorama");
+        values.add("AnimationFrame");
+        values.add("TransparencyMask");
+        values.add("CompositingLayer");
+        values.add("SpectralSlice");
+        values.add("Unknown");
+        addAttribute("SubimageInterpretation", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("ImageCreationTime", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("ImageCreationTime", "year", DATATYPE_INTEGER, true, null);
+        addAttribute(
+                "ImageCreationTime", "month",
+                DATATYPE_INTEGER, true, null, "1", "12", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "day",
+                DATATYPE_INTEGER, true, null, "1", "31", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "hour",
+                DATATYPE_INTEGER, false, "0", "0", "23", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "minute",
+                DATATYPE_INTEGER, false, "0", "0", "59", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "second",
+                DATATYPE_INTEGER, false, "0", "0", "60", true, true
+        );
+
+        addElement("ImageModificationTime", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("ImageModificationTime", "year", DATATYPE_INTEGER, true, null);
+        addAttribute(
+                "ImageModificationTime", "month",
+                DATATYPE_INTEGER, true, null, "1", "12", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "day",
+                DATATYPE_INTEGER, true, null, "1", "31", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "hour",
+                DATATYPE_INTEGER, false, "0", "0", "23", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "minute",
+                DATATYPE_INTEGER, false, "0", "0", "59", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "second",
+                DATATYPE_INTEGER, false, "0", "0", "60", true, true
+        );
+
+        // TEXT
+        addElement("Text", standardMetadataFormatName, 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("TextEntry", "Text", CHILD_POLICY_EMPTY);
+        addAttribute("TextEntry", "keyword", DATATYPE_STRING, false, null);
+        addAttribute("TextEntry", "value", DATATYPE_STRING, true, null);
+        addAttribute("TextEntry", "language", DATATYPE_STRING, false, null);
+        addAttribute("TextEntry", "encoding", DATATYPE_STRING, false, null);
+        values = new ArrayList<String>(5);
+        values.add("none");
+        values.add("lzw");
+        values.add("zip");
+        values.add("bzip");
+        values.add("other");
+        addAttribute("TextEntry", "compression", DATATYPE_STRING, false, "none", values);
+
+        // TRANSPARENCY
+        addElement("Transparency", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("Alpha", "Transparency", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(3);
+        values.add("none");
+        values.add("premultiplied");
+        values.add("nonpremultiplied");
+        addAttribute("Alpha", "value", DATATYPE_STRING, false, "none", values);
+
+        addElement("TransparentIndex", "Transparency", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentIndex", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("TransparentColor", "Transparency", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentColor", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE);
+
+        addElement("TileTransparencies", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("TransparentTile", "TileTransparencies", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentTile", "x", DATATYPE_INTEGER, true, null);
+        addAttribute("TransparentTile", "y", DATATYPE_INTEGER, true, null);
+
+        addElement("TileOpacities", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("OpaqueTile", "TileOpacities", CHILD_POLICY_EMPTY);
+        addAttribute("OpaqueTile", "x", DATATYPE_INTEGER, true, null);
+        addAttribute("OpaqueTile", "y", DATATYPE_INTEGER, true, null);
+    }
+}
+

Propchange: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties?view=auto&rev=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties (added)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties Fri Nov 24 14:29:43 2006
@@ -0,0 +1,133 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+# Descriptions of elements and attributes of the plugin neutral metadata format
+# (see IIOStandardMetadataFormat)
+
+# Messages for EN locale
+Chroma=Chroma (color) information
+ColorSpaceType=The raw color space of the image
+ColorSpaceType/name=The raw color space of the image
+NumChannels=The number of channels in the raw image, including alpha
+NumChannels/value=The number of channels in the raw image, including alpha
+Gamma=The image gamma
+Gamma/value=The image gamma
+BlackIsZero=True if smaller values represent darker shades
+BlackIsZero/value=True if smaller values represent darker shades
+Palette=Palette-color information
+PaletteEntry=A palette entry
+PaletteEntry/index=The index of the palette entry
+PaletteEntry/red=The red value for the palette entry
+PaletteEntry/green=The green value for the palette entry
+PaletteEntry/blue=The blue value for the palette entry
+PaletteEntry/alpha=The alpha value for the palette entry
+BackgroundIndex=A palette index to be used as a background
+BackgroundIndex/value=A palette index to be used as a background
+BackgroundColor=An RGB triple to be used as a background
+BackgroundColor/red=The red background value
+BackgroundColor/green=The green background value
+BackgroundColor/blue=The blue background value
+
+Compression=Compression information
+CompressionTypeName=The name of the compression scheme in use
+CompressionTypeName/value=The name of the compression scheme in use
+Lossless=True if the compression scheme is lossless
+Lossless/value=True if the compression scheme is lossless
+NumProgressiveScans=The number of progressive scans used in the image encoding
+NumProgressiveScans/value=The number of progressive scans used in the image encoding
+BitRate=The estimated bit rate of the compression scheme
+BitRate/value=The estimated bit rate of the compression scheme
+
+Data=Information on the image layout
+PlanarConfiguration=The organization of image samples in the stream
+PlanarConfiguration/value=The organization of image samples in the stream
+SampleFormat=The numeric format of image samples
+SampleFormat/value=The numeric format of image samples
+BitsPerSample=The number of bits per sample
+BitsPerSample/value=A list of integers, one per channel
+SignificantBitsPerSample=The number of significant bits per sample
+SignificantBitsPerSample/value=A list of integers, one per channel
+SampleMSB=The position of the most significant bit of each sample
+SampleMSB/value=A list of integers, one per channel
+
+Dimension=Dimension information
+PixelAspectRatio=The width of a pixel divided by its height
+PixelAspectRatio/value=The width of a pixel divided by its height
+ImageOrientation=The desired orientation of the image in terms of flips and counter-clockwise rotations
+ImageOrientation/value=The desired orientation of the image in terms of flips and counter-clockwise rotations
+HorizontalPixelSize=The width of a pixel, in millimeters, as it should be rendered on media
+HorizontalPixelSize/value=The width of a pixel, in millimeters, as it should be rendered on media
+VerticalPixelSize=The height of a pixel, in millimeters, as it should be rendered on media
+VerticalPixelSize/value=The height of a pixel, in millimeters, as it should be rendered on media
+HorizontalPhysicalPixelSpacing=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+HorizontalPhysicalPixelSpacing/value=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+VerticalPhysicalPixelSpacing=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+VerticalPhysicalPixelSpacing/value=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+HorizontalPosition=The horizontal position, in millimeters, where the image should be rendered on media
+HorizontalPosition/value=The horizontal position, in millimeters, where the image should be rendered on media
+VerticalPosition=The vertical position, in millimeters, where the image should be rendered on media
+VerticalPosition/value=The vertical position, in millimeters, where the image should be rendered on media
+HorizontalPixelOffset=The horizonal position, in pixels, where the image should be rendered onto a raster display
+HorizontalPixelOffset/value=The horizonal position, in pixels, where the image should be rendered onto a raster display
+VerticalPixelOffset=The vertical position, in pixels, where the image should be rendered onto a raster display
+VerticalPixelOffset/value=The vertical position, in pixels, where the image should be rendered onto a raster display
+HorizontalScreenSize=The width, in pixels, of the raster display into which the image should be rendered
+HorizontalScreenSize/value=The width, in pixels, of the raster display into which the image should be rendered
+VerticalScreenSize=The height, in pixels, of the raster display into which the image should be rendered
+VerticalScreenSize/value=The height, in pixels, of the raster display into which the image should be rendered
+
+Document=Document information
+FormatVersion=The version of the format used by the stream
+FormatVersion/value=The version of the format used by the stream
+SubimageInterpretation=The interpretation of this image in relation to the other images stored in the same stream
+SubimageInterpretation/value=The interpretation of this image in relation to the other images stored in the same stream
+ImageCreationTime=The time of image creation
+ImageCreationTime/year=The full year (e.g., 1967, not 67)
+ImageCreationTime/month=The month, with January = 1
+ImageCreationTime/day=The day of the month
+ImageCreationTime/hour=The hour from 0 to 23
+ImageCreationTime/minute=The minute from 0 to 59
+ImageCreationTime/second=The second from 0 to 60 (60 = leap second)
+ImageModificationTime=The time of the last image modification
+ImageModificationTime/year=The full year (e.g., 1967, not 67)
+ImageModificationTime/month=The month, with January = 1
+ImageModificationTime/day=The day of the month
+ImageModificationTime/hour=The hour from 0 to 23
+ImageModificationTime/minute=The minute from 0 to 59
+ImageModificationTime/second=The second from 0 to 60 (60 = leap second)
+
+Text=Text information
+TextEntry=A text entry
+TextEntry/keyword=A keyword associated with the text entry
+TextEntry/value=the text entry
+TextEntry/language=The language of the text
+TextEntry/encoding=The encoding of the text
+TextEntry/compression=The method used to compress the text
+
+Transparency=Transparency information
+Alpha=The type of alpha information contained in the image
+Alpha/value=The type of alpha information contained in the image
+TransparentIndex=A palette index to be treated as transparent
+TransparentIndex/value=A palette index to be treated as transparent
+TransparentColor=An RGB color to be treated as transparent
+TransparentColor/value=An RGB color to be treated as transparent
+TileTransparencies=A list of completely transparent tiles
+TransparentTile=The index of a completely transparent tile
+TransparentTile/x=The tile's X index
+TransparentTile/y=The tile's Y index
+TileOpacities=A list of completely opaque tiles
+OpaqueTile=The index of a completely opaque tile
+OpaqueTile/x=The tile's X index
+OpaqueTile/y=The tile's Y index

Propchange: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/spi/ImageReaderWriterSpi.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/spi/ImageReaderWriterSpi.java?view=diff&rev=479027&r1=479026&r2=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/spi/ImageReaderWriterSpi.java (original)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/spi/ImageReaderWriterSpi.java Fri Nov 24 14:29:43 2006
@@ -20,9 +20,10 @@
  */
 package javax.imageio.spi;
 
-/**
- * TODO add all the methods from the spec
- */
+import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
+
+import javax.imageio.metadata.IIOMetadataFormat;
+
 public abstract class ImageReaderWriterSpi extends IIOServiceProvider
         implements RegisterableService {
 
@@ -56,7 +57,7 @@
                                 String[] extraImageMetadataFormatClassNames) {
         super(vendorName, version);
 
-        if (names == null || names.length == 0 || pluginClassName == null) {
+        if (names == null || names.length == 0) {
             throw new NullPointerException("format names array cannot be NULL or empty");
         }
 
@@ -64,32 +65,93 @@
             throw new NullPointerException("Plugin class name cannot be NULL");
         }
 
-
-        this.names = names;
-        this.suffixes = suffixes;
-        this.MIMETypes = MIMETypes;
+        // We clone all the arrays to be consistent with the fact that
+        // some methods of this class must return clones of the arrays
+        // as it is stated in the spec.
+        this.names = names.clone();
+        this.suffixes = suffixes == null ? null : suffixes.clone();
+        this.MIMETypes = MIMETypes == null ? null : MIMETypes.clone();
         this.pluginClassName = pluginClassName;
         this.supportsStandardStreamMetadataFormat = supportsStandardStreamMetadataFormat;
         this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName;
         this.nativeStreamMetadataFormatClassName = nativeStreamMetadataFormatClassName;
-        this.extraStreamMetadataFormatNames = extraStreamMetadataFormatNames;
-        this.extraStreamMetadataFormatClassNames = extraStreamMetadataFormatClassNames;
+
+        this.extraStreamMetadataFormatNames =
+                extraStreamMetadataFormatNames == null ?
+                null : extraStreamMetadataFormatNames.clone();
+
+        this.extraStreamMetadataFormatClassNames =
+                extraStreamMetadataFormatClassNames == null ?
+                null : extraStreamMetadataFormatClassNames.clone();
+
         this.supportsStandardImageMetadataFormat = supportsStandardImageMetadataFormat;
         this.nativeImageMetadataFormatName = nativeImageMetadataFormatName;
         this.nativeImageMetadataFormatClassName = nativeImageMetadataFormatClassName;
-        this.extraImageMetadataFormatNames = extraImageMetadataFormatNames;
-        this.extraImageMetadataFormatClassNames = extraImageMetadataFormatClassNames;
-    }
 
-    public ImageReaderWriterSpi() {
-        throw new UnsupportedOperationException("Not implemented yet");
+        this.extraImageMetadataFormatNames =
+                extraImageMetadataFormatNames == null ?
+                null : extraImageMetadataFormatNames.clone();
+
+        this.extraImageMetadataFormatClassNames =
+                extraImageMetadataFormatClassNames == null ?
+                null : extraImageMetadataFormatClassNames.clone();
     }
 
+    public ImageReaderWriterSpi() {}
+
     public String[] getFormatNames() {
-        return names;
+        return names.clone();
     }
 
     public String[] getFileSuffixes() {
-        return suffixes;
+        return suffixes == null ? null : suffixes.clone();
+    }
+
+    public String[] getExtraImageMetadataFormatNames() {
+        return extraImageMetadataFormatNames == null ? null : extraImageMetadataFormatNames.clone();
+    }
+
+    public String[] getExtraStreamMetadataFormatNames() {
+        return extraStreamMetadataFormatNames == null ? null : extraStreamMetadataFormatNames.clone();
+    }
+
+    public IIOMetadataFormat getImageMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames
+        );
+    }
+
+    public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName, supportsStandardStreamMetadataFormat,
+                nativeStreamMetadataFormatName, nativeStreamMetadataFormatClassName,
+                extraStreamMetadataFormatNames, extraStreamMetadataFormatClassNames
+        );
+    }
+
+    public String[] getMIMETypes() {
+        return MIMETypes == null ? null : MIMETypes.clone();
+    }
+
+    public String getNativeImageMetadataFormatName() {
+        return nativeImageMetadataFormatName;
+    }
+
+    public String getNativeStreamMetadataFormatName() {
+        return nativeStreamMetadataFormatName;
+    }
+
+    public String getPluginClassName() {
+        return pluginClassName;
+    }
+
+    public boolean isStandardImageMetadataFormatSupported() {
+        return supportsStandardImageMetadataFormat;
+    }
+
+    public boolean isStandardStreamMetadataFormatSupported() {
+        return supportsStandardStreamMetadataFormat;
     }
 }

Modified: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/stream/MemoryCacheImageInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/stream/MemoryCacheImageInputStream.java?view=diff&rev=479027&r1=479026&r2=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/stream/MemoryCacheImageInputStream.java (original)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/javax/imageio/stream/MemoryCacheImageInputStream.java Fri Nov 24 14:29:43 2006
@@ -27,7 +27,7 @@
     private InputStream is;
     private RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
 
-    public MemoryCacheImageInputStream(InputStream stream) throws IOException {
+    public MemoryCacheImageInputStream(InputStream stream) {
         if (stream == null) {
             throw new IllegalArgumentException("stream == null!");
         }

Added: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java?view=auto&rev=479027
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java (added)
+++ harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java Fri Nov 24 14:29:43 2006
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.metadata;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+
+public class IIOMetadataUtils {
+    private IIOMetadataUtils() {} 
+
+    public static IIOMetadataFormat instantiateMetadataFormat(
+            String formatName, boolean standardFormatSupported,
+            String nativeMetadataFormatName, String nativeMetadataFormatClassName,
+            String [] extraMetadataFormatNames, String [] extraMetadataFormatClassNames
+    ) {
+        if (formatName == null) {
+            throw new IllegalArgumentException("formatName == null!");
+        }
+        if (formatName.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
+            if (standardFormatSupported) {
+                return IIOMetadataFormatImpl.getStandardFormatInstance();
+            }
+        }
+
+        String className = null;
+
+        if (formatName.equals(nativeMetadataFormatName)) {
+            className = nativeMetadataFormatClassName;
+        } else if (extraMetadataFormatNames != null) {
+            for (int i = 0; i < extraMetadataFormatNames.length; i++) {
+                if (formatName.equals(extraMetadataFormatNames[i])) {
+                    className = extraMetadataFormatClassNames[i];
+                    break;
+                }
+            }
+        }
+
+        if (className == null) {
+            throw new IllegalArgumentException("Unsupported format name");
+        }
+
+        // Get the context class loader and try to use it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        Class cls;
+
+        try {
+            cls = Class.forName(className, true, contextClassloader);
+        } catch (ClassNotFoundException e) {
+            try {
+                // Use current class loader
+                cls = Class.forName(className);
+            } catch (ClassNotFoundException e1) {
+                throw new IllegalStateException ("Can't obtain format");
+            }
+        }
+
+        try {
+            Method getInstance = cls.getMethod("getInstance");
+            return (IIOMetadataFormat) getInstance.invoke(null);
+        } catch (Exception e) {
+            IllegalStateException e1 = new IllegalStateException("Can't obtain format");
+            e1.initCause(e); // Add some details to the message
+            throw e1;
+        }
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/imageio/src/main/java/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native