changeset 5827:0ecf1a700fca

7186799: Regression tests for ImageIO metadata fail on second run Reviewed-by: prr, bae Contributed-by: Vadim Pakhnushev <vadim.pakhnushev@oracle.com>
author bae
date Mon, 17 Sep 2012 13:44:07 +0400
parents bce9611f1e8f
children a96f5b1d03f9 4d8b411a2bc1
files test/javax/imageio/metadata/BooleanAttributes.java test/javax/imageio/metadata/DOML3Node.java test/javax/imageio/metadata/GetChildNames.java test/javax/imageio/metadata/GetObjectMinValue.java test/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatTest.java test/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatThreadTest.java test/javax/imageio/metadata/IIOMetadataFormat/MetadataTest.java test/javax/imageio/metadata/IIOMetadataFormat/UserPluginMetadataFormatTest.java test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh test/javax/imageio/metadata/IIOMetadataFormatImplTest.java test/javax/imageio/metadata/MetadataFormatPrinter.java test/javax/imageio/metadata/ObjectArrayMaxLength.java test/javax/imageio/metadata/RegisteredFormatsTest.java test/javax/imageio/metadata/RemoveElement.java test/javax/imageio/metadata/SetAttributeNode.java
diffstat 16 files changed, 2438 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/test/javax/imageio/metadata/BooleanAttributes.java	Fri Sep 14 13:52:30 2012 -0700
+++ b/test/javax/imageio/metadata/BooleanAttributes.java	Mon Sep 17 13:44:07 2012 +0400
@@ -1,12 +1,10 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
--- a/test/javax/imageio/metadata/DOML3Node.java	Fri Sep 14 13:52:30 2012 -0700
+++ b/test/javax/imageio/metadata/DOML3Node.java	Mon Sep 17 13:44:07 2012 +0400
@@ -1,12 +1,10 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/GetChildNames.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4429876
+ * @run main GetChildNames
+ * @summary Tests that the getChildNames method of
+ * IIOMetadataFormatImpl returns null for a CHILD_POLICY_EMPTY node.
+ */
+
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.ImageTypeSpecifier;
+
+public class GetChildNames {
+
+    public static void main(String argv[]) {
+        GCNFormatImpl fmt = new GCNFormatImpl("root", 1, 10);
+        fmt.addElement("cc", "root", fmt.CHILD_POLICY_EMPTY);
+
+        String[] result = fmt.getChildNames("cc");
+        if (result != null) {
+            throw new RuntimeException
+                ("Failed, result is not null: " + result);
+        }
+    }
+}
+
+class GCNFormatImpl extends IIOMetadataFormatImpl {
+
+    GCNFormatImpl(String root, int minChildren, int maxChildren) {
+        super(root, minChildren, maxChildren);
+    }
+
+    public void addElement(String elementName,
+                           String parentName, int childPolicy) {
+        super.addElement(elementName, parentName, childPolicy);
+    }
+
+    public boolean canNodeAppear(String elementName,
+                                 ImageTypeSpecifier imageType) {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/GetObjectMinValue.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4429875 7186799
+ * @compile -source 1.4 GetObjectMinValue.java
+ * @run main GetObjectMinValue
+ * @summary Tests the getObject{Min,Max}Value method of
+ * IIOMetadataFormatImpl for an inclusive range
+ */
+
+// Compiled with -source 1.4 to work around javac bug 5041233
+
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.ImageTypeSpecifier;
+
+public class GetObjectMinValue {
+
+    public static void main(String argv[]) {
+        test(true, true);
+        test(true, false);
+        test(false, true);
+        test(false, false);
+    }
+
+    private static void test(boolean minInclusive, boolean maxInclusive) {
+        Integer defValue = new Integer(1);
+        Integer minValue = new Integer(0);
+        Integer maxValue = new Integer(10);
+
+        MyFormatImpl fmt = new MyFormatImpl("root", 1, 10);
+
+        fmt.addObjectValue("root", defValue.getClass(), defValue,
+                           minValue, maxValue, minInclusive, maxInclusive);
+
+        try {
+            Integer act_min = (Integer)fmt.getObjectMinValue("root");
+            if (! act_min.equals(minValue))
+                throw new RuntimeException("invalid min value: " + act_min);
+        } catch (Throwable e) {
+            throw new RuntimeException
+                ("getObjectMinValue: unexpected exception: " + e);
+        }
+        try {
+            Integer act_max = (Integer)fmt.getObjectMaxValue("root");
+            if (! act_max.equals(maxValue))
+                throw new RuntimeException("invalid max value: " + act_max);
+        } catch (Throwable e) {
+            throw new RuntimeException
+                ("getObjectMaxValue: unexpected exception: " + e);
+        }
+    }
+
+    static class MyFormatImpl extends IIOMetadataFormatImpl {
+
+        MyFormatImpl(String root, int minChildren, int maxChildren) {
+            super(root, minChildren, maxChildren);
+        }
+
+        public void addObjectValue(String elementName,
+                                   Class classType, Object defaultValue,
+                                   Comparable minValue, Comparable maxValue,
+                                   boolean minInclusive, boolean maxInclusive) {
+            super.addObjectValue(elementName,
+                                 classType, defaultValue,
+                                 minValue, maxValue,
+                                 minInclusive, maxInclusive);
+        }
+
+        public boolean canNodeAppear(String elementName,
+                                     ImageTypeSpecifier imageType) {
+            return true;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatTest.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @bug 4929170
+ * @summary  Tests that user-supplied IIOMetadata implementations
+ *           is able to load correspnding IIOMetadataFormat implementations.
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+
+public class MetadataFormatTest {
+    public static void main(String[] args) throws Exception {
+        String codebase = args[0];
+        String code = args[1];
+
+        MetadataTest t = createTest(codebase, code);
+        try {
+            t.doTest();
+        } catch (IllegalStateException e) {
+            System.out.println("Test failed.");
+            e.printStackTrace();
+
+            System.exit(1);
+        }
+    }
+
+    protected static MetadataTest createTest(String codebase,
+                                             String code) throws Exception {
+        URL[] urls = { new File(codebase).toURL()};
+        ClassLoader loader = new URLClassLoader(urls);
+
+        Class ct = loader.loadClass(code);
+
+        return (MetadataTest)ct.newInstance();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatThreadTest.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @bug 4929170
+ * @summary Tests that user-supplied IIOMetadata implementations
+ *           is able to load correspnding IIOMetadataFormat implementations.
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+
+public class MetadataFormatThreadTest implements Runnable {
+
+    String test_class;
+
+    public static void main(String[] args) throws Exception {
+        String codebase = args[0];
+        String code = args[1];
+
+        Thread t = createTest(codebase, code);
+        try {
+            t.start();
+        } catch (IllegalStateException e) {
+            System.out.println("Test failed.");
+            e.printStackTrace();
+
+            System.exit(1);
+        }
+    }
+
+    public MetadataFormatThreadTest(String c) {
+        test_class = c;
+    }
+
+    public void run() {
+        try {
+            ClassLoader loader = (ClassLoader)
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction() {
+                            public Object run() {
+                                return Thread.currentThread().getContextClassLoader();
+                            }
+                        });
+
+            Class ct = loader.loadClass(test_class);
+
+            MetadataTest t = (MetadataTest)ct.newInstance();
+
+            t.doTest();
+        } catch (Exception e) {
+            System.out.println("Test failed.");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    protected static Thread createTest(String codebase,
+                                             String code) throws Exception {
+
+        URL[] urls = { new File(codebase).toURL()};
+        final ClassLoader loader = new URLClassLoader(urls);
+
+        final Thread t = new Thread(new MetadataFormatThreadTest(code));
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction() {
+                    public Object run() {
+                        t.setContextClassLoader(loader);
+                        return null;
+                    }
+                });
+
+        return t;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormat/MetadataTest.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @bug       4929170
+ * @summary   Interface for user-supplied IIOMetadata
+ *            implementation tests.
+ */
+
+import java.io.IOException;
+
+public interface MetadataTest {
+    public void doTest() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormat/UserPluginMetadataFormatTest.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     4929170
+ * @summary Tests that user-supplied IIOMetadata implementations loaded by
+ *           system class loader (i.e. corresponding classes are available via
+ *           classpath) is able to load correspnding IIOMetadataFormat
+ *           implementations.
+ * @run     main UserPluginMetadataFormatTest
+ */
+
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.util.Iterator;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Vector;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageReadParam;
+import javax.imageio.IIOException;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.event.IIOReadWarningListener;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.spi.ImageReaderSpi;
+import org.w3c.dom.Node;
+
+public class UserPluginMetadataFormatTest implements MetadataTest {
+
+    public static void main(String[] argv) throws IOException {
+        new UserPluginMetadataFormatTest().doTest();
+    }
+
+    public void doTest() throws IOException {
+
+        DummyImageReaderImpl reader;
+
+        reader = new DummyImageReaderImpl(new DummyImageReaderSpiImpl());
+
+        byte[] data = new byte[1024];
+        ByteArrayInputStream bais =
+            new ByteArrayInputStream(data);
+
+        reader.setInput(ImageIO.createImageInputStream(bais));
+        IIOMetadata metadata = reader.getImageMetadata(1);
+        if(metadata == null) {
+            throw new RuntimeException("IIOMetada is NULL");
+        }
+
+        String[] formatNames = metadata.getMetadataFormatNames();
+
+        for(int j=0; j<formatNames.length; j++) {
+
+            String formatName = formatNames[j];
+            System.out.println("\nFormat Names : " + formatName);
+
+            try {
+                IIOMetadataFormat metadataFormat =
+                    metadata.getMetadataFormat(formatName);
+                System.out.println("  Class Name " +
+                                   metadataFormat.getClass());
+            } catch(IllegalStateException ise) {
+                Throwable t = ise;
+                t.printStackTrace();
+                while(t.getCause() != null) {
+                    t = t.getCause();
+                    t.printStackTrace();
+                }
+                // test failed!
+                // stop applet!
+                System.out.println("Test faied.");
+                throw new RuntimeException("Test failed.", ise);
+            }
+        }
+    }
+
+    public static class DummyImageReaderImpl extends ImageReader {
+
+        public DummyImageReaderImpl(ImageReaderSpi originatingProvider) {
+            super(originatingProvider);
+        }
+
+        public int getNumImages(boolean allowSearch) throws IOException {
+            return 5;
+        }
+
+        public int getWidth(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            return 10;
+        }
+
+        public int getHeight(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            return 15;
+        }
+
+        public Iterator getImageTypes(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            Vector imageTypes = new Vector();
+            imageTypes.add(ImageTypeSpecifier.createFromBufferedImageType
+                           (BufferedImage.TYPE_BYTE_GRAY ));
+            return imageTypes.iterator();
+        }
+
+        public IIOMetadata getStreamMetadata() throws IOException {
+            return new DummyIIOMetadataImpl(true, null, null, null, null);
+        }
+
+        public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
+
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+            if (seekForwardOnly) {
+                if (imageIndex < minIndex)
+                    throw new IndexOutOfBoundsException();
+                minIndex = imageIndex;
+            }
+            System.out.println("Current format class name " + DummyIIOMetadataFormatImpl.class.getName());
+            return new DummyIIOMetadataImpl(true,
+                                            DummyIIOMetadataFormatImpl.nativeMetadataFormatName,
+                                            DummyIIOMetadataFormatImpl.class.getName(),
+                                            null, null);
+        }
+
+
+        public BufferedImage read(int imageIndex, ImageReadParam param)
+          throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+            if (seekForwardOnly) {
+                if (imageIndex < minIndex)
+                    throw new IndexOutOfBoundsException();
+                minIndex = imageIndex;
+            }
+
+            return getDestination(param, getImageTypes(imageIndex), 10, 15);
+        }
+
+        // protected  methods - now public
+
+        public  boolean abortRequested() {
+            return super.abortRequested();
+        }
+
+        public  void clearAbortRequest() {
+            super.clearAbortRequest();
+        }
+
+        public  void processImageComplete() {
+            super.processImageComplete();
+        }
+
+        public  void processImageProgress(float percentageDone) {
+            super.processImageProgress(percentageDone);
+        }
+
+        public  void processImageStarted(int imageIndex) {
+            super.processImageStarted(imageIndex);
+        }
+
+        public  void processImageUpdate(BufferedImage theImage,
+                                        int minX,
+                                        int minY,
+                                        int width,
+                                        int height,
+                                        int periodX,
+                                        int periodY,
+                                        int[] bands) {
+            super.processImageUpdate(theImage,
+                                     minX,
+                                     minY,
+                                     width,
+                                     height,
+                                     periodX,
+                                     periodY,
+                                     bands);
+        }
+
+        public  void processPassComplete(BufferedImage theImage) {
+            super. processPassComplete(theImage);
+        }
+
+        public  void processPassStarted(BufferedImage theImage,
+                                        int pass, int minPass,
+                                        int maxPass,
+                                        int minX,
+                                        int minY,
+                                        int periodX,
+                                        int periodY,
+                                        int[] bands) {
+            super.processPassStarted(theImage,
+                                     pass,
+                                     minPass,
+                                     maxPass,
+                                     minX,
+                                     minY,
+                                     periodX,
+                                     periodY,
+                                     bands);
+        }
+
+        public  void processReadAborted() {
+            super.processReadAborted();
+        }
+
+        public  void processSequenceComplete() {
+            super.processSequenceComplete();
+        }
+
+        public  void processSequenceStarted(int minIndex) {
+            super.processSequenceStarted(minIndex);
+        }
+
+        public  void processThumbnailComplete() {
+            super.processThumbnailComplete();
+        }
+
+        public  void processThumbnailPassComplete(BufferedImage theThumbnail) {
+            super.processThumbnailPassComplete(theThumbnail);
+        }
+
+        public  void processThumbnailPassStarted(BufferedImage theThumbnail,
+                                                 int pass,
+                                                 int minPass,
+                                                 int maxPass,
+                                                 int minX,
+                                                 int minY,
+                                                 int periodX,
+                                                 int periodY,
+                                                 int[] bands) {
+            super.processThumbnailPassStarted(theThumbnail,
+                                              pass,
+                                              minPass,
+                                              maxPass,
+                                              minX,
+                                              minY,
+                                              periodX,
+                                              periodY,
+                                              bands);
+        }
+
+        public  void processThumbnailProgress(float percentageDone) {
+            super.processThumbnailProgress(percentageDone);
+        }
+
+        public  void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
+            super.processThumbnailStarted(imageIndex, thumbnailIndex);
+        }
+
+        public  void processThumbnailUpdate(BufferedImage theThumbnail,
+                                            int minX,
+                                            int minY,
+                                            int width,
+                                            int height,
+                                            int periodX,
+                                            int periodY,
+                                            int[] bands) {
+            super.processThumbnailUpdate(theThumbnail,
+                                         minX,
+                                         minY,
+                                         width,
+                                         height,
+                                         periodX,
+                                         periodY,
+                                         bands);
+        }
+
+        public  void processWarningOccurred(String warning) {
+            super.processWarningOccurred(warning);
+        }
+
+
+
+        public static Rectangle getSourceRegion(ImageReadParam param,
+                                                int srcWidth,
+                                                int srcHeight) {
+            return ImageReader.getSourceRegion(param, srcWidth, srcHeight);
+        }
+
+        public static void computeRegions(ImageReadParam param,
+                                          int srcWidth,
+                                          int srcHeight,
+                                          BufferedImage image,
+                                          Rectangle srcRegion,
+                                          Rectangle destRegion) {
+            ImageReader.computeRegions(param,
+                                       srcWidth,
+                                       srcHeight,
+                                       image,
+                                       srcRegion,
+                                       destRegion);
+        }
+
+        public static void checkReadParamBandSettings(ImageReadParam param,
+                                                      int numSrcBands,
+                                                      int numDstBands) {
+            ImageReader.checkReadParamBandSettings( param,
+                                                    numSrcBands,
+                                                    numDstBands);
+        }
+
+        public static BufferedImage getDestination(ImageReadParam param,
+                                                   Iterator imageTypes,
+                                                   int width,
+                                                   int height)
+          throws IIOException {
+            return ImageReader.getDestination(param,
+                                              imageTypes,
+                                              width,
+                                              height);
+        }
+
+        public  void setAvailableLocales(Locale[] locales) {
+            if (locales == null || locales.length == 0)
+                availableLocales = null;
+            else
+                availableLocales = (Locale[])locales.clone();
+        }
+
+        public  void processWarningOccurred(String baseName, String keyword) {
+            super.processWarningOccurred(baseName, keyword);
+        }
+    }
+
+    public static class DummyIIOMetadataFormatImpl
+        extends IIOMetadataFormatImpl {
+        public static String nativeMetadataFormatName =
+        "javax_imageio_dummy_1.0";
+
+        private static IIOMetadataFormat instance = null;
+
+
+        private DummyIIOMetadataFormatImpl() {
+            super(DummyIIOMetadataFormatImpl.nativeMetadataFormatName,
+                  CHILD_POLICY_SOME);
+        }
+
+        public boolean canNodeAppear(String elementName,
+                                     ImageTypeSpecifier imageType) {
+            return false;
+        }
+
+        public static synchronized IIOMetadataFormat getInstance() {
+            if (instance == null) {
+                instance = new DummyIIOMetadataFormatImpl();
+            }
+            return instance;
+        }
+    }
+
+    public static class DummyIIOMetadataImpl extends IIOMetadata {
+
+        public DummyIIOMetadataImpl() {
+            super();
+        }
+
+        public DummyIIOMetadataImpl(boolean standardMetadataFormatSupported,
+                                    String nativeMetadataFormatName,
+                                    String nativeMetadataFormatClassName,
+                                    String[] extraMetadataFormatNames,
+                                    String[] extraMetadataFormatClassNames) {
+            super(standardMetadataFormatSupported,
+                  nativeMetadataFormatName,
+                  nativeMetadataFormatClassName,
+                  extraMetadataFormatNames,
+                  extraMetadataFormatClassNames);
+        }
+
+        public boolean isReadOnly() {
+            return true;
+        }
+
+        public Node getAsTree(String formatName) {
+            return null;
+        }
+
+        public void mergeTree(String formatName, Node root)
+          throws IIOInvalidTreeException {
+            throw new IllegalStateException();
+        }
+
+        public void reset() {
+            throw new IllegalStateException();
+        }
+    }
+
+    public static class DummyImageReaderSpiImpl extends ImageReaderSpi {
+
+        static final String[] names ={ "myformat" };
+
+        public DummyImageReaderSpiImpl() {
+            super("vendorName",
+                  "version",
+                  names,
+                  null,
+                  null,
+                  "DummyImageReaderImpl",
+                  STANDARD_INPUT_TYPE,
+                  null,
+                  true,
+                  null,
+                  null,
+                  null,
+                  null,
+                  true,
+                  null,
+                  null,
+                  null,
+                  null);
+        }
+        public boolean canDecodeInput(Object source)
+          throws IOException {
+            return true;
+        }
+        public ImageReader createReaderInstance(Object extension)
+          throws IOException {
+            return new DummyImageReaderImpl(this);
+        }
+        public String getDescription(Locale locale) {
+            return "DummyImageReaderSpiImpl";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,228 @@
+#!/bin/ksh -p
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+#   @test
+#   @bug        4929170 7078379
+#   @summary    Tests that user-supplied IIOMetadata implementations
+#               loaded by separate classloader is able to load correspnding 
+#               IIOMetadataFormat implementations.
+#   @author     Andrew Brygin
+#
+#   @compile    UserPluginMetadataFormatTest.java MetadataFormatTest.java MetadataTest.java
+#   @run shell/timeout=60 runMetadataFormatTest.sh
+
+# Note!!!! JavaCodeForYourTest_CHANGE_THIS.java must be changed or deleted.  
+# If there is any java code which will be executed during the test, it must 
+# be compiled by the line above.  If multiple .java files, separate the 
+# files by spaces on that line.  See testing page of AWT home page for
+# pointers to the testharness spec. and FAQ.
+# Note!!!! Change AppletDeadlock.sh to the name of your test!!!!
+
+# There are several resources which need to be present before many 
+#  shell scripts can run.  Following are examples of how to check for
+#  many common ones.
+# 
+# Note that the shell used is the Korn Shell, KSH
+#
+# Also note, it is recommended that make files NOT be used.  Rather,
+#  put the individual commands directly into this file.  That way,
+#  it is possible to use command line arguments and other shell tech-
+#  niques to find the compiler, etc on different systems.  For example,
+#  a different path could be used depending on whether this were a
+#  Solaris or Win32 machine, which is more difficult (if even possible)
+#  in a make file.  
+
+
+# Beginning of subroutines:
+status=1
+
+#Call this from anywhere to fail the test with an error message
+# usage: fail "reason why the test failed"
+fail() 
+ { echo "The test failed :-("
+   echo "$*" 1>&2
+   exit 1
+ } #end of fail()
+
+#Call this from anywhere to pass the test with a message
+# usage: pass "reason why the test passed if applicable"
+pass() 
+ { echo "The test passed!!!"
+   echo "$*" 1>&2
+   exit 0
+ } #end of pass()
+
+# end of subroutines
+
+
+# The beginning of the script proper
+
+# Checking for proper OS
+OS=`uname -s`
+case "$OS" in
+   SunOS )
+      VAR="One value for Sun"
+      DEFAULT_JDK=/none
+      #DEFAULT_JDK=/usr/local/java/jdk1.2/solaris
+      FILESEP="/"
+      ;;
+
+   Linux | Darwin  )
+      VAR="A different value for Linux"
+      DEFAULT_JDK=/none
+      #DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
+      FILESEP="/"
+      ;;
+
+   Windows_95 | Windows_98 | Windows_NT | Windows_ME )
+      VAR="A different value for Win32"
+      DEFAULT_JDK=/none
+      #DEFAULT_JDK=/usr/local/java/jdk1.2/win32
+      FILESEP="\\"
+      ;;
+
+    CYGWIN* )
+      VAR="A different value for CYGWIN"
+      DEFAULT_JDK=/none
+      FILESEP="/"
+      ;;
+
+   # catch all other OSs
+   * )
+      echo "Unrecognized system!  $OS"
+      fail "Unrecognized system!  $OS"
+      ;;
+esac
+
+# check that some executable or other file you need is available, abort if not
+#  note that the name of the executable is in the fail string as well.
+# this is how to check for presence of the compiler, etc.
+#RESOURCE=`whence SomeProgramOrFileNeeded`
+#if [ "${RESOURCE}" = "" ] ; 
+#   then fail "Need SomeProgramOrFileNeeded to perform the test" ; 
+#fi
+
+# IT'S FINE TO DELETE THIS IF NOT NEEDED!
+# check if an environment variable you need is set, give it a default if not
+#if [ -z "${NEEDED_VAR}" ] ; then
+#   # The var is NOT set, so give it a default
+#   NEEDED_VAR=/some/default/value/such/as/a/path
+#fi
+
+# IT'S FINE TO DELETE THIS IF NOT NEEDED!
+#if [ -z "${NEEDED_LATER_VAR}" ] ; then
+#   # The var is NOT set, so give it a default
+#   # will need it in other scripts called from this one, so export it
+#   NEEDED_LATER_VAR="/a/different/path/note/the/quotes"
+#   export NEEDED_LATER_VAR
+#fi
+
+# Want this test to run standalone as well as in the harness, so do the 
+#  following to copy the test's directory into the harness's scratch directory 
+#  and set all appropriate variables:
+
+if [ -z "${TESTJAVA}" ] ; then
+   # TESTJAVA is not set, so the test is running stand-alone.
+   # TESTJAVA holds the path to the root directory of the build of the JDK
+   # to be tested.  That is, any java files run explicitly in this shell
+   # should use TESTJAVA in the path to the java interpreter.
+   # So, we'll set this to the JDK spec'd on the command line.  If none
+   # is given on the command line, tell the user that and use a cheesy
+   # default.
+   # THIS IS THE JDK BEING TESTED.
+   if [ -n "$1" ] ;
+      then TESTJAVA=$1
+      else echo "no JDK specified on command line so using default!"
+	 TESTJAVA=$DEFAULT_JDK
+   fi
+   TESTSRC=.
+   TESTCLASSES=.
+   STANDALONE=1;
+fi
+echo "JDK under test is: $TESTJAVA"
+
+#Deal with .class files:
+if [ -n "${STANDALONE}" ] ; 
+   then 
+   #if standalone, remind user to cd to dir. containing test before running it
+   echo "Just a reminder: cd to the dir containing this test when running it"
+   # then compile all .java files (if there are any) into .class files
+   if [ -a *.java ] ; 
+      then echo "Reminder, this test should be in its own directory with all"
+      echo "supporting files it needs in the directory with it."
+      ${TESTJAVA}/bin/javac ./*.java ; 
+   fi
+   # else in harness so copy all the class files from where jtreg put them
+   # over to the scratch directory this test is running in. 
+   else cp ${TESTCLASSES}/*.class . ;
+fi
+
+#if in test harness, then copy the entire directory that the test is in over 
+# to the scratch directory.  This catches any support files needed by the test.
+
+#if [ -z "${STANDALONE}" ] ; 
+#   then cp ${TESTSRC}/* . 
+#fi
+
+#Just before executing anything, make sure it has executable permission!
+chmod 777 ./*
+
+###############  YOUR TEST CODE HERE!!!!!!!  #############
+
+#All files required for the test should be in the same directory with
+# this file.  If converting a standalone test to run with the harness,
+# as long as all files are in the same directory and it returns 0 for
+# pass, you should be able to cut and paste it into here and it will
+# run with the test harness.
+
+# This is an example of running something -- test
+# The stuff below catches the exit status of test then passes or fails
+# this shell test as appropriate ( 0 status is considered a pass here )
+#./test # DELETE THIS LINE AND REPLACE WITH YOUR OWN COMMAND!!!
+
+if [ -d ./test_classes ] ; then 
+    rm -rf ./test_calsses
+fi
+
+mkdir ./test_classes
+ 
+# split application classes and test plugin classes
+mv ./UserPluginMetadataFormatTest*.class ./test_classes
+
+$TESTJAVA/bin/java MetadataFormatTest test_classes UserPluginMetadataFormatTest
+
+###############  END YOUR TEST CODE !!!!! ############
+status=$?
+
+# pass or fail the test based on status of the command
+if [ $status -eq "0" ];
+   then pass "Test passed - no stack trace printing"
+
+   else fail "Test failure - stack trace was printed"
+fi
+
+#For additional examples of how to write platform independent KSH scripts,
+# see the jtreg file itself.  It is a KSH script for both Solaris and Win32
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,229 @@
+#!/bin/ksh -p
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+#   @test
+#   @bug        4929170 7078379
+#   @summary    Tests that user-supplied IIOMetadata implementations 
+#                loaded by separate classloader in separate thread  
+#                is able to load correspnding IIOMetadataFormat 
+#                implementations.
+#   @author     Andrew Brygin
+#
+#   @compile    UserPluginMetadataFormatTest.java MetadataFormatThreadTest.java MetadataTest.java
+#   @run shell/timeout=60 runMetadataFormatThreadTest.sh
+
+# Note!!!! JavaCodeForYourTest_CHANGE_THIS.java must be changed or deleted.  
+# If there is any java code which will be executed during the test, it must 
+# be compiled by the line above.  If multiple .java files, separate the 
+# files by spaces on that line.  See testing page of AWT home page for
+# pointers to the testharness spec. and FAQ.
+# Note!!!! Change AppletDeadlock.sh to the name of your test!!!!
+
+# There are several resources which need to be present before many 
+#  shell scripts can run.  Following are examples of how to check for
+#  many common ones.
+# 
+# Note that the shell used is the Korn Shell, KSH
+#
+# Also note, it is recommended that make files NOT be used.  Rather,
+#  put the individual commands directly into this file.  That way,
+#  it is possible to use command line arguments and other shell tech-
+#  niques to find the compiler, etc on different systems.  For example,
+#  a different path could be used depending on whether this were a
+#  Solaris or Win32 machine, which is more difficult (if even possible)
+#  in a make file.  
+
+
+# Beginning of subroutines:
+status=1
+
+#Call this from anywhere to fail the test with an error message
+# usage: fail "reason why the test failed"
+fail() 
+ { echo "The test failed :-("
+   echo "$*" 1>&2
+   exit 1
+ } #end of fail()
+
+#Call this from anywhere to pass the test with a message
+# usage: pass "reason why the test passed if applicable"
+pass() 
+ { echo "The test passed!!!"
+   echo "$*" 1>&2
+   exit 0
+ } #end of pass()
+
+# end of subroutines
+
+
+# The beginning of the script proper
+
+# Checking for proper OS
+OS=`uname -s`
+case "$OS" in
+   SunOS )
+      VAR="One value for Sun"
+      DEFAULT_JDK=/none
+      #DEFAULT_JDK=/usr/local/java/jdk1.2/solaris
+      FILESEP="/"
+      ;;
+
+   Linux | Darwin )
+      VAR="A different value for Linux"
+      DEFAULT_JDK=/none
+      #DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
+      FILESEP="/"
+      ;;
+
+   Windows_95 | Windows_98 | Windows_NT | Windows_ME )
+      VAR="A different value for Win32"
+      DEFAULT_JDK=/none
+      #DEFAULT_JDK=/usr/local/java/jdk1.2/win32
+      FILESEP="\\"
+      ;;
+    
+    CYGWIN* )
+      VAR="A different value for CYGWIN"
+      DEFAULT_JDK=/none
+      FILESEP="/"
+      ;;
+
+   # catch all other OSs
+   * )
+      echo "Unrecognized system!  $OS"
+      fail "Unrecognized system!  $OS"
+      ;;
+esac
+
+# check that some executable or other file you need is available, abort if not
+#  note that the name of the executable is in the fail string as well.
+# this is how to check for presence of the compiler, etc.
+#RESOURCE=`whence SomeProgramOrFileNeeded`
+#if [ "${RESOURCE}" = "" ] ; 
+#   then fail "Need SomeProgramOrFileNeeded to perform the test" ; 
+#fi
+
+# IT'S FINE TO DELETE THIS IF NOT NEEDED!
+# check if an environment variable you need is set, give it a default if not
+#if [ -z "${NEEDED_VAR}" ] ; then
+#   # The var is NOT set, so give it a default
+#   NEEDED_VAR=/some/default/value/such/as/a/path
+#fi
+
+# IT'S FINE TO DELETE THIS IF NOT NEEDED!
+#if [ -z "${NEEDED_LATER_VAR}" ] ; then
+#   # The var is NOT set, so give it a default
+#   # will need it in other scripts called from this one, so export it
+#   NEEDED_LATER_VAR="/a/different/path/note/the/quotes"
+#   export NEEDED_LATER_VAR
+#fi
+
+# Want this test to run standalone as well as in the harness, so do the 
+#  following to copy the test's directory into the harness's scratch directory 
+#  and set all appropriate variables:
+
+if [ -z "${TESTJAVA}" ] ; then
+   # TESTJAVA is not set, so the test is running stand-alone.
+   # TESTJAVA holds the path to the root directory of the build of the JDK
+   # to be tested.  That is, any java files run explicitly in this shell
+   # should use TESTJAVA in the path to the java interpreter.
+   # So, we'll set this to the JDK spec'd on the command line.  If none
+   # is given on the command line, tell the user that and use a cheesy
+   # default.
+   # THIS IS THE JDK BEING TESTED.
+   if [ -n "$1" ] ;
+      then TESTJAVA=$1
+      else echo "no JDK specified on command line so using default!"
+	 TESTJAVA=$DEFAULT_JDK
+   fi
+   TESTSRC=.
+   TESTCLASSES=.
+   STANDALONE=1;
+fi
+echo "JDK under test is: $TESTJAVA"
+
+#Deal with .class files:
+if [ -n "${STANDALONE}" ] ; 
+   then 
+   #if standalone, remind user to cd to dir. containing test before running it
+   echo "Just a reminder: cd to the dir containing this test when running it"
+   # then compile all .java files (if there are any) into .class files
+   if [ -a *.java ] ; 
+      then echo "Reminder, this test should be in its own directory with all"
+      echo "supporting files it needs in the directory with it."
+      ${TESTJAVA}/bin/javac ./*.java ; 
+   fi
+   # else in harness so copy all the class files from where jtreg put them
+   # over to the scratch directory this test is running in. 
+   else cp ${TESTCLASSES}/*.class . ;
+fi
+
+#if in test harness, then copy the entire directory that the test is in over 
+# to the scratch directory.  This catches any support files needed by the test.
+
+#if [ -z "${STANDALONE}" ] ; 
+#   then cp ${TESTSRC}/* . 
+#fi
+
+#Just before executing anything, make sure it has executable permission!
+chmod 777 ./*
+
+###############  YOUR TEST CODE HERE!!!!!!!  #############
+
+#All files required for the test should be in the same directory with
+# this file.  If converting a standalone test to run with the harness,
+# as long as all files are in the same directory and it returns 0 for
+# pass, you should be able to cut and paste it into here and it will
+# run with the test harness.
+
+# This is an example of running something -- test
+# The stuff below catches the exit status of test then passes or fails
+# this shell test as appropriate ( 0 status is considered a pass here )
+#./test # DELETE THIS LINE AND REPLACE WITH YOUR OWN COMMAND!!!
+
+if [ -d ./test_classes ] ; then 
+    rm -rf ./test_calsses
+fi
+
+mkdir ./test_classes
+ 
+# split application classes and test plugin classes
+mv ./UserPluginMetadataFormatTest*.class ./test_classes
+
+$TESTJAVA/bin/java MetadataFormatThreadTest test_classes UserPluginMetadataFormatTest
+
+###############  END YOUR TEST CODE !!!!! ############
+status=$?
+
+# pass or fail the test based on status of the command
+if [ $status -eq "0" ];
+   then pass "Test passed - no stack trace printing"
+
+   else fail "Test failure - stack trace was printed"
+fi
+
+#For additional examples of how to write platform independent KSH scripts,
+# see the jtreg file itself.  It is a KSH script for both Solaris and Win32
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/IIOMetadataFormatImplTest.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4403350 4403352 4436995 4438977
+ * @run main IIOMetadataFormatImplTest
+ * @summary Tests various methods of IIOMetadataFormatImpl:
+ *
+ * getElement{Min,Max}Children and getAttribute{Min,Max}Value
+ * getAttributeDescription
+ * getAttributeEnumerations
+ */
+
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+
+public class IIOMetadataFormatImplTest {
+
+    public static void main(String[] args) {
+        test440335x();
+        test4436995();
+        test4438977();
+    }
+
+    static class IIOMetadataFormatImpl440335x extends IIOMetadataFormatImpl {
+
+        public IIOMetadataFormatImpl440335x() {
+            super("rootNode", 0, 1);
+            addElement("anElement", "rootNode", 20, 200);
+            addAttribute("anElement", "exclusiveAttr",
+                         IIOMetadataFormat.DATATYPE_INTEGER,
+                         true, null,
+                         "50", "500",
+                         false, false);
+            addAttribute("anElement", "minAttr",
+                         IIOMetadataFormat.DATATYPE_INTEGER,
+                         true, null,
+                         "60", "600",
+                         true, false);
+            addAttribute("anElement", "maxAttr",
+                         IIOMetadataFormat.DATATYPE_INTEGER,
+                         true, null,
+                         "70", "700",
+                         false, true);
+            addAttribute("anElement", "minMaxAttr",
+                         IIOMetadataFormat.DATATYPE_INTEGER,
+                         true, null,
+                         "80", "800",
+                         true, true);
+        }
+
+        public boolean canNodeAppear(String nodeName,
+                                     ImageTypeSpecifier imageType) {
+            return true;
+        }
+    }
+
+    private static void test440335x() {
+        IIOMetadataFormat format = new IIOMetadataFormatImpl440335x();
+
+        // Check that correct value is returned
+        if (format.getElementMinChildren("anElement") != 20) {
+            throw new RuntimeException("Error on getElementMinChildren!");
+        }
+        if (format.getElementMaxChildren("anElement") != 200) {
+            throw new RuntimeException("Error on getElementMaxChildren!");
+        }
+
+        // Check that correct value is returned and no exception is thrown
+        try {
+            if (!format.getAttributeMinValue("anElement",
+                                             "exclusiveAttr").equals("50")) {
+                throw new RuntimeException("Error on exclusiveAttr min!");
+            }
+            if (!format.getAttributeMaxValue("anElement",
+                                             "exclusiveAttr").equals("500")) {
+                throw new RuntimeException("Error on exclusiveAttr max!");
+            }
+            if (!format.getAttributeMinValue("anElement",
+                                             "minAttr").equals("60")) {
+                throw new RuntimeException("Error on minAttr min!");
+            }
+            if (!format.getAttributeMaxValue("anElement",
+                                             "minAttr").equals("600")) {
+                throw new RuntimeException("Error on minAttr max!");
+            }
+            if (!format.getAttributeMinValue("anElement",
+                                             "maxAttr").equals("70")) {
+                throw new RuntimeException("Error on maxAttr min!");
+            }
+            if (!format.getAttributeMaxValue("anElement",
+                                             "maxAttr").equals("700")) {
+                throw new RuntimeException("Error on maxAttr max!");
+            }
+            if (!format.getAttributeMinValue("anElement",
+                                             "minMaxAttr").equals("80")) {
+                throw new RuntimeException("Error on minMaxAttr min!");
+            }
+            if (!format.getAttributeMaxValue("anElement",
+                                             "minMaxAttr").equals("800")) {
+                throw new RuntimeException("Error on minMaxAttr max!");
+            }
+        } catch (IllegalStateException e) {
+            throw new RuntimeException("Got IllegalStateException!");
+        }
+    }
+
+    static class IIOMetadataFormatImpl4436995 extends IIOMetadataFormatImpl {
+
+        public IIOMetadataFormatImpl4436995(String root,
+                                            int minChildren, int maxChildren) {
+            super(root, minChildren, maxChildren);
+        }
+
+        public void addAttribute(String elementName,
+                                 String attrName,
+                                 int dataType,
+                                 boolean required,
+                                 int listMinLength, int listMaxLength) {
+            super.addAttribute(elementName,
+                               attrName,
+                               dataType,
+                               required, listMinLength,
+                               listMaxLength);
+        }
+
+        public boolean canNodeAppear(String elementName,
+                                     ImageTypeSpecifier imageType) {
+            return true;
+        }
+    }
+
+    private static void test4436995() {
+        String result;
+
+        IIOMetadataFormatImpl4436995 fmt =
+            new IIOMetadataFormatImpl4436995("root", 1, 10);
+        fmt.addAttribute("root", "attr", fmt.DATATYPE_INTEGER, true, 2, 5);
+        try {
+            result = fmt.getAttributeDescription("root", "non-existent", null);
+            throw new RuntimeException("Failed to get IAE!");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    static class IIOMetadataFormatImpl4438977 extends IIOMetadataFormatImpl {
+
+        public IIOMetadataFormatImpl4438977(String root,
+                                            int minChildren, int maxChildren) {
+            super(root, minChildren, maxChildren);
+        }
+
+        public void addAttribute(String elementName,
+                                 String attrName,
+                                 int dataType,
+                                 boolean required,
+                                 int listMinLength, int listMaxLength) {
+            super.addAttribute(elementName,
+                               attrName,
+                               dataType,
+                               required, listMinLength,
+                               listMaxLength);
+        }
+
+        public boolean canNodeAppear(String elementName,
+                                     ImageTypeSpecifier imageType) {
+            return true;
+        }
+    }
+
+    private static void test4438977() {
+        String[] result;
+
+        IIOMetadataFormatImpl4438977 fmt =
+            new IIOMetadataFormatImpl4438977("root", 1, 10);
+        fmt.addAttribute("root", "attr", fmt.DATATYPE_INTEGER, true, 2, 5);
+        try {
+            result = fmt.getAttributeEnumerations("root", "attr");
+            throw new RuntimeException("Failed to get IAE!");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/MetadataFormatPrinter.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import com.sun.imageio.plugins.png.PNGMetadata;
+
+public class MetadataFormatPrinter {
+
+    private int indentLevel = 0;
+
+    private int column = 0;
+
+    private PrintStream out;
+
+    private static final int maxColumn = 75;
+
+    private static String[] dataTypeNames = {
+        "String", "Boolean", "Integer", "Float", "Double"
+    };
+
+    // "Infinite" values
+    private static String maxInteger = Integer.toString(Integer.MAX_VALUE);
+
+    public MetadataFormatPrinter(PrintStream out) {
+        this.out = out;
+    }
+
+    private void println() {
+        out.println();
+        column = 0;
+    }
+
+    private void println(String s) {
+        out.println(s);
+        column = 0;
+    }
+
+    private void printWrapped(String in, int leftIndent) {
+        StringTokenizer t = new StringTokenizer(in);
+        while (t.hasMoreTokens()) {
+            String s = t.nextToken();
+            int length = s.length();
+            if (column + length > maxColumn) {
+                println();
+                indent();
+                for (int i = 0; i < leftIndent; i++) {
+                    print(" ");
+                }
+            }
+            out.print(s);
+            out.print(" ");
+            column += length + 1;
+        }
+    }
+
+    private void print(String s) {
+        int length = s.length();
+        if (column + length > maxColumn) {
+            println();
+            indent();
+            print("  ");
+        }
+        out.print(s);
+        column += length;
+    }
+
+    private void print(IIOMetadataFormat format) {
+        String rootName = format.getRootName();
+        println("<!DOCTYPE \"" +
+                           rootName +
+                           "\" [");
+        ++indentLevel;
+        print(format, rootName);
+        --indentLevel;
+        print("]>");
+        println();
+        println();
+    }
+
+    private void indent() {
+        for (int i = 0; i < indentLevel; i++) {
+            out.print("  ");
+            column += 2;
+        }
+    }
+
+    private void printElementInfo(IIOMetadataFormat format,
+                                  String elementName) {
+        println();
+        indent();
+        print("<!ELEMENT \"" +
+              elementName +
+              "\"");
+
+        String[] childNames = format.getChildNames(elementName);
+        boolean hasChildren = true;
+        String separator = " "; // symbol to place between children
+        String terminator = ""; // symbol to follow last child
+        String repeater = ""; // "*" if repeating
+
+        switch (format.getChildPolicy(elementName)) {
+        case IIOMetadataFormat.CHILD_POLICY_EMPTY:
+            hasChildren = false;
+            break;
+        case IIOMetadataFormat.CHILD_POLICY_ALL:
+            separator = ", ";
+            break;
+        case IIOMetadataFormat.CHILD_POLICY_SOME:
+            separator = "?, ";
+            terminator = "?";
+            break;
+        case IIOMetadataFormat.CHILD_POLICY_CHOICE:
+            separator = " | ";
+            break;
+        case IIOMetadataFormat.CHILD_POLICY_SEQUENCE:
+            separator = " | ";
+            repeater = "*";
+            break;
+        case IIOMetadataFormat.CHILD_POLICY_REPEAT:
+            repeater = "*";
+            break;
+        default:
+            break;
+        }
+
+        if (hasChildren) {
+            print(" (");
+            for (int i = 0; i < childNames.length - 1; i++) {
+                print(childNames[i] + separator);
+            }
+            print(childNames[childNames.length - 1] + terminator);
+            print(")" + repeater + ">");
+        } else {
+            print(" EMPTY>");
+        }
+        println();
+
+        String description = format.getElementDescription(elementName, null);
+        if (description != null) {
+            ++indentLevel;
+            indent();
+            printWrapped("<!-- " + description + " -->", 5);
+            println();
+            --indentLevel;
+        }
+        if (format.getChildPolicy(elementName) ==
+            IIOMetadataFormat.CHILD_POLICY_REPEAT) {
+            int minChildren = format.getElementMinChildren(elementName);
+            if (minChildren != 0) {
+                indent();
+                println("  <!-- Min children: " +
+                        minChildren +
+                        " -->");
+            }
+            int maxChildren = format.getElementMaxChildren(elementName);
+            if (maxChildren != Integer.MAX_VALUE) {
+                indent();
+                println("  <!-- Max children: " +
+                        maxChildren +
+                        " -->");
+            }
+        }
+    }
+
+    private void printAttributeInfo(IIOMetadataFormat format,
+                                    String elementName,
+                                    String attrName) {
+        indent();
+        print("<!ATTLIST \"" +
+              elementName +
+              "\" \"" +
+              attrName +
+              "\"");
+
+        int attrValueType =
+            format.getAttributeValueType(elementName, attrName);
+        switch (attrValueType) {
+        case IIOMetadataFormat.VALUE_NONE:
+            throw new RuntimeException
+                ("Encountered VALUE_NONE for an attribute!");
+            // break;
+        case IIOMetadataFormat.VALUE_ARBITRARY:
+            print(" #CDATA");
+            break;
+        case IIOMetadataFormat.VALUE_RANGE:
+        case IIOMetadataFormat.VALUE_RANGE_MIN_INCLUSIVE:
+        case IIOMetadataFormat.VALUE_RANGE_MAX_INCLUSIVE:
+        case IIOMetadataFormat.VALUE_RANGE_MIN_MAX_INCLUSIVE:
+            print(" #CDATA");
+            break;
+        case IIOMetadataFormat.VALUE_ENUMERATION:
+            print(" (");
+            String[] attrValues =
+                format.getAttributeEnumerations(elementName, attrName);
+            for (int j = 0; j < attrValues.length - 1; j++) {
+                print("\"" + attrValues[j] + "\" | ");
+            }
+            print("\"" + attrValues[attrValues.length - 1] + "\")");
+            break;
+        case IIOMetadataFormat.VALUE_LIST:
+            print(" #CDATA");
+            break;
+        default:
+            throw new RuntimeException
+                ("Encountered unknown value type for an attribute!");
+            // break;
+        }
+
+        String defaultValue =
+            format.getAttributeDefaultValue(elementName, attrName);
+        if (defaultValue != null) {
+            print(" ");
+            print("\"" + defaultValue + "\"");
+        } else {
+            if (format.isAttributeRequired(elementName, attrName)) {
+                print(" #REQUIRED");
+            } else {
+                print(" #IMPLIED");
+            }
+        }
+        println(">");
+
+        String description = format.getAttributeDescription(elementName,
+                                                            attrName,
+                                                            null);
+        if (description != null) {
+            ++indentLevel;
+            indent();
+            printWrapped("<!-- " + description + " -->", 5);
+            println();
+            --indentLevel;
+        }
+
+        int dataType = format.getAttributeDataType(elementName, attrName);
+
+        switch (attrValueType) {
+        case IIOMetadataFormat.VALUE_ARBITRARY:
+            indent();
+            println("  <!-- Data type: " + dataTypeNames[dataType] + " -->");
+            break;
+
+        case IIOMetadataFormat.VALUE_RANGE:
+        case IIOMetadataFormat.VALUE_RANGE_MIN_INCLUSIVE:
+        case IIOMetadataFormat.VALUE_RANGE_MAX_INCLUSIVE:
+        case IIOMetadataFormat.VALUE_RANGE_MIN_MAX_INCLUSIVE:
+            indent();
+            println("  <!-- Data type: " + dataTypeNames[dataType] + " -->");
+
+            boolean minInclusive =
+                (attrValueType &
+                 IIOMetadataFormat.VALUE_RANGE_MIN_INCLUSIVE_MASK) != 0;
+            boolean maxInclusive =
+                (attrValueType &
+                 IIOMetadataFormat.VALUE_RANGE_MAX_INCLUSIVE_MASK) != 0;
+            indent();
+            println("  <!-- Min value: " +
+                    format.getAttributeMinValue(elementName, attrName) +
+                    " " +
+                    (minInclusive ? "(inclusive)" : "(exclusive)") +
+                    " -->");
+            String maxValue =
+                format.getAttributeMaxValue(elementName, attrName);
+            // Hack: don't print "infinite" max values
+            if (dataType != IIOMetadataFormat.DATATYPE_INTEGER ||
+                !maxValue.equals(maxInteger)) {
+                indent();
+                println("  <!-- Max value: " +
+                        maxValue +
+                        " " +
+                        (maxInclusive ? "(inclusive)" : "(exclusive)") +
+                        " -->");
+            }
+            break;
+
+        case IIOMetadataFormat.VALUE_LIST:
+            indent();
+            println("  <!-- Data type: List of " + dataTypeNames[dataType] + " -->");
+
+            int minLength =
+                format.getAttributeListMinLength(elementName, attrName);
+            if (minLength != 0) {
+                indent();
+                println("  <!-- Min length: " +
+                        minLength +
+                        " -->");
+            }
+            int maxLength =
+                format.getAttributeListMaxLength(elementName, attrName);
+            if (maxLength != Integer.MAX_VALUE) {
+                indent();
+                println("  <!-- Max length: " +
+                        maxLength +
+                        " -->");
+            }
+            break;
+        }
+    }
+
+    private void printObjectInfo(IIOMetadataFormat format,
+                                 String elementName) {
+        int objectType = format.getObjectValueType(elementName);
+        if (objectType == IIOMetadataFormat.VALUE_NONE) {
+            return;
+        }
+
+        Class objectClass = format.getObjectClass(elementName);
+        if (objectClass != null) {
+            indent();
+            if (objectType == IIOMetadataFormat.VALUE_LIST) {
+                println("  <!-- User object: array of " +
+                        objectClass.getName() +
+                        " -->");
+            } else {
+                println("  <!-- User object: " +
+                        objectClass.getName() +
+                        " -->");
+            }
+
+            Object defaultValue = format.getObjectDefaultValue(elementName);
+            if (defaultValue != null) {
+                indent();
+                println("  <!-- Default value: " +
+                        defaultValue.toString() +
+                        " -->");
+            }
+
+            switch (objectType) {
+            case IIOMetadataFormat.VALUE_RANGE:
+                indent();
+                println("  <!-- Min value: " +
+                        format.getObjectMinValue(elementName).toString() +
+                        " -->");
+                indent();
+                println("  <!-- Max value: " +
+                        format.getObjectMaxValue(elementName).toString() +
+                        " -->");
+                break;
+
+            case IIOMetadataFormat.VALUE_ENUMERATION:
+                Object[] enums = format.getObjectEnumerations(elementName);
+                for (int i = 0; i < enums.length; i++) {
+                    indent();
+                    println("  <!-- Enumerated value: " +
+                            enums[i].toString() +
+                            " -->");
+                }
+                break;
+
+            case IIOMetadataFormat.VALUE_LIST:
+                int minLength = format.getObjectArrayMinLength(elementName);
+                if (minLength != 0) {
+                    indent();
+                    println("  <!-- Min length: " +
+                            minLength +
+                            " -->");
+                }
+                int maxLength = format.getObjectArrayMaxLength(elementName);
+                if (maxLength != Integer.MAX_VALUE) {
+                    indent();
+                    println("  <!-- Max length: " +
+                            maxLength +
+                            " -->");
+                }
+                break;
+            }
+        }
+    }
+
+    // Set of elements that have been printed already
+    Set printedElements = new HashSet();
+
+    // Set of elements that have been scheduled to be printed
+    Set scheduledElements = new HashSet();
+
+    private void print(IIOMetadataFormat format,
+                       String elementName) {
+        // Don't print elements more than once
+        if (printedElements.contains(elementName)) {
+            return;
+        }
+        printedElements.add(elementName);
+
+        // Add the unscheduled children of this node to a list,
+        // and mark them as scheduled
+        List children = new ArrayList();
+        String[] childNames = format.getChildNames(elementName);
+        if (childNames != null) {
+            for (int i = 0; i < childNames.length; i++) {
+                String childName = childNames[i];
+                if (!scheduledElements.contains(childName)) {
+                    children.add(childName);
+                    scheduledElements.add(childName);
+                }
+            }
+        }
+
+        printElementInfo(format, elementName);
+        printObjectInfo(format, elementName);
+
+        ++indentLevel;
+        String[] attrNames = format.getAttributeNames(elementName);
+        for (int i = 0; i < attrNames.length; i++) {
+            printAttributeInfo(format, elementName, attrNames[i]);
+        }
+
+        // Recurse on child nodes
+        Iterator iter = children.iterator();
+        while (iter.hasNext()) {
+            print(format, (String)iter.next());
+        }
+        --indentLevel;
+    }
+
+    public static void main(String[] args) {
+        IIOMetadataFormat format = null;
+        if (args.length == 0 || args[0].equals("javax_imageio_1.0")) {
+            format = IIOMetadataFormatImpl.getStandardFormatInstance();
+        } else {
+            IIORegistry registry = IIORegistry.getDefaultInstance();
+            Iterator iter = registry.getServiceProviders(ImageReaderSpi.class,
+                                                         false);
+            while (iter.hasNext()) {
+                ImageReaderSpi spi = (ImageReaderSpi)iter.next();
+                if (args[0].equals
+                    (spi.getNativeStreamMetadataFormatName())) {
+                    System.out.print(spi.getDescription(null));
+                    System.out.println(": native stream format");
+                    format = spi.getStreamMetadataFormat(args[0]);
+                    break;
+                }
+
+                String[] extraStreamFormatNames =
+                    spi.getExtraStreamMetadataFormatNames();
+                if (extraStreamFormatNames != null &&
+                    Arrays.asList(extraStreamFormatNames).
+                    contains(args[0])) {
+                    System.out.print(spi.getDescription(null));
+                    System.out.println(": extra stream format");
+                    format = spi.getStreamMetadataFormat(args[0]);
+                    break;
+                }
+
+                if (args[0].equals
+                    (spi.getNativeImageMetadataFormatName())) {
+                    System.out.print(spi.getDescription(null));
+                    System.out.println(": native image format");
+                    format = spi.getImageMetadataFormat(args[0]);
+                    break;
+                }
+
+                String[] extraImageFormatNames =
+                    spi.getExtraImageMetadataFormatNames();
+                if (extraImageFormatNames != null &&
+                    Arrays.asList(extraImageFormatNames).contains(args[0])) {
+                    System.out.print(spi.getDescription(null));
+                    System.out.println(": extra image format");
+                    format = spi.getImageMetadataFormat(args[0]);
+                    break;
+                }
+            }
+        }
+
+        if (format == null) {
+            System.err.println("Unknown format: " + args[0]);
+            System.exit(0);
+        }
+
+        MetadataFormatPrinter printer = new MetadataFormatPrinter(System.out);
+        printer.print(format);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/ObjectArrayMaxLength.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4406353
+ * @run main ObjectArrayMaxLength
+ * @summary Tests the getObjectArrayMaxLength method of
+ * IIOMetadataFormatImpl
+ */
+
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+
+class MyIIOMetadataFormatImpl extends IIOMetadataFormatImpl {
+
+    MyIIOMetadataFormatImpl() {
+        super("root", CHILD_POLICY_EMPTY);
+        addObjectValue("root", byte.class, 123, 321);
+    }
+
+    public boolean canNodeAppear(String nodeName, ImageTypeSpecifier type) {
+        return true;
+    }
+}
+
+public class ObjectArrayMaxLength {
+
+    public static void main(String[] args) {
+        IIOMetadataFormat f = new MyIIOMetadataFormatImpl();
+        if (f.getObjectArrayMaxLength("root") != 321) {
+            throw new RuntimeException
+                ("Bad value for getObjectArrayMaxLength!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/RegisteredFormatsTest.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      5017991
+ * @summary  This test verifies two things:
+ *            a) we can get MetadataFormat classes for
+ *                each registered metadata format.
+ *            b) all metadata formats for standard plugins
+ *                are registered.
+ * @run main RegisteredFormatsTest
+ */
+
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.metadata.IIOMetadataFormat;
+import java.util.Iterator;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+public class RegisteredFormatsTest {
+
+    private static Hashtable fmts;
+
+    public static void main(String[] args) {
+        fmts = new Hashtable();
+
+        fmts.put("javax_imageio_jpeg_stream_1.0", Boolean.FALSE);
+        fmts.put("javax_imageio_jpeg_image_1.0",  Boolean.FALSE);
+        fmts.put("javax_imageio_png_1.0",         Boolean.FALSE);
+        fmts.put("javax_imageio_bmp_1.0",         Boolean.FALSE);
+        fmts.put("javax_imageio_wbmp_1.0",        Boolean.FALSE);
+        fmts.put("javax_imageio_gif_stream_1.0",  Boolean.FALSE);
+        fmts.put("javax_imageio_gif_image_1.0",   Boolean.FALSE);
+
+        IIORegistry registry = IIORegistry.getDefaultInstance();
+        Iterator iter = registry.getServiceProviders(ImageReaderSpi.class,
+                                                     false);
+        while(iter.hasNext()) {
+            ImageReaderSpi spi = (ImageReaderSpi)iter.next();
+            String fmt_name;
+            fmt_name = spi.getNativeStreamMetadataFormatName();
+            testStreamMetadataFormat(spi, fmt_name);
+
+            fmt_name = spi.getNativeImageMetadataFormatName();
+            testImageMetadataFormat(spi, fmt_name);
+
+            String[] fmt_names;
+            fmt_names = spi.getExtraStreamMetadataFormatNames();
+            for (int i=0; fmt_names != null && i < fmt_names.length; i++) {
+                testStreamMetadataFormat(spi, fmt_names[i]);
+            }
+
+            fmt_names = spi.getExtraImageMetadataFormatNames();
+            for (int i=0; fmt_names != null && i < fmt_names.length; i++) {
+                testImageMetadataFormat(spi, fmt_names[i]);
+            }
+        }
+        Enumeration keys = fmts.keys();
+        while (keys.hasMoreElements()) {
+            String key = (String)keys.nextElement();
+            boolean val = ((Boolean)fmts.get(key)).booleanValue();
+            if (!val) {
+                throw new RuntimeException("Test failed: format " +
+                                           key + "is not registered.");
+            }
+        }
+    }
+
+    private static void testStreamMetadataFormat(ImageReaderSpi spi,
+                                                 String fmt_name) {
+        if (fmt_name == null) {
+            return;
+        }
+        try {
+            testMetadataFormat(spi.getStreamMetadataFormat(fmt_name),
+                               fmt_name);
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed for " + fmt_name,
+                                       e);
+        }
+    }
+
+    private static void testImageMetadataFormat(ImageReaderSpi spi,
+                                                String fmt_name) {
+        if (fmt_name == null) {
+            return;
+        }
+        try {
+            testMetadataFormat(spi.getImageMetadataFormat(fmt_name),
+                               fmt_name);
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed for " + fmt_name,
+                                       e);
+        }
+    }
+    private static void testMetadataFormat(IIOMetadataFormat fmt,
+                                           String fmt_name) {
+        System.out.print(fmt_name + "...");
+        if (fmt != null) {
+            fmts.put(fmt_name, Boolean.TRUE);
+            System.out.println("Ok");
+        } else {
+            throw new RuntimeException("Test failed for " + fmt_name);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/RemoveElement.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4432628 7186799
+ * @run main RemoveElement
+ * @summary Checks if ImageMetadataFormatImpl.removeElement properly
+ * removes the element from its parent's child list.
+ */
+
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.ImageTypeSpecifier;
+
+public class RemoveElement {
+
+    public static void main(String[] args) {
+        String elem = "elem2";
+        int policy = IIOMetadataFormat.CHILD_POLICY_SOME;
+        MyFormatImpl fmt = new MyFormatImpl("root", 1, 10);
+        fmt.addElement("elem1", "root", policy);
+        fmt.addElement(elem, "root", policy);
+        fmt.removeElement("elem1");
+
+        boolean gotIAE = false;
+        try {
+            fmt.getChildPolicy("elem1");
+        } catch (IllegalArgumentException e) {
+            gotIAE = true;
+        }
+        if (!gotIAE) {
+            throw new RuntimeException("Element is still present!");
+        }
+        String[] chNames = fmt.getChildNames("root");
+        if (chNames.length != 1) {
+            throw new RuntimeException("Root still has more than 1 child!");
+        }
+        if (!elem.equals(chNames[0])) {
+            throw new RuntimeException("Root's remaining child is incorrect!");
+        }
+    }
+
+    static class MyFormatImpl extends IIOMetadataFormatImpl {
+
+        MyFormatImpl(String root, int minChildren, int maxChildren) {
+            super(root, minChildren, maxChildren);
+        }
+
+        public void addElement(String elementName,
+                               String parentName,
+                               int childPolicy) {
+            super.addElement(elementName, parentName, childPolicy);
+        }
+
+        public void removeElement(String elementName) {
+            super.removeElement(elementName);
+        }
+
+        public boolean canNodeAppear(String elementName,
+                                     ImageTypeSpecifier imageType) {
+            return true;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/metadata/SetAttributeNode.java	Mon Sep 17 13:44:07 2012 +0400
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4507256
+ * @run main SetAttributeNode
+ * @summary Tests the functionality of IIOMetadataNode.setAttributeNode().
+ * Four separate tests are involved:
+ *   1) Tests whether a DOMException.INUSE_ATTRIBUTE_ERR is thrown if newAttr
+ *      is already an attribute of another Element object.
+ *   2) Tests whether setAttributeNode() returns the old attribute if it is
+ *      replaced.
+ *   3) Tests whether setAttributeNode() returns null if the new attribute is
+ *      not replacing an existing attribute.
+ *   4) Tests whether the new attribute successfully replaces an existing one.
+ */
+
+import javax.imageio.metadata.IIOMetadataNode;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.TypeInfo;
+
+public class SetAttributeNode {
+
+    public static void test1() {
+        IIOMetadataNode parent = new IIOMetadataNode("parent");
+        IIOMetadataNode elem   = new IIOMetadataNode("elem");
+
+        MyAttrNode attrNode = new MyAttrNode("name", "value");
+        elem.setAttributeNode(attrNode);
+        attrNode.setOwnerElement(elem);
+
+        try {
+            parent.setAttributeNode(attrNode);
+        } catch (DOMException e) {
+            if (e.code != DOMException.INUSE_ATTRIBUTE_ERR) {
+                throw new RuntimeException("Test 1 failed: " +
+                                           "Invalid exception code: " +
+                                           e.code);
+            }
+            return;
+        }
+
+        throw new RuntimeException("Test 1 failed: DOMException not thrown");
+    }
+
+    public static void test2() {
+        String name = "attr";
+        String oldValue = "old value";
+        String newValue = "new value";
+        Attr retAttr;
+
+        IIOMetadataNode parent = new IIOMetadataNode("parent");
+        MyAttrNode attrNode1 = new MyAttrNode(name, oldValue);
+        MyAttrNode attrNode2 = new MyAttrNode(name, newValue);
+
+        retAttr = parent.setAttributeNode(attrNode1);
+        retAttr = parent.setAttributeNode(attrNode2);
+
+        String actName = retAttr.getNodeName();
+        String actValue = retAttr.getValue();
+
+        if (!actName.equals(name) || !actValue.equals(oldValue)) {
+            throw new RuntimeException("Test 2 failed: Invalid attribute " +
+                                       "returned: " +
+                                       "(name: " + actName +
+                                       ", value: " + actValue + ")");
+        }
+    }
+
+    public static void test3() {
+        IIOMetadataNode parent = new IIOMetadataNode("parent");
+        MyAttrNode attrNode = new MyAttrNode("name", "value");
+        Attr retAttr = parent.setAttributeNode(attrNode);
+
+        if (retAttr != null) {
+            throw new RuntimeException("Test 3 failed: Return value is " +
+                                       "non-null");
+        }
+    }
+
+    public static void test4() {
+        String name = "name";
+        String correctValue = "correct value";
+        String wrongValue = "wrong value";
+
+        IIOMetadataNode parent = new IIOMetadataNode("parent");
+        MyAttrNode attrNode1 = new MyAttrNode(name, wrongValue);
+        MyAttrNode attrNode2 = new MyAttrNode(name, correctValue);
+
+        parent.setAttributeNode(attrNode1);
+        parent.setAttributeNode(attrNode2);
+
+        Attr actAttr = parent.getAttributeNode(name);
+        String actValue = actAttr.getValue();
+
+        if (!actValue.equals(correctValue)) {
+            throw new RuntimeException("Test 4 failed: Return value is: " +
+                                       actValue);
+        }
+    }
+
+    public static void main(String[] args) {
+        test1();
+        test2();
+        test3();
+        test4();
+    }
+}
+
+class MyAttrNode extends IIOMetadataNode implements Attr {
+
+    private Element owner;
+    private String name;
+    private String value;
+
+    public MyAttrNode(String name, String value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public Element getOwnerElement() {
+        return owner;
+    }
+
+    public void setOwnerElement(Element owner) {
+        this.owner = owner;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public boolean getSpecified() {
+        return false;
+    }
+
+    public TypeInfo getSchemaTypeInfo() {
+        return null;
+    }
+
+    public boolean isId() {
+        return false;
+    }
+}