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 }