1//=================================================================================================
2//ADOBE SYSTEMS INCORPORATED
3//Copyright 2006-2007 Adobe Systems Incorporated
4//All Rights Reserved
5//
6//NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
7//of the Adobe license agreement accompanying it.
8//=================================================================================================
9
10package com.adobe.xmp;
11
12import java.io.InputStream;
13import java.io.OutputStream;
14
15import com.adobe.xmp.impl.XMPMetaImpl;
16import com.adobe.xmp.impl.XMPMetaParser;
17import com.adobe.xmp.impl.XMPSchemaRegistryImpl;
18import com.adobe.xmp.impl.XMPSerializerHelper;
19import com.adobe.xmp.options.ParseOptions;
20import com.adobe.xmp.options.SerializeOptions;
21
22
23/**
24 * Creates <code>XMPMeta</code>-instances from an <code>InputStream</code>
25 *
26 * @since 30.01.2006
27 */
28public final class XMPMetaFactory
29{
30	/** The singleton instance of the <code>XMPSchemaRegistry</code>. */
31	private static XMPSchemaRegistry schema = new XMPSchemaRegistryImpl();
32	/** cache for version info */
33	private static XMPVersionInfo versionInfo = null;
34
35	/**
36	 * Hides public constructor
37	 */
38	private XMPMetaFactory()
39	{
40		// EMPTY
41	}
42
43
44	/**
45	 * @return Returns the singleton instance of the <code>XMPSchemaRegistry</code>.
46	 */
47	public static XMPSchemaRegistry getSchemaRegistry()
48	{
49		return schema;
50	}
51
52
53	/**
54	 * @return Returns an empty <code>XMPMeta</code>-object.
55	 */
56	public static XMPMeta create()
57	{
58		return new XMPMetaImpl();
59	}
60
61
62	/**
63	 * Parsing with default options.
64	 * @see XMPMetaFactory#parse(InputStream, ParseOptions)
65	 *
66	 * @param in an <code>InputStream</code>
67	 * @return Returns the <code>XMPMeta</code>-object created from the input.
68	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
69	 */
70	public static XMPMeta parse(InputStream in) throws XMPException
71	{
72		return parse(in, null);
73	}
74
75
76	/**
77	 * These functions support parsing serialized RDF into an XMP object, and serailizing an XMP
78	 * object into RDF. The input for parsing may be any valid Unicode
79	 * encoding. ISO Latin-1 is also recognized, but its use is strongly discouraged. Serialization
80	 * is always as UTF-8.
81	 * <p>
82	 * <code>parseFromBuffer()</code> parses RDF from an <code>InputStream</code>. The encoding
83	 * is recognized automatically.
84	 *
85	 * @param in an <code>InputStream</code>
86	 * @param options Options controlling the parsing.<br>
87	 *        The available options are:
88	 *        <ul>
89	 *        <li> XMP_REQUIRE_XMPMETA - The &lt;x:xmpmeta&gt; XML element is required around
90	 *        <tt>&lt;rdf:RDF&gt;</tt>.
91	 *        <li> XMP_STRICT_ALIASING - Do not reconcile alias differences, throw an exception.
92	 *        </ul>
93	 *        <em>Note:</em>The XMP_STRICT_ALIASING option is not yet implemented.
94	 * @return Returns the <code>XMPMeta</code>-object created from the input.
95	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
96	 */
97	public static XMPMeta parse(InputStream in, ParseOptions options)
98			throws XMPException
99	{
100		return XMPMetaParser.parse(in, options);
101	}
102
103
104	/**
105	 * Parsing with default options.
106	 * @see XMPMetaFactory#parse(InputStream)
107	 *
108	 * @param packet a String contain an XMP-file.
109	 * @return Returns the <code>XMPMeta</code>-object created from the input.
110	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
111	 */
112	public static XMPMeta parseFromString(String packet) throws XMPException
113	{
114		return parseFromString(packet, null);
115	}
116
117
118	/**
119	 * Creates an <code>XMPMeta</code>-object from a string.
120	 * @see XMPMetaFactory#parseFromString(String, ParseOptions)
121	 *
122	 * @param packet a String contain an XMP-file.
123	 * @param options Options controlling the parsing.
124	 * @return Returns the <code>XMPMeta</code>-object created from the input.
125	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
126	 */
127	public static XMPMeta parseFromString(String packet, ParseOptions options)
128			throws XMPException
129	{
130		return XMPMetaParser.parse(packet, options);
131	}
132
133
134	/**
135	 * Parsing with default options.
136	 * @see XMPMetaFactory#parseFromBuffer(byte[], ParseOptions)
137	 *
138	 * @param buffer a String contain an XMP-file.
139	 * @return Returns the <code>XMPMeta</code>-object created from the input.
140	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
141	 */
142	public static XMPMeta parseFromBuffer(byte[] buffer) throws XMPException
143	{
144		return parseFromBuffer(buffer, null);
145	}
146
147
148	/**
149	 * Creates an <code>XMPMeta</code>-object from a byte-buffer.
150	 * @see XMPMetaFactory#parse(InputStream, ParseOptions)
151	 *
152	 * @param buffer a String contain an XMP-file.
153	 * @param options Options controlling the parsing.
154	 * @return Returns the <code>XMPMeta</code>-object created from the input.
155	 * @throws XMPException If the file is not well-formed XML or if the parsing fails.
156	 */
157	public static XMPMeta parseFromBuffer(byte[] buffer,
158		ParseOptions options) throws XMPException
159	{
160		return XMPMetaParser.parse(buffer, options);
161	}
162
163
164	/**
165	 * Serializes an <code>XMPMeta</code>-object as RDF into an <code>OutputStream</code>
166	 * with default options.
167	 *
168	 * @param xmp a metadata object
169	 * @param out an <code>OutputStream</code> to write the serialized RDF to.
170	 * @throws XMPException on serializsation errors.
171	 */
172	public static void serialize(XMPMeta xmp, OutputStream out) throws XMPException
173	{
174		serialize(xmp, out, null);
175	}
176
177
178	/**
179	 * Serializes an <code>XMPMeta</code>-object as RDF into an <code>OutputStream</code>.
180	 *
181	 * @param xmp a metadata object
182	 * @param options Options to control the serialization (see {@link SerializeOptions}).
183	 * @param out an <code>OutputStream</code> to write the serialized RDF to.
184	 * @throws XMPException on serializsation errors.
185	 */
186	public static void serialize(XMPMeta xmp, OutputStream out, SerializeOptions options)
187			throws XMPException
188	{
189		assertImplementation(xmp);
190		XMPSerializerHelper.serialize((XMPMetaImpl) xmp, out, options);
191	}
192
193
194	/**
195	 * Serializes an <code>XMPMeta</code>-object as RDF into a byte buffer.
196	 *
197	 * @param xmp a metadata object
198	 * @param options Options to control the serialization (see {@link SerializeOptions}).
199	 * @return Returns a byte buffer containing the serialized RDF.
200	 * @throws XMPException on serializsation errors.
201	 */
202	public static byte[] serializeToBuffer(XMPMeta xmp, SerializeOptions options)
203			throws XMPException
204	{
205		assertImplementation(xmp);
206		return XMPSerializerHelper.serializeToBuffer((XMPMetaImpl) xmp, options);
207	}
208
209
210	/**
211	 * Serializes an <code>XMPMeta</code>-object as RDF into a string. <em>Note:</em> Encoding
212	 * is ignored when serializing to a string.
213	 *
214	 * @param xmp a metadata object
215	 * @param options Options to control the serialization (see {@link SerializeOptions}).
216	 * @return Returns a string containing the serialized RDF.
217	 * @throws XMPException on serializsation errors.
218	 */
219	public static String serializeToString(XMPMeta xmp, SerializeOptions options)
220			throws XMPException
221	{
222		assertImplementation(xmp);
223		return XMPSerializerHelper.serializeToString((XMPMetaImpl) xmp, options);
224	}
225
226
227	/**
228	 * @param xmp Asserts that xmp is compatible to <code>XMPMetaImpl</code>.s
229	 */
230	private static void assertImplementation(XMPMeta xmp)
231	{
232		if (!(xmp instanceof XMPMetaImpl))
233		{
234			throw new UnsupportedOperationException("The serializing service works only" +
235				"with the XMPMeta implementation of this library");
236		}
237	}
238
239
240	/**
241	 * Resets the schema registry to its original state (creates a new one).
242	 * Be careful this might break all existing XMPMeta-objects and should be used
243	 * only for testing purpurses.
244	 */
245	public static void reset()
246	{
247		schema = new XMPSchemaRegistryImpl();
248	}
249
250
251	/**
252	 * Obtain version information. The XMPVersionInfo singleton is created the first time
253	 * its requested.
254	 *
255	 * @return Returns the version information.
256	 */
257	public static synchronized XMPVersionInfo getVersionInfo()
258	{
259		if (versionInfo == null)
260		{
261			try
262			{
263				final int major = 5;
264				final int minor = 1;
265				final int micro = 0;
266				final int engBuild = 3;
267				final boolean debug = false;
268
269				// Adobe XMP Core 5.0-jc001 DEBUG-<branch>.<changelist>, 2009 Jan 28 15:22:38-CET
270				final String message = "Adobe XMP Core 5.1.0-jc003";
271
272
273				versionInfo = new XMPVersionInfo()
274				{
275					public int getMajor()
276					{
277						return major;
278					}
279
280					public int getMinor()
281					{
282						return minor;
283					}
284
285					public int getMicro()
286					{
287						return micro;
288					}
289
290					public boolean isDebug()
291					{
292						return debug;
293					}
294
295					public int getBuild()
296					{
297						return engBuild;
298					}
299
300					public String getMessage()
301					{
302						return message;
303					}
304
305					public String toString()
306					{
307						return message;
308					}
309				};
310
311			}
312			catch (Throwable e)
313			{
314				// EMTPY, severe error would be detected during the tests
315				System.out.println(e);
316			}
317		}
318		return versionInfo;
319	}
320}
321