001 /* IIOMetadata.java -- 002 Copyright (C) 2004 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.imageio.metadata; 040 041 import org.w3c.dom.Node; 042 043 /** 044 * Represents metadata that describe an image or an image stream. 045 * Each ImageIO plugin will represent image data using an opaque 046 * object but all such objects should expose their internal 047 * information as a tree of IIOMetadataNodes. 048 * 049 * There are three formats of metadata that a plugin can support: 050 * 051 * <ul> 052 * <li>a "native" format</li> 053 * <li>a custom format</li> 054 * <li>a standard plugin-neutral format</li> 055 * </ul> 056 * 057 * If a plugin supports more than one format of metadata, the other 058 * formats can be retrieved by calling getMetadataFormatNames. 059 * 060 * The native format is used to transfer metadata from one image to 061 * another image of the same type, losslessly. 062 * 063 * The custom format describes the image metadata and exposes a tree 064 * of IIOMetadataNodes but its internal representation is specific to 065 * this plugin. 066 * 067 * The plugin-neutral format uses a generic tree structure as its 068 * internal representation. 069 * 070 * ImageTranscoders may be used to convert metadata understood by one 071 * plugin to metadata understood by another, however the conversion 072 * may be lossy. 073 * 074 * @author Michael Koch (konqueror@gmx.de) 075 * @author Thomas Fitzsimmons (fitzsim@redhat.com) 076 */ 077 public abstract class IIOMetadata 078 { 079 protected IIOMetadataController controller; 080 protected IIOMetadataController defaultController; 081 protected String[] extraMetadataFormatClassNames; 082 protected String[] extraMetadataFormatNames; 083 protected String nativeMetadataFormatClassName; 084 protected String nativeMetadataFormatName; 085 protected boolean standardFormatSupported; 086 087 /** 088 * Construct an IIOMetadata object. 089 */ 090 protected IIOMetadata() 091 { 092 // Do nothing here. 093 } 094 095 /** 096 * Construct an IIOMetadata object. 097 * 098 * @param standardMetadataFormatSupported 099 * @param nativeMetadataFormatName 100 * @param nativeMetadataFormatClassName 101 * @param extraMetadataFormatNames 102 * @param extraMetadataFormatClassNames 103 * 104 * @throws IllegalArgumentException if extraMetadataFormatNames has length of 105 * zero or extraMetadataFormatNames and extraMetadataFormatClassNames are 106 * neither both null, not have the same length 107 */ 108 protected IIOMetadata(boolean standardMetadataFormatSupported, 109 String nativeMetadataFormatName, 110 String nativeMetadataFormatClassName, 111 String[] extraMetadataFormatNames, 112 String[] extraMetadataFormatClassNames) 113 { 114 if (extraMetadataFormatNames != null 115 && extraMetadataFormatNames.length == 0) 116 throw new IllegalArgumentException 117 ("extraMetadataFormatNames may not be empty"); 118 119 if (((extraMetadataFormatNames == null) 120 && (extraMetadataFormatClassNames != null)) 121 || ((extraMetadataFormatNames != null) 122 && (extraMetadataFormatClassNames == null)) 123 || ((extraMetadataFormatNames != null) 124 && (extraMetadataFormatClassNames != null) 125 && (extraMetadataFormatNames.length != 126 extraMetadataFormatClassNames.length))) 127 throw new IllegalArgumentException 128 ("extraMetadataFormatNames and extraMetadataFormatClassNames " + 129 "have different lengths"); 130 131 this.standardFormatSupported = standardMetadataFormatSupported; 132 this.nativeMetadataFormatName = nativeMetadataFormatName; 133 this.nativeMetadataFormatClassName = nativeMetadataFormatClassName; 134 this.extraMetadataFormatNames = extraMetadataFormatNames; 135 this.extraMetadataFormatClassNames = extraMetadataFormatClassNames; 136 } 137 138 public boolean activateController() 139 { 140 if (! hasController()) 141 return false; 142 143 return getDefaultController().activate(this); 144 } 145 146 public IIOMetadataController getController() 147 { 148 return controller; 149 } 150 151 public IIOMetadataController getDefaultController() 152 { 153 return defaultController; 154 } 155 156 public String[] getExtraMetadataFormatNames() 157 { 158 return (String[]) extraMetadataFormatNames.clone(); 159 } 160 161 public IIOMetadataFormat getMetadataFormat(String formatName) 162 { 163 if (formatName == null) 164 throw new IllegalArgumentException("formatName may not be null"); 165 166 String formatClassName = null; 167 168 if (isStandardMetadataFormatSupported() 169 && formatName.equals(nativeMetadataFormatName)) 170 formatClassName = nativeMetadataFormatClassName; 171 else 172 { 173 String[] extraFormatNames = getExtraMetadataFormatNames(); 174 175 for (int i = extraFormatNames.length - 1; i >= 0; --i) 176 if (extraFormatNames[i].equals(formatName)) 177 { 178 formatClassName = extraFormatNames[i]; 179 break; 180 } 181 } 182 183 if (formatClassName == null) 184 throw new IllegalArgumentException("unknown format"); 185 186 IIOMetadataFormat format; 187 188 try 189 { 190 format = (IIOMetadataFormat) Class.forName(formatClassName) 191 .newInstance(); 192 } 193 catch (Exception e) 194 { 195 IllegalStateException ise = new IllegalStateException(); 196 ise.initCause(e); 197 throw ise; 198 } 199 200 return format; 201 } 202 203 public String[] getMetadataFormatNames() 204 { 205 String[] formatNames = getExtraMetadataFormatNames(); 206 207 if (isStandardMetadataFormatSupported()) 208 { 209 // Combine native metadata format name and extra metadata format names 210 // into one String array. 211 String[] tmp = new String[formatNames.length + 1]; 212 tmp[0] = getNativeMetadataFormatName(); 213 214 for (int i = 1; i < tmp.length; ++i) 215 tmp[i] = formatNames[i - 1]; 216 217 formatNames = tmp; 218 } 219 220 return formatNames; 221 } 222 223 public String getNativeMetadataFormatName() 224 { 225 return nativeMetadataFormatName; 226 } 227 228 public boolean hasController() 229 { 230 return getController() != null; 231 } 232 233 public abstract boolean isReadOnly(); 234 235 public boolean isStandardMetadataFormatSupported() 236 { 237 return standardFormatSupported; 238 } 239 240 public abstract void reset(); 241 242 public void setController(IIOMetadataController controller) 243 { 244 this.controller = controller; 245 } 246 247 public abstract Node getAsTree (String formatName); 248 249 protected IIOMetadataNode getStandardChromaNode () 250 { 251 return null; 252 } 253 254 protected IIOMetadataNode getStandardCompressionNode () 255 { 256 return null; 257 } 258 259 protected IIOMetadataNode getStandardDataNode () 260 { 261 return null; 262 } 263 264 protected IIOMetadataNode getStandardDimensionNode () 265 { 266 return null; 267 } 268 269 protected IIOMetadataNode getStandardDocumentNode () 270 { 271 return null; 272 } 273 274 protected IIOMetadataNode getStandardTextNode () 275 { 276 return null; 277 } 278 279 protected IIOMetadataNode getStandardTileNode () 280 { 281 return null; 282 } 283 284 protected IIOMetadataNode getStandardTransparencyNode () 285 { 286 return null; 287 } 288 289 private void appendChild (IIOMetadataNode node, 290 IIOMetadataNode child) 291 { 292 if (child != null) 293 node.appendChild(child); 294 } 295 296 protected final IIOMetadataNode getStandardTree () 297 { 298 IIOMetadataNode node = new IIOMetadataNode(); 299 300 appendChild (node, getStandardChromaNode()); 301 appendChild (node, getStandardCompressionNode()); 302 appendChild (node, getStandardDataNode()); 303 appendChild (node, getStandardDimensionNode()); 304 appendChild (node, getStandardDocumentNode()); 305 appendChild (node, getStandardTextNode()); 306 appendChild (node, getStandardTileNode()); 307 appendChild (node, getStandardTransparencyNode()); 308 309 return node; 310 } 311 312 public abstract void mergeTree (String formatName, 313 Node root) 314 throws IIOInvalidTreeException; 315 316 public void setFromTree (String formatName, Node root) 317 throws IIOInvalidTreeException 318 { 319 reset(); 320 321 mergeTree (formatName, root); 322 } 323 }