001: /**
002: * Copyright (c) 2004-2005, www.pdfbox.org
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain the above copyright notice,
009: * this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: * 3. Neither the name of pdfbox; nor the names of its
014: * contributors may be used to endorse or promote products derived from this
015: * software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: * http://www.pdfbox.org
029: *
030: */package org.pdfbox.pdmodel.fdf;
031:
032: import java.io.BufferedInputStream;
033: import java.io.BufferedWriter;
034: import java.io.File;
035: import java.io.FileInputStream;
036: import java.io.FileOutputStream;
037: import java.io.FileWriter;
038: import java.io.InputStream;
039: import java.io.IOException;
040: import java.io.OutputStream;
041: import java.io.Writer;
042:
043: import org.pdfbox.cos.COSDictionary;
044: import org.pdfbox.cos.COSDocument;
045: import org.pdfbox.cos.COSName;
046:
047: import org.pdfbox.exceptions.COSVisitorException;
048:
049: import org.pdfbox.pdfparser.PDFParser;
050:
051: import org.pdfbox.pdfwriter.COSWriter;
052:
053: import org.pdfbox.util.XMLUtil;
054:
055: import org.w3c.dom.Document;
056: import org.w3c.dom.Element;
057:
058: /**
059: * This is the in-memory representation of the FDF document. You need to call
060: * close() on this object when you are done using it!!
061: *
062: * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
063: * @version $Revision: 1.6 $
064: */
065: public class FDFDocument {
066: private COSDocument document;
067:
068: /**
069: * Constructor, creates a new FDF document.
070: *
071: * @throws IOException If there is an error creating this document.
072: */
073: public FDFDocument() throws IOException {
074: document = new COSDocument();
075: document.setHeaderString("%FDF-1.2");
076:
077: //First we need a trailer
078: document.setTrailer(new COSDictionary());
079:
080: //Next we need the root dictionary.
081: FDFCatalog catalog = new FDFCatalog();
082: setCatalog(catalog);
083: }
084:
085: /**
086: * Constructor that uses an existing document. The COSDocument that
087: * is passed in must be valid.
088: *
089: * @param doc The COSDocument that this document wraps.
090: */
091: public FDFDocument(COSDocument doc) {
092: document = doc;
093: }
094:
095: /**
096: * This will create an FDF document from an XFDF XML document.
097: *
098: * @param doc The XML document that contains the XFDF data.
099: * @throws IOException If there is an error reading from the dom.
100: */
101: public FDFDocument(Document doc) throws IOException {
102: this ();
103: Element xfdf = doc.getDocumentElement();
104: if (!xfdf.getNodeName().equals("xfdf")) {
105: throw new IOException(
106: "Error while importing xfdf document, "
107: + "root should be 'xfdf' and not '"
108: + xfdf.getNodeName() + "'");
109: }
110: FDFCatalog cat = new FDFCatalog(xfdf);
111: setCatalog(cat);
112: }
113:
114: /**
115: * This will write this element as an XML document.
116: *
117: * @param output The stream to write the xml to.
118: *
119: * @throws IOException If there is an error writing the XML.
120: */
121: public void writeXML(Writer output) throws IOException {
122: output.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
123: output
124: .write("<xfdf xmlns=\"http://ns.adobe.com/xfdf/\" xml:space=\"preserve\">\n");
125:
126: getCatalog().writeXML(output);
127:
128: output.write("</xfdf>\n");
129: }
130:
131: /**
132: * This will get the low level document.
133: *
134: * @return The document that this layer sits on top of.
135: */
136: public COSDocument getDocument() {
137: return document;
138: }
139:
140: /**
141: * This will get the FDF Catalog. This is guaranteed to not return null.
142: *
143: * @return The documents /Root dictionary
144: */
145: public FDFCatalog getCatalog() {
146: FDFCatalog retval = null;
147: COSDictionary trailer = document.getTrailer();
148: COSDictionary root = (COSDictionary) trailer
149: .getDictionaryObject(COSName.ROOT);
150: if (root == null) {
151: retval = new FDFCatalog();
152: setCatalog(retval);
153: } else {
154: retval = new FDFCatalog(root);
155: }
156: return retval;
157: }
158:
159: /**
160: * This will set the FDF catalog for this FDF document.
161: *
162: * @param cat The FDF catalog.
163: */
164: public void setCatalog(FDFCatalog cat) {
165: COSDictionary trailer = document.getTrailer();
166: trailer.setItem(COSName.ROOT, cat);
167: }
168:
169: /**
170: * This will load a document from a file.
171: *
172: * @param filename The name of the file to load.
173: *
174: * @return The document that was loaded.
175: *
176: * @throws IOException If there is an error reading from the stream.
177: */
178: public static FDFDocument load(String filename) throws IOException {
179: return load(new BufferedInputStream(new FileInputStream(
180: filename)));
181: }
182:
183: /**
184: * This will load a document from a file.
185: *
186: * @param file The name of the file to load.
187: *
188: * @return The document that was loaded.
189: *
190: * @throws IOException If there is an error reading from the stream.
191: */
192: public static FDFDocument load(File file) throws IOException {
193: return load(new BufferedInputStream(new FileInputStream(file)));
194: }
195:
196: /**
197: * This will load a document from an input stream.
198: *
199: * @param input The stream that contains the document.
200: *
201: * @return The document that was loaded.
202: *
203: * @throws IOException If there is an error reading from the stream.
204: */
205: public static FDFDocument load(InputStream input)
206: throws IOException {
207: PDFParser parser = new PDFParser(input);
208: parser.parse();
209: return parser.getFDFDocument();
210: }
211:
212: /**
213: * This will load a document from a file.
214: *
215: * @param filename The name of the file to load.
216: *
217: * @return The document that was loaded.
218: *
219: * @throws IOException If there is an error reading from the stream.
220: */
221: public static FDFDocument loadXFDF(String filename)
222: throws IOException {
223: return loadXFDF(new BufferedInputStream(new FileInputStream(
224: filename)));
225: }
226:
227: /**
228: * This will load a document from a file.
229: *
230: * @param file The name of the file to load.
231: *
232: * @return The document that was loaded.
233: *
234: * @throws IOException If there is an error reading from the stream.
235: */
236: public static FDFDocument loadXFDF(File file) throws IOException {
237: return loadXFDF(new BufferedInputStream(new FileInputStream(
238: file)));
239: }
240:
241: /**
242: * This will load a document from an input stream.
243: *
244: * @param input The stream that contains the document.
245: *
246: * @return The document that was loaded.
247: *
248: * @throws IOException If there is an error reading from the stream.
249: */
250: public static FDFDocument loadXFDF(InputStream input)
251: throws IOException {
252: Document doc = XMLUtil.parse(input);
253: return new FDFDocument(doc);
254: }
255:
256: /**
257: * This will save this document to the filesystem.
258: *
259: * @param fileName The file to save as.
260: *
261: * @throws IOException If there is an error saving the document.
262: * @throws COSVisitorException If an error occurs while generating the data.
263: */
264: public void save(File fileName) throws IOException,
265: COSVisitorException {
266: save(new FileOutputStream(fileName));
267: }
268:
269: /**
270: * This will save this document to the filesystem.
271: *
272: * @param fileName The file to save as.
273: *
274: * @throws IOException If there is an error saving the document.
275: * @throws COSVisitorException If an error occurs while generating the data.
276: */
277: public void save(String fileName) throws IOException,
278: COSVisitorException {
279: save(new FileOutputStream(fileName));
280: }
281:
282: /**
283: * This will save the document to an output stream.
284: *
285: * @param output The stream to write to.
286: *
287: * @throws IOException If there is an error writing the document.
288: * @throws COSVisitorException If an error occurs while generating the data.
289: */
290: public void save(OutputStream output) throws IOException,
291: COSVisitorException {
292: COSWriter writer = null;
293: try {
294: writer = new COSWriter(output);
295: writer.write(document);
296: writer.close();
297: } finally {
298: if (writer != null) {
299: writer.close();
300: }
301: }
302: }
303:
304: /**
305: * This will save this document to the filesystem.
306: *
307: * @param fileName The file to save as.
308: *
309: * @throws IOException If there is an error saving the document.
310: * @throws COSVisitorException If an error occurs while generating the data.
311: */
312: public void saveXFDF(File fileName) throws IOException,
313: COSVisitorException {
314: saveXFDF(new BufferedWriter(new FileWriter(fileName)));
315: }
316:
317: /**
318: * This will save this document to the filesystem.
319: *
320: * @param fileName The file to save as.
321: *
322: * @throws IOException If there is an error saving the document.
323: * @throws COSVisitorException If an error occurs while generating the data.
324: */
325: public void saveXFDF(String fileName) throws IOException,
326: COSVisitorException {
327: saveXFDF(new BufferedWriter(new FileWriter(fileName)));
328: }
329:
330: /**
331: * This will save the document to an output stream and close the stream.
332: *
333: * @param output The stream to write to.
334: *
335: * @throws IOException If there is an error writing the document.
336: * @throws COSVisitorException If an error occurs while generating the data.
337: */
338: public void saveXFDF(Writer output) throws IOException,
339: COSVisitorException {
340: try {
341: writeXML(output);
342: } finally {
343: if (output != null) {
344: output.close();
345: }
346: }
347: }
348:
349: /**
350: * This will close the underlying COSDocument object.
351: *
352: * @throws IOException If there is an error releasing resources.
353: */
354: public void close() throws IOException {
355: document.close();
356: }
357: }
|