jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFieldNode.java
changeset 34416 68c0d866db5d
child 36443 d9d59282fc1a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFieldNode.java	Mon Nov 23 12:26:12 2015 -0800
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2005, 2015, 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.
+ *
+ * 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.
+ */
+package com.sun.imageio.plugins.tiff;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.imageio.metadata.IIOMetadataNode;
+import org.w3c.dom.Node;
+import javax.imageio.plugins.tiff.TIFFDirectory;
+import javax.imageio.plugins.tiff.TIFFField;
+import javax.imageio.plugins.tiff.TIFFTag;
+import javax.imageio.plugins.tiff.TIFFTagSet;
+
+/**
+ * The <code>Node</code> representation of a <code>TIFFField</code>
+ * wherein the child node is procedural rather than buffered.
+ */
+public class TIFFFieldNode extends IIOMetadataNode {
+    private static String getNodeName(TIFFField f) {
+        return f.getData() instanceof TIFFDirectory ?
+            "TIFFIFD" : "TIFFField";
+    }
+
+    private boolean isIFD;
+
+    private Boolean isInitialized = Boolean.FALSE;
+
+    private TIFFField field;
+
+    public TIFFFieldNode(TIFFField field) {
+        super(getNodeName(field));
+
+        isIFD = field.getData() instanceof TIFFDirectory;
+
+        this.field = field;
+
+        TIFFTag tag = field.getTag();
+        int tagNumber = tag.getNumber();
+        String tagName = tag.getName();
+
+        if(isIFD) {
+            if(tagNumber != 0) {
+                setAttribute("parentTagNumber", Integer.toString(tagNumber));
+            }
+            if(tagName != null) {
+                setAttribute("parentTagName", tagName);
+            }
+
+            TIFFDirectory dir = (TIFFDirectory)field.getData();
+            TIFFTagSet[] tagSets = dir.getTagSets();
+            if(tagSets != null) {
+                StringBuilder tagSetNames = new StringBuilder();
+                for(int i = 0; i < tagSets.length; i++) {
+                    tagSetNames.append(tagSets[i].getClass().getName());
+                    if(i != tagSets.length - 1) {
+                        tagSetNames.append(",");
+                    }
+                }
+                setAttribute("tagSets", tagSetNames.toString());
+            }
+        } else {
+            setAttribute("number", Integer.toString(tagNumber));
+            setAttribute("name", tagName);
+        }
+    }
+
+    private synchronized void initialize() {
+        if(isInitialized) return;
+
+        if(isIFD) {
+            TIFFDirectory dir = (TIFFDirectory)field.getData();
+            TIFFField[] fields = dir.getTIFFFields();
+            if(fields != null) {
+                TIFFTagSet[] tagSets = dir.getTagSets();
+                List<TIFFTagSet> tagSetList = Arrays.asList(tagSets);
+                int numFields = fields.length;
+                for(int i = 0; i < numFields; i++) {
+                    TIFFField f = fields[i];
+                    int tagNumber = f.getTagNumber();
+                    TIFFTag tag = TIFFIFD.getTag(tagNumber, tagSetList);
+
+                    Node node = f.getAsNativeNode();
+
+                    if (node != null) {
+                        appendChild(node);
+                    }
+                }
+            }
+        } else {
+            IIOMetadataNode child;
+            int count = field.getCount();
+            if (field.getType() == TIFFTag.TIFF_UNDEFINED) {
+                child = new IIOMetadataNode("TIFFUndefined");
+
+                byte[] data = field.getAsBytes();
+                StringBuffer sb = new StringBuffer();
+                for (int i = 0; i < count; i++) {
+                    sb.append(Integer.toString(data[i] & 0xff));
+                    if (i < count - 1) {
+                        sb.append(",");
+                    }
+                }
+                child.setAttribute("value", sb.toString());
+            } else {
+                child = new IIOMetadataNode("TIFF" +
+                                            TIFFField.getTypeName(field.getType()) +
+                                            "s");
+
+                TIFFTag tag = field.getTag();
+
+                for (int i = 0; i < count; i++) {
+                    IIOMetadataNode cchild =
+                        new IIOMetadataNode("TIFF" +
+                                            TIFFField.getTypeName(field.getType()));
+
+                    cchild.setAttribute("value", field.getValueAsString(i));
+                    if (tag.hasValueNames() && field.isIntegral()) {
+                        int value = field.getAsInt(i);
+                        String name = tag.getValueName(value);
+                        if (name != null) {
+                            cchild.setAttribute("description", name);
+                        }
+                    }
+
+                    child.appendChild(cchild);
+                }
+            }
+            appendChild(child);
+        }
+
+        isInitialized = Boolean.TRUE;
+    }
+
+    // Need to override this method to avoid a stack overflow exception
+    // which will occur if super.appendChild is called from initialize().
+    public Node appendChild(Node newChild) {
+        if (newChild == null) {
+            throw new NullPointerException("newChild == null!");
+        }
+
+        return super.insertBefore(newChild, null);
+    }
+
+    // Override all methods which refer to child nodes.
+
+    public boolean hasChildNodes() {
+        initialize();
+        return super.hasChildNodes();
+    }
+
+    public int getLength() {
+        initialize();
+        return super.getLength();
+    }
+
+    public Node getFirstChild() {
+        initialize();
+        return super.getFirstChild();
+    }
+
+    public Node getLastChild() {
+        initialize();
+        return super.getLastChild();
+    }
+
+    public Node getPreviousSibling() {
+        initialize();
+        return super.getPreviousSibling();
+    }
+
+    public Node getNextSibling() {
+        initialize();
+        return super.getNextSibling();
+    }
+
+    public Node insertBefore(Node newChild,
+                             Node refChild) {
+        initialize();
+        return super.insertBefore(newChild, refChild);
+    }
+
+    public Node replaceChild(Node newChild,
+                             Node oldChild) {
+        initialize();
+        return super.replaceChild(newChild, oldChild);
+    }
+
+    public Node removeChild(Node oldChild) {
+        initialize();
+        return super.removeChild(oldChild);
+    }
+
+    public Node cloneNode(boolean deep) {
+        initialize();
+        return super.cloneNode(deep);
+    }
+}