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 5082756 27 * @summary ensure that boolean attributes follow ( "TRUE" | "FALSE" ) 28 * including correct (i.e. upper) case 29 * 30 * @run main BooleanAttributes 31 */ 32 33import java.awt.image.BufferedImage; 34import java.io.ByteArrayInputStream; 35import java.io.ByteArrayOutputStream; 36import java.io.StringReader; 37import java.util.Arrays; 38import java.util.List; 39import javax.imageio.IIOImage; 40import javax.imageio.ImageIO; 41import javax.imageio.ImageReader; 42import javax.imageio.ImageTypeSpecifier; 43import javax.imageio.ImageWriteParam; 44import javax.imageio.ImageWriter; 45import javax.imageio.metadata.IIOMetadata; 46import javax.imageio.stream.ImageInputStream; 47import javax.imageio.stream.ImageOutputStream; 48import javax.imageio.stream.MemoryCacheImageInputStream; 49import javax.imageio.stream.MemoryCacheImageOutputStream; 50import javax.xml.transform.Result; 51import javax.xml.transform.Source; 52import javax.xml.transform.TransformerFactory; 53import javax.xml.transform.dom.DOMResult; 54import javax.xml.transform.stream.StreamSource; 55import javax.xml.xpath.XPath; 56import javax.xml.xpath.XPathConstants; 57import javax.xml.xpath.XPathFactory; 58import org.w3c.dom.Document; 59import org.w3c.dom.Element; 60import org.w3c.dom.Node; 61import org.w3c.dom.NodeList; 62 63public class BooleanAttributes { 64 65 private static TransformerFactory transformerFactory = 66 TransformerFactory.newInstance(); 67 68 private static XPath xpathEngine = XPathFactory.newInstance().newXPath(); 69 70 public static void main(String[] args) throws Exception { 71 test("image/png", false, "<javax_imageio_1.0 />", 72 "Chroma/BlackIsZero/@value", 73 "Compression/Lossless/@value"); 74 75 test("image/png", false, 76 "<javax_imageio_png_1.0>" + 77 "<iTXt><iTXtEntry keyword='Comment' compressionFlag='TRUE' " + 78 "compressionMethod='0' languageTag='en' " + 79 "translatedKeyword='comment' text='foo'/></iTXt>" + 80 "</javax_imageio_png_1.0>", 81 "iTXt/iTXtEntry/@compressionFlag"); 82 83 test("image/png", false, 84 "<javax_imageio_png_1.0>" + 85 "<iTXt><iTXtEntry keyword='Comment' compressionFlag='FALSE' " + 86 "compressionMethod='0' languageTag='en' " + 87 "translatedKeyword='comment' text='foo'/></iTXt>" + 88 "</javax_imageio_png_1.0>", 89 "iTXt/iTXtEntry/@compressionFlag"); 90 91 test("image/gif", false, "<javax_imageio_1.0 />", 92 "Chroma/BlackIsZero/@value", 93 "Compression/Lossless/@value"); 94 95 test("image/gif", false, 96 "<javax_imageio_gif_image_1.0>" + 97 "<ImageDescriptor imageLeftPosition='0' imageTopPosition='0' " + 98 "imageWidth='16' imageHeight='16' interlaceFlag='TRUE' />" + 99 "<LocalColorTable sizeOfLocalColorTable='2' " + 100 "backgroundColorIndex='1' sortFlag='TRUE'>" + 101 "<ColorTableEntry index='0' red='0' green='0' blue='0' />" + 102 "<ColorTableEntry index='1' red='255' green='255' blue='255' />" + 103 "</LocalColorTable>" + 104 "<GraphicControlExtension disposalMethod='doNotDispose' " + 105 "userInputFlag='FALSE' transparentColorFlag='TRUE' " + 106 "delayTime='100' transparentColorIndex='1' />" + 107 "</javax_imageio_gif_image_1.0>", 108 "ImageDescriptor/@interlaceFlag", 109 "LocalColorTable/@sortFlag", 110 "GraphicControlExtension/@userInputFlag", 111 "GraphicControlExtension/@transparentColorFlag"); 112 113 test("image/gif", true, 114 "<javax_imageio_gif_stream_1.0>" + 115 "<GlobalColorTable sizeOfGlobalColorTable='2' " + 116 "backgroundColorIndex='1' sortFlag='TRUE'>" + 117 "<ColorTableEntry index='0' red='0' green='0' blue='0' />" + 118 "<ColorTableEntry index='1' red='255' green='255' blue='255' />" + 119 "</GlobalColorTable>" + 120 "</javax_imageio_gif_stream_1.0>", 121 "GlobalColorTable/@sortFlag"); 122 123 test("image/jpeg", false, "<javax_imageio_1.0 />", 124 "Compression/Lossless/@value"); 125 } 126 127 private static void transform(Source src, Result dst) 128 throws Exception 129 { 130 transformerFactory.newTransformer().transform(src, dst); 131 } 132 133 private static void verify(Node meta, String[] xpaths, boolean required) 134 throws Exception 135 { 136 for (String xpath: xpaths) { 137 NodeList list = (NodeList) 138 xpathEngine.evaluate(xpath, meta, XPathConstants.NODESET); 139 if (list.getLength() == 0 && required) 140 throw new AssertionError("Missing value: " + xpath); 141 for (int i = 0; i < list.getLength(); ++i) { 142 String value = list.item(i).getNodeValue(); 143 if (!(value.equals("TRUE") || value.equals("FALSE"))) 144 throw new AssertionError(xpath + " has value " + value); 145 } 146 } 147 } 148 149 public static void test(String mimeType, boolean useStreamMeta, 150 String metaXml, String... boolXpaths) 151 throws Exception 152 { 153 BufferedImage img = 154 new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB); 155 ImageWriter iw = ImageIO.getImageWritersByMIMEType(mimeType).next(); 156 ByteArrayOutputStream os = new ByteArrayOutputStream(); 157 ImageOutputStream ios = new MemoryCacheImageOutputStream(os); 158 iw.setOutput(ios); 159 ImageWriteParam param = null; 160 IIOMetadata streamMeta = iw.getDefaultStreamMetadata(param); 161 IIOMetadata imageMeta = 162 iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param); 163 IIOMetadata meta = useStreamMeta ? streamMeta : imageMeta; 164 Source src = new StreamSource(new StringReader(metaXml)); 165 DOMResult dst = new DOMResult(); 166 transform(src, dst); 167 Document doc = (Document)dst.getNode(); 168 Element node = doc.getDocumentElement(); 169 String metaFormat = node.getNodeName(); 170 171 // Verify that the default metadata gets formatted correctly. 172 verify(meta.getAsTree(metaFormat), boolXpaths, false); 173 174 meta.mergeTree(metaFormat, node); 175 176 // Verify that the merged metadata gets formatte correctly. 177 verify(meta.getAsTree(metaFormat), boolXpaths, true); 178 179 iw.write(streamMeta, new IIOImage(img, null, imageMeta), param); 180 iw.dispose(); 181 ios.close(); 182 ImageReader ir = ImageIO.getImageReader(iw); 183 byte[] bytes = os.toByteArray(); 184 if (bytes.length == 0) 185 throw new AssertionError("Zero length image file"); 186 ByteArrayInputStream is = new ByteArrayInputStream(bytes); 187 ImageInputStream iis = new MemoryCacheImageInputStream(is); 188 ir.setInput(iis); 189 if (useStreamMeta) meta = ir.getStreamMetadata(); 190 else meta = ir.getImageMetadata(0); 191 192 // Verify again after writing and re-reading the image 193 verify(meta.getAsTree(metaFormat), boolXpaths, true); 194 } 195 196 public static void xtest(Object... eatAnyArguments) { 197 System.err.println("Disabled test! Change xtest back into test!"); 198 } 199 200} 201