001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: XMPSerializer.java 426584 2006-07-28 16:01:47Z jeremias $ */
019:
020: package org.apache.xmlgraphics.xmp;
021:
022: import java.io.OutputStream;
023:
024: import javax.xml.transform.OutputKeys;
025: import javax.xml.transform.Result;
026: import javax.xml.transform.Transformer;
027: import javax.xml.transform.TransformerConfigurationException;
028: import javax.xml.transform.sax.SAXTransformerFactory;
029: import javax.xml.transform.sax.TransformerHandler;
030: import javax.xml.transform.stream.StreamResult;
031:
032: import org.xml.sax.SAXException;
033:
034: /**
035: * Serializes an XMP tree to XML or to an XMP packet.
036: */
037: public class XMPSerializer {
038:
039: private static final String DEFAULT_ENCODING = "UTF-8";
040:
041: /**
042: * Writes the in-memory representation of the XMP metadata to a JAXP Result.
043: * @param meta the metadata
044: * @param res the JAXP Result to write to
045: * @throws TransformerConfigurationException if an error occurs setting up the XML
046: * infrastructure.
047: * @throws SAXException if a SAX-related problem occurs while writing the XML
048: */
049: public static void writeXML(Metadata meta, Result res)
050: throws TransformerConfigurationException, SAXException {
051: writeXML(meta, res, false, false);
052: }
053:
054: /**
055: * Writes the in-memory representation of the XMP metadata to an OutputStream as an XMP packet.
056: * @param meta the metadata
057: * @param out the stream to write to
058: * @param readOnlyXMP true if the generated XMP packet should be read-only
059: * @throws TransformerConfigurationException if an error occurs setting up the XML
060: * infrastructure.
061: * @throws SAXException if a SAX-related problem occurs while writing the XML
062: */
063: public static void writeXMPPacket(Metadata meta, OutputStream out,
064: boolean readOnlyXMP)
065: throws TransformerConfigurationException, SAXException {
066: StreamResult res = new StreamResult(out);
067: writeXML(meta, res, true, readOnlyXMP);
068:
069: }
070:
071: private static void writeXML(Metadata meta, Result res,
072: boolean asXMPPacket, boolean readOnlyXMP)
073: throws TransformerConfigurationException, SAXException {
074: SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory
075: .newInstance();
076: TransformerHandler handler = tFactory.newTransformerHandler();
077: Transformer transformer = handler.getTransformer();
078: if (asXMPPacket) {
079: transformer.setOutputProperty(
080: OutputKeys.OMIT_XML_DECLARATION, "yes");
081: }
082: transformer.setOutputProperty(OutputKeys.ENCODING,
083: DEFAULT_ENCODING);
084: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
085: handler.setResult(res);
086: handler.startDocument();
087: if (asXMPPacket) {
088: handler.processingInstruction("xpacket",
089: "begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"");
090: }
091: meta.toSAX(handler);
092: if (asXMPPacket) {
093: if (readOnlyXMP) {
094: handler.processingInstruction("xpacket", "end=\"r\"");
095: } else {
096: //Create padding string (40 * 101 characters is more or less the recommended 4KB)
097: StringBuffer sb = new StringBuffer(101);
098: sb.append('\n');
099: for (int i = 0; i < 100; i++) {
100: sb.append(" ");
101: }
102: char[] padding = sb.toString().toCharArray();
103: for (int i = 0; i < 40; i++) {
104: handler.characters(padding, 0, padding.length);
105: }
106: handler.characters(new char[] { '\n' }, 0, 1);
107: handler.processingInstruction("xpacket", "end=\"w\"");
108: }
109:
110: }
111: handler.endDocument();
112: }
113:
114: }
|