1 /*
2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug     4929170
27  * @summary Tests that user-supplied IIOMetadata implementations loaded by
28  *           system class loader (i.e. corresponding classes are available via
29  *           classpath) is able to load correspnding IIOMetadataFormat
30  *           implementations.
31  * @run     main UserPluginMetadataFormatTest
32  */
33 
34 import java.awt.Rectangle;
35 import java.awt.image.BufferedImage;
36 import java.io.IOException;
37 import java.io.ByteArrayInputStream;
38 import java.util.Iterator;
39 import java.util.ListResourceBundle;
40 import java.util.Locale;
41 import java.util.MissingResourceException;
42 import java.util.Vector;
43 import javax.imageio.ImageIO;
44 import javax.imageio.ImageReader;
45 import javax.imageio.ImageReadParam;
46 import javax.imageio.IIOException;
47 import javax.imageio.ImageTypeSpecifier;
48 import javax.imageio.event.IIOReadWarningListener;
49 import javax.imageio.metadata.IIOMetadata;
50 import javax.imageio.metadata.IIOMetadataFormat;
51 import javax.imageio.metadata.IIOMetadataFormatImpl;
52 import javax.imageio.metadata.IIOInvalidTreeException;
53 import javax.imageio.spi.ImageReaderSpi;
54 import org.w3c.dom.Node;
55 
56 public class UserPluginMetadataFormatTest implements MetadataTest {
57 
main(String[] argv)58     public static void main(String[] argv) throws IOException {
59         new UserPluginMetadataFormatTest().doTest();
60     }
61 
doTest()62     public void doTest() throws IOException {
63 
64         DummyImageReaderImpl reader;
65 
66         reader = new DummyImageReaderImpl(new DummyImageReaderSpiImpl());
67 
68         byte[] data = new byte[1024];
69         ByteArrayInputStream bais =
70             new ByteArrayInputStream(data);
71 
72         reader.setInput(ImageIO.createImageInputStream(bais));
73         IIOMetadata metadata = reader.getImageMetadata(1);
74         if(metadata == null) {
75             throw new RuntimeException("IIOMetada is NULL");
76         }
77 
78         String[] formatNames = metadata.getMetadataFormatNames();
79 
80         for(int j=0; j<formatNames.length; j++) {
81 
82             String formatName = formatNames[j];
83             System.out.println("\nFormat Names : " + formatName);
84 
85             try {
86                 IIOMetadataFormat metadataFormat =
87                     metadata.getMetadataFormat(formatName);
88                 System.out.println("  Class Name " +
89                                    metadataFormat.getClass());
90             } catch(IllegalStateException ise) {
91                 Throwable t = ise;
92                 t.printStackTrace();
93                 while(t.getCause() != null) {
94                     t = t.getCause();
95                     t.printStackTrace();
96                 }
97                 // test failed!
98                 // stop applet!
99                 System.out.println("Test faied.");
100                 throw new RuntimeException("Test failed.", ise);
101             }
102         }
103     }
104 
105     public static class DummyImageReaderImpl extends ImageReader {
106 
DummyImageReaderImpl(ImageReaderSpi originatingProvider)107         public DummyImageReaderImpl(ImageReaderSpi originatingProvider) {
108             super(originatingProvider);
109         }
110 
getNumImages(boolean allowSearch)111         public int getNumImages(boolean allowSearch) throws IOException {
112             return 5;
113         }
114 
getWidth(int imageIndex)115         public int getWidth(int imageIndex) throws IOException {
116             if (input == null)
117                 throw new IllegalStateException();
118             if (imageIndex >= 5 || imageIndex < 0)
119                 throw new IndexOutOfBoundsException();
120 
121             return 10;
122         }
123 
getHeight(int imageIndex)124         public int getHeight(int imageIndex) throws IOException {
125             if (input == null)
126                 throw new IllegalStateException();
127             if (imageIndex >= 5 || imageIndex < 0)
128                 throw new IndexOutOfBoundsException();
129 
130             return 15;
131         }
132 
getImageTypes(int imageIndex)133         public Iterator getImageTypes(int imageIndex) throws IOException {
134             if (input == null)
135                 throw new IllegalStateException();
136             if (imageIndex >= 5 || imageIndex < 0)
137                 throw new IndexOutOfBoundsException();
138 
139             Vector imageTypes = new Vector();
140             imageTypes.add(ImageTypeSpecifier.createFromBufferedImageType
141                            (BufferedImage.TYPE_BYTE_GRAY ));
142             return imageTypes.iterator();
143         }
144 
getStreamMetadata()145         public IIOMetadata getStreamMetadata() throws IOException {
146             return new DummyIIOMetadataImpl(true, null, null, null, null);
147         }
148 
getImageMetadata(int imageIndex)149         public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
150 
151             if (input == null)
152                 throw new IllegalStateException();
153             if (imageIndex >= 5 || imageIndex < 0)
154                 throw new IndexOutOfBoundsException();
155             if (seekForwardOnly) {
156                 if (imageIndex < minIndex)
157                     throw new IndexOutOfBoundsException();
158                 minIndex = imageIndex;
159             }
160             System.out.println("Current format class name " + DummyIIOMetadataFormatImpl.class.getName());
161             return new DummyIIOMetadataImpl(true,
162                                             DummyIIOMetadataFormatImpl.nativeMetadataFormatName,
163                                             DummyIIOMetadataFormatImpl.class.getName(),
164                                             null, null);
165         }
166 
167 
read(int imageIndex, ImageReadParam param)168         public BufferedImage read(int imageIndex, ImageReadParam param)
169           throws IOException {
170             if (input == null)
171                 throw new IllegalStateException();
172             if (imageIndex >= 5 || imageIndex < 0)
173                 throw new IndexOutOfBoundsException();
174             if (seekForwardOnly) {
175                 if (imageIndex < minIndex)
176                     throw new IndexOutOfBoundsException();
177                 minIndex = imageIndex;
178             }
179 
180             return getDestination(param, getImageTypes(imageIndex), 10, 15);
181         }
182 
183         // protected  methods - now public
184 
abortRequested()185         public  boolean abortRequested() {
186             return super.abortRequested();
187         }
188 
clearAbortRequest()189         public  void clearAbortRequest() {
190             super.clearAbortRequest();
191         }
192 
processImageComplete()193         public  void processImageComplete() {
194             super.processImageComplete();
195         }
196 
processImageProgress(float percentageDone)197         public  void processImageProgress(float percentageDone) {
198             super.processImageProgress(percentageDone);
199         }
200 
processImageStarted(int imageIndex)201         public  void processImageStarted(int imageIndex) {
202             super.processImageStarted(imageIndex);
203         }
204 
processImageUpdate(BufferedImage theImage, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands)205         public  void processImageUpdate(BufferedImage theImage,
206                                         int minX,
207                                         int minY,
208                                         int width,
209                                         int height,
210                                         int periodX,
211                                         int periodY,
212                                         int[] bands) {
213             super.processImageUpdate(theImage,
214                                      minX,
215                                      minY,
216                                      width,
217                                      height,
218                                      periodX,
219                                      periodY,
220                                      bands);
221         }
222 
processPassComplete(BufferedImage theImage)223         public  void processPassComplete(BufferedImage theImage) {
224             super. processPassComplete(theImage);
225         }
226 
processPassStarted(BufferedImage theImage, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands)227         public  void processPassStarted(BufferedImage theImage,
228                                         int pass, int minPass,
229                                         int maxPass,
230                                         int minX,
231                                         int minY,
232                                         int periodX,
233                                         int periodY,
234                                         int[] bands) {
235             super.processPassStarted(theImage,
236                                      pass,
237                                      minPass,
238                                      maxPass,
239                                      minX,
240                                      minY,
241                                      periodX,
242                                      periodY,
243                                      bands);
244         }
245 
processReadAborted()246         public  void processReadAborted() {
247             super.processReadAborted();
248         }
249 
processSequenceComplete()250         public  void processSequenceComplete() {
251             super.processSequenceComplete();
252         }
253 
processSequenceStarted(int minIndex)254         public  void processSequenceStarted(int minIndex) {
255             super.processSequenceStarted(minIndex);
256         }
257 
processThumbnailComplete()258         public  void processThumbnailComplete() {
259             super.processThumbnailComplete();
260         }
261 
processThumbnailPassComplete(BufferedImage theThumbnail)262         public  void processThumbnailPassComplete(BufferedImage theThumbnail) {
263             super.processThumbnailPassComplete(theThumbnail);
264         }
265 
processThumbnailPassStarted(BufferedImage theThumbnail, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands)266         public  void processThumbnailPassStarted(BufferedImage theThumbnail,
267                                                  int pass,
268                                                  int minPass,
269                                                  int maxPass,
270                                                  int minX,
271                                                  int minY,
272                                                  int periodX,
273                                                  int periodY,
274                                                  int[] bands) {
275             super.processThumbnailPassStarted(theThumbnail,
276                                               pass,
277                                               minPass,
278                                               maxPass,
279                                               minX,
280                                               minY,
281                                               periodX,
282                                               periodY,
283                                               bands);
284         }
285 
processThumbnailProgress(float percentageDone)286         public  void processThumbnailProgress(float percentageDone) {
287             super.processThumbnailProgress(percentageDone);
288         }
289 
processThumbnailStarted(int imageIndex, int thumbnailIndex)290         public  void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
291             super.processThumbnailStarted(imageIndex, thumbnailIndex);
292         }
293 
processThumbnailUpdate(BufferedImage theThumbnail, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands)294         public  void processThumbnailUpdate(BufferedImage theThumbnail,
295                                             int minX,
296                                             int minY,
297                                             int width,
298                                             int height,
299                                             int periodX,
300                                             int periodY,
301                                             int[] bands) {
302             super.processThumbnailUpdate(theThumbnail,
303                                          minX,
304                                          minY,
305                                          width,
306                                          height,
307                                          periodX,
308                                          periodY,
309                                          bands);
310         }
311 
processWarningOccurred(String warning)312         public  void processWarningOccurred(String warning) {
313             super.processWarningOccurred(warning);
314         }
315 
316 
317 
getSourceRegion(ImageReadParam param, int srcWidth, int srcHeight)318         public static Rectangle getSourceRegion(ImageReadParam param,
319                                                 int srcWidth,
320                                                 int srcHeight) {
321             return ImageReader.getSourceRegion(param, srcWidth, srcHeight);
322         }
323 
computeRegions(ImageReadParam param, int srcWidth, int srcHeight, BufferedImage image, Rectangle srcRegion, Rectangle destRegion)324         public static void computeRegions(ImageReadParam param,
325                                           int srcWidth,
326                                           int srcHeight,
327                                           BufferedImage image,
328                                           Rectangle srcRegion,
329                                           Rectangle destRegion) {
330             ImageReader.computeRegions(param,
331                                        srcWidth,
332                                        srcHeight,
333                                        image,
334                                        srcRegion,
335                                        destRegion);
336         }
337 
checkReadParamBandSettings(ImageReadParam param, int numSrcBands, int numDstBands)338         public static void checkReadParamBandSettings(ImageReadParam param,
339                                                       int numSrcBands,
340                                                       int numDstBands) {
341             ImageReader.checkReadParamBandSettings( param,
342                                                     numSrcBands,
343                                                     numDstBands);
344         }
345 
getDestination(ImageReadParam param, Iterator imageTypes, int width, int height)346         public static BufferedImage getDestination(ImageReadParam param,
347                                                    Iterator imageTypes,
348                                                    int width,
349                                                    int height)
350           throws IIOException {
351             return ImageReader.getDestination(param,
352                                               imageTypes,
353                                               width,
354                                               height);
355         }
356 
setAvailableLocales(Locale[] locales)357         public  void setAvailableLocales(Locale[] locales) {
358             if (locales == null || locales.length == 0)
359                 availableLocales = null;
360             else
361                 availableLocales = (Locale[])locales.clone();
362         }
363 
processWarningOccurred(String baseName, String keyword)364         public  void processWarningOccurred(String baseName, String keyword) {
365             super.processWarningOccurred(baseName, keyword);
366         }
367     }
368 
369     public static class DummyIIOMetadataFormatImpl
370         extends IIOMetadataFormatImpl {
371         public static String nativeMetadataFormatName =
372         "javax_imageio_dummy_1.0";
373 
374         private static IIOMetadataFormat instance = null;
375 
376 
DummyIIOMetadataFormatImpl()377         private DummyIIOMetadataFormatImpl() {
378             super(DummyIIOMetadataFormatImpl.nativeMetadataFormatName,
379                   CHILD_POLICY_SOME);
380         }
381 
canNodeAppear(String elementName, ImageTypeSpecifier imageType)382         public boolean canNodeAppear(String elementName,
383                                      ImageTypeSpecifier imageType) {
384             return false;
385         }
386 
getInstance()387         public static synchronized IIOMetadataFormat getInstance() {
388             if (instance == null) {
389                 instance = new DummyIIOMetadataFormatImpl();
390             }
391             return instance;
392         }
393     }
394 
395     public static class DummyIIOMetadataImpl extends IIOMetadata {
396 
DummyIIOMetadataImpl()397         public DummyIIOMetadataImpl() {
398             super();
399         }
400 
DummyIIOMetadataImpl(boolean standardMetadataFormatSupported, String nativeMetadataFormatName, String nativeMetadataFormatClassName, String[] extraMetadataFormatNames, String[] extraMetadataFormatClassNames)401         public DummyIIOMetadataImpl(boolean standardMetadataFormatSupported,
402                                     String nativeMetadataFormatName,
403                                     String nativeMetadataFormatClassName,
404                                     String[] extraMetadataFormatNames,
405                                     String[] extraMetadataFormatClassNames) {
406             super(standardMetadataFormatSupported,
407                   nativeMetadataFormatName,
408                   nativeMetadataFormatClassName,
409                   extraMetadataFormatNames,
410                   extraMetadataFormatClassNames);
411         }
412 
isReadOnly()413         public boolean isReadOnly() {
414             return true;
415         }
416 
getAsTree(String formatName)417         public Node getAsTree(String formatName) {
418             return null;
419         }
420 
mergeTree(String formatName, Node root)421         public void mergeTree(String formatName, Node root)
422           throws IIOInvalidTreeException {
423             throw new IllegalStateException();
424         }
425 
reset()426         public void reset() {
427             throw new IllegalStateException();
428         }
429     }
430 
431     public static class DummyImageReaderSpiImpl extends ImageReaderSpi {
432 
433         static final String[] names ={ "myformat" };
434 
DummyImageReaderSpiImpl()435         public DummyImageReaderSpiImpl() {
436             super("vendorName",
437                   "version",
438                   names,
439                   null,
440                   null,
441                   "DummyImageReaderImpl",
442                   STANDARD_INPUT_TYPE,
443                   null,
444                   true,
445                   null,
446                   null,
447                   null,
448                   null,
449                   true,
450                   null,
451                   null,
452                   null,
453                   null);
454         }
canDecodeInput(Object source)455         public boolean canDecodeInput(Object source)
456           throws IOException {
457             return true;
458         }
createReaderInstance(Object extension)459         public ImageReader createReaderInstance(Object extension)
460           throws IOException {
461             return new DummyImageReaderImpl(this);
462         }
getDescription(Locale locale)463         public String getDescription(Locale locale) {
464             return "DummyImageReaderSpiImpl";
465         }
466     }
467 }
468