aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/lowagie/text/xml
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/lowagie/text/xml')
-rw-r--r--src/main/java/com/lowagie/text/xml/SAXiTextHandler.java921
-rw-r--r--src/main/java/com/lowagie/text/xml/SAXmyHandler.java128
-rw-r--r--src/main/java/com/lowagie/text/xml/TagMap.java213
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlParser.java379
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlPeer.java182
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlToHtml.java144
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlToPdf.java144
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlToRtf.java144
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlToXXX.java147
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlWriter.java893
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/DublinCoreSchema.java187
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/PdfSchema.java105
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/XmpArray.java99
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/XmpBasicSchema.java141
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/XmpMMSchema.java97
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/XmpSchema.java158
-rw-r--r--src/main/java/com/lowagie/text/xml/xmp/XmpWriter.java276
17 files changed, 4358 insertions, 0 deletions
diff --git a/src/main/java/com/lowagie/text/xml/SAXiTextHandler.java b/src/main/java/com/lowagie/text/xml/SAXiTextHandler.java
new file mode 100644
index 0000000..00fb5bf
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/SAXiTextHandler.java
@@ -0,0 +1,921 @@
+/*
+ * $Id: SAXiTextHandler.java,v 1.52 2006/04/20 11:49:41 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EmptyStackException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.lowagie.text.Anchor;
+import com.lowagie.text.Annotation;
+import com.lowagie.text.BadElementException;
+import com.lowagie.text.Cell;
+import com.lowagie.text.Chapter;
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocListener;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.ElementTags;
+import com.lowagie.text.Entities;
+import com.lowagie.text.ExceptionConverter;
+import com.lowagie.text.Font;
+import com.lowagie.text.Graphic;
+import com.lowagie.text.Image;
+import com.lowagie.text.List;
+import com.lowagie.text.ListItem;
+import com.lowagie.text.Meta;
+import com.lowagie.text.PageSize;
+import com.lowagie.text.Paragraph;
+import com.lowagie.text.Phrase;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.Row;
+import com.lowagie.text.Section;
+import com.lowagie.text.Table;
+import com.lowagie.text.TextElementArray;
+import com.lowagie.text.html.HtmlTagMap;
+import com.lowagie.text.pdf.BaseFont;
+
+/**
+ * This class is a Handler that controls the iText XML to PDF conversion.
+ * Subclass it, if you want to change the way iText translates XML to PDF.
+ */
+
+public class SAXiTextHandler extends DefaultHandler {
+
+ /** This is the resulting document. */
+ protected DocListener document;
+
+ /**
+ * This is a <CODE>Stack</CODE> of objects, waiting to be added to the
+ * document.
+ */
+ protected Stack stack;
+
+ /** Counts the number of chapters in this document. */
+ protected int chapters = 0;
+
+ /** This is the current chunk to which characters can be added. */
+ protected Chunk currentChunk = null;
+
+ /** This is the current chunk to which characters can be added. */
+ protected boolean ignore = false;
+
+ /**
+ * This is a flag that can be set, if you want to open and close the
+ * Document-object yourself.
+ */
+ protected boolean controlOpenClose = true;
+
+ /** current margin of a page. */
+ float topMargin = 36;
+
+ /** current margin of a page. */
+ float rightMargin = 36;
+
+ /** current margin of a page. */
+ float leftMargin = 36;
+
+ /** current margin of a page. */
+ float bottomMargin = 36;
+
+ /**
+ * @param document
+ * @throws IOException
+ */
+ public SAXiTextHandler(DocListener document)
+ throws IOException {
+ super();
+ this.document = document;
+ stack = new Stack();
+ }
+
+ protected HashMap myTags;
+
+ /**
+ * @param document
+ * @param myTags
+ * @throws IOException
+ */
+ public SAXiTextHandler(DocListener document, HtmlTagMap myTags)
+ throws IOException {
+ this(document);
+ this.myTags = myTags;
+ }
+
+ /**
+ * @param document
+ * @param myTags
+ * @param bf
+ * @throws IOException
+ */
+ public SAXiTextHandler(DocListener document, HtmlTagMap myTags,
+ BaseFont bf) throws IOException {
+ this(document, myTags);
+ this.bf = bf;
+ }
+
+ /**
+ * @param document
+ * @param myTags
+ * @throws IOException
+ */
+ public SAXiTextHandler(DocListener document, HashMap myTags)
+ throws IOException {
+ this(document);
+ this.myTags = myTags;
+ }
+
+ /**
+ * Sets the parameter that allows you to enable/disable the control over the
+ * Document.open() and Document.close() method.
+ * <P>
+ * If you set this parameter to true (= default), the parser will open the
+ * Document object when the start-root-tag is encounterd and close it when
+ * the end-root-tag is met. If you set it to false, you have to open and
+ * close the Document object yourself.
+ *
+ * @param controlOpenClose
+ * set this to false if you plan to open/close the Document
+ * yourself
+ */
+
+ public void setControlOpenClose(boolean controlOpenClose) {
+ this.controlOpenClose = controlOpenClose;
+ }
+
+ /**
+ * This method gets called when a start tag is encountered.
+ *
+ * @param uri
+ * the Uniform Resource Identifier
+ * @param lname
+ * the local name (without prefix), or the empty string if
+ * Namespace processing is not being performed.
+ * @param name
+ * the name of the tag that is encountered
+ * @param attrs
+ * the list of attributes
+ */
+
+ public void startElement(String uri, String lname, String name,
+ Attributes attrs) {
+
+ Properties attributes = new Properties();
+ if (attrs != null) {
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attribute = attrs.getQName(i);
+ attributes.setProperty(attribute, attrs.getValue(i));
+ }
+ }
+ handleStartingTags(name, attributes);
+ }
+
+ /**
+ * This method deals with the starting tags.
+ *
+ * @param name
+ * the name of the tag
+ * @param attributes
+ * the list of attributes
+ */
+
+ public void handleStartingTags(String name, Properties attributes) {
+ // System.err.println("Start: " + name);
+ if (ignore || ElementTags.IGNORE.equals(name)) {
+ ignore = true;
+ return;
+ }
+
+ // maybe there is some meaningful data that wasn't between tags
+ if (currentChunk != null) {
+ TextElementArray current;
+ try {
+ current = (TextElementArray) stack.pop();
+ } catch (EmptyStackException ese) {
+ if (bf == null) {
+ current = new Paragraph("", new Font());
+ }
+ else {
+ current = new Paragraph("", new Font(this.bf));
+ }
+ }
+ current.add(currentChunk);
+ stack.push(current);
+ currentChunk = null;
+ }
+
+ // chunks
+ if (Chunk.isTag(name)) {
+ currentChunk = new Chunk(attributes);
+ if (bf != null) {
+ currentChunk.setFont(new Font(this.bf));
+ }
+ return;
+ }
+
+ // symbols
+ if (Entities.isTag(name)) {
+ Font f = new Font();
+ if (currentChunk != null) {
+ handleEndingTags(ElementTags.CHUNK);
+ f = currentChunk.font();
+ }
+ currentChunk = Entities.get(attributes.getProperty(ElementTags.ID),
+ f);
+ return;
+ }
+
+ // phrases
+ if (Phrase.isTag(name)) {
+ stack.push(new Phrase(attributes));
+ return;
+ }
+
+ // anchors
+ if (Anchor.isTag(name)) {
+ stack.push(new Anchor(attributes));
+ return;
+ }
+
+ // paragraphs and titles
+ if (Paragraph.isTag(name) || Section.isTitle(name)) {
+ stack.push(new Paragraph(attributes));
+ return;
+ }
+
+ // lists
+ if (List.isTag(name)) {
+ stack.push(new List(attributes));
+ return;
+ }
+
+ // listitems
+ if (ListItem.isTag(name)) {
+ stack.push(new ListItem(attributes));
+ return;
+ }
+
+ // cells
+ if (Cell.isTag(name)) {
+ stack.push(new Cell(attributes));
+ return;
+ }
+
+ // tables
+ if (Table.isTag(name)) {
+ Table table = new Table(attributes);
+ float widths[] = table.getProportionalWidths();
+ for (int i = 0; i < widths.length; i++) {
+ if (widths[i] == 0) {
+ widths[i] = 100.0f / (float) widths.length;
+ }
+ }
+ try {
+ table.setWidths(widths);
+ } catch (BadElementException bee) {
+ // this shouldn't happen
+ throw new ExceptionConverter(bee);
+ }
+ stack.push(table);
+ return;
+ }
+
+ // sections
+ if (Section.isTag(name)) {
+ Element previous = (Element) stack.pop();
+ Section section;
+ try {
+ section = ((Section) previous).addSection(attributes);
+ } catch (ClassCastException cce) {
+ throw new ExceptionConverter(cce);
+ }
+ stack.push(previous);
+ stack.push(section);
+ return;
+ }
+
+ // chapters
+ if (Chapter.isTag(name)) {
+ String value; // changed after a suggestion by Serge S. Vasiljev
+ if ((value = (String) attributes.remove(ElementTags.NUMBER)) != null) {
+ chapters = Integer.parseInt(value);
+ } else {
+ chapters++;
+ }
+ Chapter chapter = new Chapter(attributes, chapters);
+ stack.push(chapter);
+ return;
+ }
+
+ // images
+ if (Image.isTag(name)) {
+ try {
+ Image img = Image.getInstance(attributes);
+ Object current;
+ try {
+ // if there is an element on the stack...
+ current = stack.pop();
+ // ...and it's a Chapter or a Section, the Image can be
+ // added directly
+ if (current instanceof Chapter
+ || current instanceof Section
+ || current instanceof Cell) {
+ ((TextElementArray) current).add(img);
+ stack.push(current);
+ return;
+ }
+ // ...if not, the Image is wrapped in a Chunk before it's
+ // added
+ else {
+ Stack newStack = new Stack();
+ try {
+ while (!(current instanceof Chapter
+ || current instanceof Section || current instanceof Cell)) {
+ newStack.push(current);
+ if (current instanceof Anchor) {
+ img.setAnnotation(new Annotation(0, 0, 0,
+ 0, ((Anchor) current).reference()));
+ }
+ current = stack.pop();
+ }
+ ((TextElementArray) current).add(img);
+ stack.push(current);
+ } catch (EmptyStackException ese) {
+ document.add(img);
+ }
+ while (!newStack.empty()) {
+ stack.push(newStack.pop());
+ }
+ return;
+ }
+ } catch (EmptyStackException ese) {
+ // if there is no element on the stack, the Image is added
+ // to the document
+ try {
+ document.add(img);
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ return;
+ }
+ } catch (Exception e) {
+ throw new ExceptionConverter(e);
+ }
+ }
+
+ // annotations
+ if (Annotation.isTag(name)) {
+ Annotation annotation = new Annotation(attributes);
+ TextElementArray current;
+ try {
+ try {
+ current = (TextElementArray) stack.pop();
+ try {
+ current.add(annotation);
+ } catch (Exception e) {
+ document.add(annotation);
+ }
+ stack.push(current);
+ } catch (EmptyStackException ese) {
+ document.add(annotation);
+ }
+ return;
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+ // newlines
+ if (isNewline(name)) {
+ TextElementArray current;
+ try {
+ current = (TextElementArray) stack.pop();
+ current.add(Chunk.NEWLINE);
+ stack.push(current);
+ } catch (EmptyStackException ese) {
+ if (currentChunk == null) {
+ try {
+ document.add(Chunk.NEWLINE);
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ } else {
+ currentChunk.append("\n");
+ }
+ }
+ return;
+ }
+
+ // newpage
+ if (isNewpage(name)) {
+ TextElementArray current;
+ try {
+ current = (TextElementArray) stack.pop();
+ Chunk newPage = new Chunk("");
+ newPage.setNewPage();
+ if (bf != null) {
+ newPage.setFont(new Font(this.bf));
+ }
+ current.add(newPage);
+ stack.push(current);
+ } catch (EmptyStackException ese) {
+ try {
+ document.newPage();
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+ return;
+ }
+
+ // newpage
+ if (ElementTags.HORIZONTALRULE.equals(name)) {
+ TextElementArray current;
+ Graphic hr = new Graphic();
+ hr.setHorizontalLine(1.0f, 100.0f);
+ try {
+ current = (TextElementArray) stack.pop();
+ current.add(hr);
+ stack.push(current);
+ } catch (EmptyStackException ese) {
+ try {
+ document.add(hr);
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+ return;
+ }
+
+ // documentroot
+ if (isDocumentRoot(name)) {
+ String key;
+ String value;
+ // pagesize and orientation specific code suggested by Samuel Gabriel
+ // Updated by Ricardo Coutinho. Only use if set in html!
+ Rectangle pageSize = null;
+ String orientation = null;
+ for (Iterator i = attributes.keySet().iterator(); i.hasNext();) {
+ key = (String) i.next();
+ value = attributes.getProperty(key);
+ try {
+ // margin specific code suggested by Reza Nasiri
+ if (ElementTags.LEFT.equalsIgnoreCase(key))
+ leftMargin = Float.valueOf(value + "f").floatValue();
+ if (ElementTags.RIGHT.equalsIgnoreCase(key))
+ rightMargin = Float.valueOf(value + "f").floatValue();
+ if (ElementTags.TOP.equalsIgnoreCase(key))
+ topMargin = Float.valueOf(value + "f").floatValue();
+ if (ElementTags.BOTTOM.equalsIgnoreCase(key))
+ bottomMargin = Float.valueOf(value + "f").floatValue();
+ } catch (Exception ex) {
+ throw new ExceptionConverter(ex);
+ }
+ if (ElementTags.PAGE_SIZE.equals(key)) {
+ try {
+ String pageSizeName = value;
+ Field pageSizeField = PageSize.class
+ .getField(pageSizeName);
+ pageSize = (Rectangle) pageSizeField.get(null);
+ } catch (Exception ex) {
+ throw new ExceptionConverter(ex);
+ }
+ } else if (ElementTags.ORIENTATION.equals(key)) {
+ try {
+ String pageSizeName = value;
+ if ("landscape".equals(value)) {
+ orientation = "landscape";
+ }
+ } catch (Exception ex) {
+ throw new ExceptionConverter(ex);
+ }
+ } else {
+ try {
+ document.add(new Meta(key, value));
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+ }
+ if(pageSize != null) {
+ if ("landscape".equals(orientation)) {
+ pageSize = pageSize.rotate();
+ }
+ document.setPageSize(pageSize);
+ }
+ document.setMargins(leftMargin, rightMargin, topMargin,
+ bottomMargin);
+
+ if (controlOpenClose)
+ document.open();
+ }
+
+ }
+
+ /**
+ * This method gets called when ignorable white space encountered.
+ *
+ * @param ch
+ * an array of characters
+ * @param start
+ * the start position in the array
+ * @param length
+ * the number of characters to read from the array
+ */
+
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ // do nothing: we handle white space ourselves in the characters method
+ }
+
+ /**
+ * This method gets called when characters are encountered.
+ *
+ * @param ch
+ * an array of characters
+ * @param start
+ * the start position in the array
+ * @param length
+ * the number of characters to read from the array
+ */
+
+ public void characters(char[] ch, int start, int length) {
+
+ if (ignore)
+ return;
+
+ String content = new String(ch, start, length);
+ // System.err.println("'" + content + "'");
+
+ if (content.trim().length() == 0) {
+ return;
+ }
+
+ StringBuffer buf = new StringBuffer();
+ int len = content.length();
+ char character;
+ boolean newline = false;
+ for (int i = 0; i < len; i++) {
+ switch (character = content.charAt(i)) {
+ case ' ':
+ if (!newline) {
+ buf.append(character);
+ }
+ break;
+ case '\n':
+ if (i > 0) {
+ newline = true;
+ buf.append(' ');
+ }
+ break;
+ case '\r':
+ break;
+ case '\t':
+ break;
+ default:
+ newline = false;
+ buf.append(character);
+ }
+ }
+ if (currentChunk == null) {
+ if (bf == null) {
+ currentChunk = new Chunk(buf.toString());
+ }
+ else {
+ currentChunk = new Chunk(buf.toString(), new Font(this.bf));
+ }
+ } else {
+ currentChunk.append(buf.toString());
+ }
+ }
+
+ private BaseFont bf = null;
+
+ /**
+ * Sets the font that has to be used.
+ * @param bf
+ */
+ public void setBaseFont(BaseFont bf) {
+ this.bf = bf;
+ }
+
+ /**
+ * This method gets called when an end tag is encountered.
+ *
+ * @param uri
+ * the Uniform Resource Identifier
+ * @param lname
+ * the local name (without prefix), or the empty string if
+ * Namespace processing is not being performed.
+ * @param name
+ * the name of the tag that ends
+ */
+
+ public void endElement(String uri, String lname, String name) {
+ handleEndingTags(name);
+ }
+
+ /**
+ * This method deals with the starting tags.
+ *
+ * @param name
+ * the name of the tag
+ */
+
+ public void handleEndingTags(String name) {
+
+ // System.err.println("Stop: " + name);
+
+ if (ElementTags.IGNORE.equals(name)) {
+ ignore = false;
+ return;
+ }
+ if (ignore)
+ return;
+ // tags that don't have any content
+ if (isNewpage(name) || Annotation.isTag(name) || Image.isTag(name)
+ || isNewline(name)) {
+ return;
+ }
+
+ try {
+ // titles of sections and chapters
+ if (Section.isTitle(name)) {
+ Paragraph current = (Paragraph) stack.pop();
+ if (currentChunk != null) {
+ current.add(currentChunk);
+ currentChunk = null;
+ }
+ Section previous = (Section) stack.pop();
+ previous.setTitle(current);
+ stack.push(previous);
+ return;
+ }
+
+ // all other endtags
+ if (currentChunk != null) {
+ TextElementArray current;
+ try {
+ current = (TextElementArray) stack.pop();
+ } catch (EmptyStackException ese) {
+ current = new Paragraph();
+ }
+ current.add(currentChunk);
+ stack.push(current);
+ currentChunk = null;
+ }
+
+ // chunks
+ if (Chunk.isTag(name)) {
+ return;
+ }
+
+ // phrases, anchors, lists, tables
+ if (Phrase.isTag(name) || Anchor.isTag(name) || List.isTag(name)
+ || Paragraph.isTag(name)) {
+ Element current = (Element) stack.pop();
+ try {
+ TextElementArray previous = (TextElementArray) stack.pop();
+ previous.add(current);
+ stack.push(previous);
+ } catch (EmptyStackException ese) {
+ document.add(current);
+ }
+ return;
+ }
+
+ // listitems
+ if (ListItem.isTag(name)) {
+ ListItem listItem = (ListItem) stack.pop();
+ List list = (List) stack.pop();
+ list.add(listItem);
+ stack.push(list);
+ }
+
+ // tables
+ if (Table.isTag(name)) {
+ Table table = (Table) stack.pop();
+ try {
+ TextElementArray previous = (TextElementArray) stack.pop();
+ previous.add(table);
+ stack.push(previous);
+ } catch (EmptyStackException ese) {
+ document.add(table);
+ }
+ return;
+ }
+
+ // rows
+ if (Row.isTag(name)) {
+ ArrayList cells = new ArrayList();
+ int columns = 0;
+ Table table;
+ Cell cell;
+ while (true) {
+ Element element = (Element) stack.pop();
+ if (element.type() == Element.CELL) {
+ cell = (Cell) element;
+ columns += cell.colspan();
+ cells.add(cell);
+ } else {
+ table = (Table) element;
+ break;
+ }
+ }
+ if (table.columns() < columns) {
+ table.addColumns(columns - table.columns());
+ }
+ Collections.reverse(cells);
+ String width;
+ float[] cellWidths = new float[columns];
+ boolean[] cellNulls = new boolean[columns];
+ for (int i = 0; i < columns; i++) {
+ cellWidths[i] = 0;
+ cellNulls[i] = true;
+ }
+ float total = 0;
+ int j = 0;
+ for (Iterator i = cells.iterator(); i.hasNext();) {
+ cell = (Cell) i.next();
+ if ((width = cell.cellWidth()) == null) {
+ if (cell.colspan() == 1 && cellWidths[j] == 0) {
+ try {
+ cellWidths[j] = 100f / columns;
+ total += cellWidths[j];
+ } catch (Exception e) {
+ // empty on purpose
+ }
+ } else if (cell.colspan() == 1) {
+ cellNulls[j] = false;
+ }
+ } else if (cell.colspan() == 1 && width.endsWith("%")) {
+ try {
+ cellWidths[j] = Float.valueOf(
+ width.substring(0, width.length() - 1)
+ + "f").floatValue();
+ total += cellWidths[j];
+ } catch (Exception e) {
+ // empty on purpose
+ }
+ }
+ j += cell.colspan();
+ table.addCell(cell);
+ }
+ float widths[] = table.getProportionalWidths();
+ if (widths.length == columns) {
+ float left = 0.0f;
+ for (int i = 0; i < columns; i++) {
+ if (cellNulls[i] && widths[i] != 0) {
+ left += widths[i];
+ cellWidths[i] = widths[i];
+ }
+ }
+ if (100.0 >= total) {
+ for (int i = 0; i < widths.length; i++) {
+ if (cellWidths[i] == 0 && widths[i] != 0) {
+ cellWidths[i] = (widths[i] / left)
+ * (100.0f - total);
+ }
+ }
+ }
+ table.setWidths(cellWidths);
+ }
+ stack.push(table);
+ }
+
+ // cells
+ if (Cell.isTag(name)) {
+ return;
+ }
+
+ // sections
+ if (Section.isTag(name)) {
+ stack.pop();
+ return;
+ }
+
+ // chapters
+ if (Chapter.isTag(name)) {
+ document.add((Element) stack.pop());
+ return;
+ }
+
+ // the documentroot
+ if (isDocumentRoot(name)) {
+ try {
+ while (true) {
+ Element element = (Element) stack.pop();
+ try {
+ TextElementArray previous = (TextElementArray) stack
+ .pop();
+ previous.add(element);
+ stack.push(previous);
+ } catch (EmptyStackException es) {
+ document.add(element);
+ }
+ }
+ } catch (EmptyStackException ese) {
+ // empty on purpose
+ }
+ if (controlOpenClose)
+ document.close();
+ return;
+ }
+ } catch (DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+ /**
+ * Checks if a certain tag corresponds with the newpage-tag.
+ *
+ * @param tag
+ * a presumed tagname
+ * @return <CODE>true</CODE> or <CODE>false</CODE>
+ */
+
+ private boolean isNewpage(String tag) {
+ return ElementTags.NEWPAGE.equals(tag);
+ }
+
+ /**
+ * Checks if a certain tag corresponds with the newpage-tag.
+ *
+ * @param tag
+ * a presumed tagname
+ * @return <CODE>true</CODE> or <CODE>false</CODE>
+ */
+
+ private boolean isNewline(String tag) {
+ return ElementTags.NEWLINE.equals(tag);
+ }
+
+ /**
+ * Checks if a certain tag corresponds with the roottag.
+ *
+ * @param tag
+ * a presumed tagname
+ * @return <CODE>true</CODE> if <VAR>tag </VAR> equals <CODE>itext
+ * </CODE>,<CODE>false</CODE> otherwise.
+ */
+
+ protected boolean isDocumentRoot(String tag) {
+ return ElementTags.ITEXT.equals(tag);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/xml/SAXmyHandler.java b/src/main/java/com/lowagie/text/xml/SAXmyHandler.java
new file mode 100644
index 0000000..acfaa83
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/SAXmyHandler.java
@@ -0,0 +1,128 @@
+/*
+ * $Id: SAXmyHandler.java,v 1.12 2005/11/29 16:00:17 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.xml.sax.Attributes;
+
+import com.lowagie.text.*;
+
+/**
+ * The <CODE>Tags</CODE>-class maps several XHTML-tags to iText-objects.
+ */
+
+public class SAXmyHandler extends SAXiTextHandler {
+
+/** This hashmap contains all the custom keys and peers. */
+ protected HashMap myTags;
+
+/**
+ * Constructs a new SAXiTextHandler that will translate all the events
+ * triggered by the parser to actions on the <CODE>Document</CODE>-object.
+ *
+ * @param document this is the document on which events must be triggered
+ * @param myTags a userdefined tagmap
+ * @throws IOException
+ * @throws DocumentException
+ */
+
+ public SAXmyHandler(DocListener document, HashMap myTags) throws DocumentException, IOException {
+ super(document);
+ this.myTags = myTags;
+ }
+
+/**
+ * This method gets called when a start tag is encountered.
+ *
+ * @param uri the Uniform Resource Identifier
+ * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed.
+ * @param name the name of the tag that is encountered
+ * @param attrs the list of attributes
+ */
+
+ public void startElement(String uri, String lname, String name, Attributes attrs) {
+ if (myTags.containsKey(name)) {
+ XmlPeer peer = (XmlPeer) myTags.get(name);
+ handleStartingTags(peer.getTag(), peer.getAttributes(attrs));
+ }
+ else {
+ Properties attributes = new Properties();
+ if (attrs != null) {
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attribute = attrs.getQName(i);
+ attributes.setProperty(attribute, attrs.getValue(i));
+ }
+ }
+ handleStartingTags(name, attributes);
+ }
+ }
+
+ /**
+ * This method gets called when an end tag is encountered.
+ *
+ * @param uri the Uniform Resource Identifier
+ * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed.
+ * @param name the name of the tag that ends
+ */
+
+ public void endElement(String uri, String lname, String name) {
+ if (myTags.containsKey(name)) {
+ XmlPeer peer = (XmlPeer) myTags.get(name);
+ handleEndingTags(peer.getTag());
+ }
+ else {
+ handleEndingTags(name);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/xml/TagMap.java b/src/main/java/com/lowagie/text/xml/TagMap.java
new file mode 100644
index 0000000..9eb0cb4
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/TagMap.java
@@ -0,0 +1,213 @@
+/*
+ * $Id: TagMap.java,v 1.10 2004/12/14 11:25:42 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+import java.util.HashMap;
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import java.io.InputStream;
+import org.xml.sax.InputSource;
+
+import com.lowagie.text.*;
+
+/**
+ * The <CODE>Tags</CODE>-class maps several XHTML-tags to iText-objects.
+ */
+
+public class TagMap extends HashMap {
+
+ class AttributeHandler extends DefaultHandler {
+
+/** This is a tag */
+ public static final String TAG = "tag";
+
+/** This is a tag */
+ public static final String ATTRIBUTE = "attribute";
+
+/** This is an attribute */
+ public static final String NAME = "name";
+
+/** This is an attribute */
+ public static final String ALIAS = "alias";
+
+/** This is an attribute */
+ public static final String VALUE = "value";
+
+/** This is an attribute */
+ public static final String CONTENT = "content";
+
+/** This is the tagmap using the AttributeHandler */
+ private HashMap tagMap;
+
+/** This is the current peer. */
+ private XmlPeer currentPeer;
+
+/**
+ * Constructs a new SAXiTextHandler that will translate all the events
+ * triggered by the parser to actions on the <CODE>Document</CODE>-object.
+ *
+ * @param tagMap A Hashmap containing XmlPeer-objects
+ */
+
+ public AttributeHandler(HashMap tagMap) {
+ super();
+ this.tagMap = tagMap;
+ }
+
+/**
+ * This method gets called when a start tag is encountered.
+ *
+ * @param uri the Uniform Resource Identifier
+ * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed.
+ * @param tag the name of the tag that is encountered
+ * @param attrs the list of attributes
+ */
+
+ public void startElement(String uri, String lname, String tag, Attributes attrs) {
+ String name = attrs.getValue(NAME);
+ String alias = attrs.getValue(ALIAS);
+ String value = attrs.getValue(VALUE);
+ if (name != null) {
+ if(TAG.equals(tag)) {
+ currentPeer = new XmlPeer(name, alias);
+ }
+ else if (ATTRIBUTE.equals(tag)) {
+ if (alias != null) {
+ currentPeer.addAlias(name, alias);
+ }
+ if (value != null) {
+ currentPeer.addValue(name, value);
+ }
+ }
+ }
+ value = attrs.getValue(CONTENT);
+ if (value != null) {
+ currentPeer.setContent(value);
+ }
+ }
+
+/**
+ * This method gets called when ignorable white space encountered.
+ *
+ * @param ch an array of characters
+ * @param start the start position in the array
+ * @param length the number of characters to read from the array
+ */
+
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ // do nothing
+ }
+
+/**
+ * This method gets called when characters are encountered.
+ *
+ * @param ch an array of characters
+ * @param start the start position in the array
+ * @param length the number of characters to read from the array
+ */
+
+ public void characters(char[] ch, int start, int length) {
+ // do nothing
+ }
+
+/**
+ * This method gets called when an end tag is encountered.
+ *
+ * @param uri the Uniform Resource Identifier
+ * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed.
+ * @param tag the name of the tag that ends
+ */
+
+ public void endElement(String uri, String lname, String tag) {
+ if (TAG.equals(tag))
+ tagMap.put(currentPeer.getAlias(), currentPeer);
+ }
+ }
+
+ /**
+ * Constructs a TagMap
+ * @param tagfile the path to an XML file with the tagmap
+ */
+ public TagMap(String tagfile) {
+ super();
+ try {
+ init(TagMap.class.getClassLoader().getResourceAsStream(tagfile));
+ }catch(Exception e) {
+ throw new ExceptionConverter(e);
+ }
+ }
+
+ /**
+ * Constructs a TagMap.
+ * @param in An InputStream with the tagmap xml
+ */
+ public TagMap(InputStream in) {
+ super();
+ init(in);
+ }
+
+ protected void init(InputStream in) {
+ try {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ parser.parse(new InputSource(in), new AttributeHandler(this));
+ }
+ catch(Exception e) {
+ throw new ExceptionConverter(e);
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/lowagie/text/xml/XmlParser.java b/src/main/java/com/lowagie/text/xml/XmlParser.java
new file mode 100644
index 0000000..adc2695
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlParser.java
@@ -0,0 +1,379 @@
+/*
+ * $Id: XmlParser.java,v 1.16 2005/12/06 10:23:08 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.HashMap;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.lowagie.text.DocListener;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.ExceptionConverter;
+
+/**
+ * This class can be used to parse an XML file.
+ */
+
+public class XmlParser {
+
+/** This is the instance of the parser. */
+ protected SAXParser parser;
+
+/**
+ * Constructs an XmlParser.
+ */
+
+ public XmlParser() {
+ try {
+ parser = SAXParserFactory.newInstance().newSAXParser();
+ }
+ catch(ParserConfigurationException pce) {
+ throw new ExceptionConverter(pce);
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ }
+
+/**
+ * Parses a given file.
+ * @param document The document that will listen to the parser
+ * @param is The InputStream with the contents
+ */
+
+ public void go(DocListener document, InputSource is) {
+ try {
+ parser.parse(is, new SAXiTextHandler(document));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ }
+
+/**
+ * Parses a given file.
+ * @param document The document that will listen to the parser
+ * @param is The inputsource with the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public void go(DocListener document, InputSource is, String tagmap) {
+ try {
+ parser.parse(is, new SAXmyHandler(document, new TagMap(tagmap)));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ catch(DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+ /**
+ * Parses a given file.
+ * @param document The document that will listen to the parser
+ * @param is the inputsource with the content
+ * @param tagmap an inputstream to a userdefined tagmap
+ */
+
+ public void go(DocListener document, InputSource is, InputStream tagmap) {
+ try {
+ parser.parse(is, new SAXmyHandler(document, new TagMap(tagmap)));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ catch(DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+/**
+ * Parses a given file.
+ * @param document The document that will listen to the parser
+ * @param is the inputsource with the content
+ * @param tagmap a userdefined tagmap
+ */
+
+ public void go(DocListener document, InputSource is, HashMap tagmap) {
+ try {
+ parser.parse(is, new SAXmyHandler(document, tagmap));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ catch(DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+/**
+ * Parses a given file.
+ * @param document The document that will listen to the parser
+ * @param file The path to a file with the content
+ */
+
+ public void go(DocListener document, String file) {
+ try {
+ parser.parse(file, new SAXiTextHandler(document));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ }
+
+/**
+ * Parses a given file.
+ * @param document the document that will listen to the parser
+ * @param file the path to a file with the content
+ * @param tagmap a userdefined tagmap
+ */
+
+ public void go(DocListener document, String file, String tagmap) {
+ try {
+ parser.parse(file, new SAXmyHandler(document, new TagMap(tagmap)));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ catch(DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+/**
+ * Parses a given file.
+ * @param document The document that will listen to the parser
+ * @param file the path to a file with the content
+ * @param tagmap a userdefined tagmap
+ */
+
+ public void go(DocListener document, String file, HashMap tagmap) {
+ try {
+ parser.parse(file, new SAXmyHandler(document, tagmap));
+ }
+ catch(SAXException se) {
+ throw new ExceptionConverter(se);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ catch(DocumentException de) {
+ throw new ExceptionConverter(de);
+ }
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param is the inputsource with the content
+ */
+
+ public static void parse(DocListener document, InputSource is) {
+ XmlParser p = new XmlParser();
+ p.go(document, is);
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param is The inputsource with the content
+ * @param tagmap a userdefined tagmap
+ */
+
+ public static void parse(DocListener document, InputSource is, String tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, is, tagmap);
+ }
+
+/**
+ * Parses a given file and writes the content to a document, using a certain tagmap.
+ * @param document The document that will listen to the parser
+ * @param is The inputsource with the content
+ * @param tagmap a userdefined tagmap
+ */
+
+ public static void parse(DocListener document, InputSource is, HashMap tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, is, tagmap);
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param file The path to a file with the content
+ */
+
+ public static void parse(DocListener document, String file) {
+ XmlParser p = new XmlParser();
+ p.go(document, file);
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param file The path to a file with the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public static void parse(DocListener document, String file, String tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, file, tagmap);
+ }
+
+/**
+ * Parses a given file and writes the content to a document, using a certain tagmap.
+ * @param document The document that will listen to the parser
+ * @param file The path to a file with the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public static void parse(DocListener document, String file, HashMap tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, file, tagmap);
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param is The inputsource with the content
+ */
+
+ public static void parse(DocListener document, InputStream is) {
+ XmlParser p = new XmlParser();
+ p.go(document, new InputSource(is));
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param is The inputstream with the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public static void parse(DocListener document, InputStream is, String tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, new InputSource(is), tagmap);
+ }
+
+/**
+ * Parses a given file and writes the content to a document, using a certain tagmap.
+ * @param document The document that will listen to the parser
+ * @param is The InputStream with the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public static void parse(DocListener document, InputStream is, HashMap tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, new InputSource(is), tagmap);
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param is The reader that reads the content
+ */
+
+ public static void parse(DocListener document, Reader is) {
+ XmlParser p = new XmlParser();
+ p.go(document, new InputSource(is));
+ }
+
+/**
+ * Parses a given file that validates with the iText DTD and writes the content to a document.
+ * @param document The document that will listen to the parser
+ * @param is The reader that reads the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public static void parse(DocListener document, Reader is, String tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, new InputSource(is), tagmap);
+ }
+
+/**
+ * Parses a given file and writes the content to a document, using a certain tagmap.
+ * @param document The document that will listen to the parser
+ * @param is The reader that reads the content
+ * @param tagmap A userdefined tagmap
+ */
+
+ public static void parse(DocListener document, Reader is, HashMap tagmap) {
+ XmlParser p = new XmlParser();
+ p.go(document, new InputSource(is), tagmap);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/xml/XmlPeer.java b/src/main/java/com/lowagie/text/xml/XmlPeer.java
new file mode 100644
index 0000000..5ca16a5
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlPeer.java
@@ -0,0 +1,182 @@
+/*
+ * $Id: XmlPeer.java,v 1.13 2004/12/14 11:25:42 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+import java.util.Properties;
+import org.xml.sax.Attributes;
+
+import com.lowagie.text.ElementTags;
+
+/**
+ * This interface is implemented by the peer of all the iText objects.
+ */
+
+public class XmlPeer {
+
+/** This is the name of the alias. */
+ protected String tagname;
+
+/** This is the name of the alias. */
+ protected String customTagname;
+
+/** This is the Map that contains the aliases of the attributes. */
+ protected Properties attributeAliases = new Properties();
+
+/** This is the Map that contains the default values of the attributes. */
+ protected Properties attributeValues = new Properties();
+
+/** This is String that contains the default content of the attributes. */
+ protected String defaultContent = null;
+
+/**
+ * Creates a XmlPeer.
+ * @param name the iText name of a tag
+ * @param alias the userdefined name of a tag
+ */
+
+ public XmlPeer(String name, String alias) {
+ this.tagname = name;
+ this.customTagname = alias;
+ }
+
+/**
+ * Gets the tagname of the peer.
+ * @return the iText name of a tag
+ */
+
+ public String getTag() {
+ return tagname;
+ }
+
+/**
+ * Gets the tagname of the peer.
+ * @return the userdefined tagname
+ */
+
+ public String getAlias() {
+ return customTagname;
+ }
+
+/** Gets the list of attributes of the peer.
+ * @param attrs the userdefined set of attributes
+ * @return the set of attributes translated to iText attributes
+ */
+ public Properties getAttributes(Attributes attrs) {
+ Properties attributes = new Properties();
+ attributes.putAll(attributeValues);
+ if (defaultContent != null) {
+ attributes.put(ElementTags.ITEXT, defaultContent);
+ }
+ if (attrs != null) {
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attribute = getName(attrs.getQName(i));
+ attributes.setProperty(attribute, attrs.getValue(i));
+ }
+ }
+ return attributes;
+ }
+
+/**
+ * Sets an alias for an attribute.
+ *
+ * @param name the iText tagname
+ * @param alias the custom tagname
+ */
+
+ public void addAlias(String name, String alias) {
+ attributeAliases.put(alias, name);
+ }
+
+/**
+ * Sets a value for an attribute.
+ *
+ * @param name the iText tagname
+ * @param value the default value for this tag
+ */
+
+ public void addValue(String name, String value) {
+ attributeValues.put(name, value);
+ }
+
+/**
+ * Sets the default content.
+ *
+ * @param content the default content
+ */
+
+ public void setContent(String content) {
+ this.defaultContent = content;
+ }
+
+/**
+ * Returns the iText attribute name.
+ *
+ * @param name the custom attribute name
+ * @return iText translated attribute name
+ */
+
+ public String getName(String name) {
+ String value;
+ if ((value = attributeAliases.getProperty(name)) != null) {
+ return value;
+ }
+ return name;
+ }
+
+/**
+ * Returns the default values.
+ * @return A set of default (userdefined) values
+ */
+
+ public Properties getDefaultValues() {
+ return attributeValues;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/xml/XmlToHtml.java b/src/main/java/com/lowagie/text/xml/XmlToHtml.java
new file mode 100644
index 0000000..e145e57
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlToHtml.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.html.HtmlWriter;
+
+
+/**
+ * HTML-specific subclass of <code>XmlToXXX</code>.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public class XmlToHtml
+ extends XmlToXXX
+{
+
+/**
+ * Construct an <CODE>XmlToHtml</CODE> with the default page size.
+ */
+ public XmlToHtml()
+ {
+ super();
+ }//end default constructor
+
+
+/**
+ * Construct an <CODE>XmlToHtml</CODE> with the specified page size.
+ * @param pageSize <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+ public XmlToHtml(String pageSize)
+ {
+ super(pageSize);
+ }//end constructor(String)
+
+
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream where the HTML will be sent to
+ * @throws DocumentException if document errors occur.
+ */
+ protected final void addWriter(Document doc, OutputStream out)
+ throws DocumentException
+ {
+ HtmlWriter.getInstance(doc, out);
+ }//end addWriter
+
+
+/**
+ * Main method of the <CODE>XmlToHtml</CODE> class.
+ * @param args <CODE>String[]</CODE> of command-line arguments.
+ */
+ public static void main(String[] args)
+ {
+ int code = 0;
+
+ if (args.length > 1)
+ {
+ try
+ {
+ XmlToHtml x;
+ if (args.length > 2)
+ {
+ x = new XmlToHtml(args[2]);
+ }//end if at least 3 args
+ else
+ {
+ x = new XmlToHtml();
+ }//end else, only 2 args
+
+ x.parse(new FileInputStream(args[0]), new FileOutputStream(args[1]));
+ }//end try to do everything
+ catch (Exception ex)
+ {
+ code = 2;
+ ex.printStackTrace(System.err);
+ }//end catch Exception
+ }//end if at least 2 args
+ else
+ {
+ code = 1;
+ System.err.println(
+ "Usage: XmlToHtml [XML file in] [PDF file out] [optional page size]");
+ }//end else, not enough arguments
+
+ System.exit(code);
+ }//end main
+
+}//end class XmlToHtml
diff --git a/src/main/java/com/lowagie/text/xml/XmlToPdf.java b/src/main/java/com/lowagie/text/xml/XmlToPdf.java
new file mode 100644
index 0000000..3965831
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlToPdf.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.pdf.PdfWriter;
+
+
+/**
+ * PDF-specific subclass of <code>XmlToXXX</code>.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public class XmlToPdf
+ extends XmlToXXX
+{
+
+/**
+ * Construct an <CODE>XmlToPdf</CODE> with the default page size.
+ */
+ public XmlToPdf()
+ {
+ super();
+ }//end default constructor
+
+
+/**
+ * Construct an <CODE>XmlToPdf</CODE> with the specified page size.
+ * @param pageSize <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+ public XmlToPdf(String pageSize)
+ {
+ super(pageSize);
+ }//end constructor(String)
+
+
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream to which the PDF will be sent
+ * @throws DocumentException if document errors occur.
+ */
+ protected final void addWriter(Document doc, OutputStream out)
+ throws DocumentException
+ {
+ PdfWriter.getInstance(doc, out);
+ }//end addWriter
+
+
+/**
+ * Main method of the <CODE>XmlToPdf</CODE> class.
+ * @param args <CODE>String[]</CODE> of command-line arguments.
+ */
+ public static void main(String[] args)
+ {
+ int code = 0;
+
+ if (args.length > 1)
+ {
+ try
+ {
+ XmlToPdf x;
+ if (args.length > 2)
+ {
+ x = new XmlToPdf(args[2]);
+ }//end if at least 3 args
+ else
+ {
+ x = new XmlToPdf();
+ }//end else, only 2 args
+
+ x.parse(new FileInputStream(args[0]), new FileOutputStream(args[1]));
+ }//end try to do everything
+ catch (Exception ex)
+ {
+ code = 2;
+ ex.printStackTrace(System.err);
+ }//end catch Exception
+ }//end if at least 2 args
+ else
+ {
+ code = 1;
+ System.err.println(
+ "Usage: XmlToPdf [XML file in] [PDF file out] [optional page size]");
+ }//end else, not enough arguments
+
+ System.exit(code);
+ }//end main
+
+}//end class XmlToPdf
diff --git a/src/main/java/com/lowagie/text/xml/XmlToRtf.java b/src/main/java/com/lowagie/text/xml/XmlToRtf.java
new file mode 100644
index 0000000..d83b4b6
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlToRtf.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.rtf.RtfWriter;
+
+
+/**
+ * RTF-specific subclass of <code>XmlToXXX</code>.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public class XmlToRtf
+ extends XmlToXXX
+{
+
+/**
+ * Construct an <CODE>XmlToRtf</CODE> with the default page size.
+ */
+ public XmlToRtf()
+ {
+ super();
+ }//end default constructor
+
+
+/**
+ * Construct an <CODE>XmlToRtf</CODE> with the specified page size.
+ * @param pageSize <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+ public XmlToRtf(String pageSize)
+ {
+ super(pageSize);
+ }//end constructor(String)
+
+
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream to which RTF will be sent
+ * @throws DocumentException if document errors occur.
+ */
+ protected final void addWriter(Document doc, OutputStream out)
+ throws DocumentException
+ {
+ RtfWriter.getInstance(doc, out);
+ }//end addWriter
+
+
+/**
+ * Main method of the <CODE>XmlToRtf</CODE> class.
+ * @param args <CODE>String[]</CODE> of command-line arguments.
+ */
+ public static void main(String[] args)
+ {
+ int code = 0;
+
+ if (args.length > 1)
+ {
+ try
+ {
+ XmlToRtf x;
+ if (args.length > 2)
+ {
+ x = new XmlToRtf(args[2]);
+ }//end if at least 3 args
+ else
+ {
+ x = new XmlToRtf();
+ }//end else, only 2 args
+
+ x.parse(new FileInputStream(args[0]), new FileOutputStream(args[1]));
+ }//end try to do everything
+ catch (Exception ex)
+ {
+ code = 2;
+ ex.printStackTrace(System.err);
+ }//end catch Exception
+ }//end if at least 2 args
+ else
+ {
+ code = 1;
+ System.err.println(
+ "Usage: XmlToRtf [XML file in] [PDF file out] [optional page size]");
+ }//end else, not enough arguments
+
+ System.exit(code);
+ }//end main
+
+}//end class XmlToRtf
diff --git a/src/main/java/com/lowagie/text/xml/XmlToXXX.java b/src/main/java/com/lowagie/text/xml/XmlToXXX.java
new file mode 100644
index 0000000..016efdd
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlToXXX.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.PageSize;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.DocumentException;
+
+
+/**
+ * Generates an specific file from an iText XML file.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public abstract class XmlToXXX
+{
+
+ protected Rectangle pageSize;
+
+
+/**
+ * Construct an <CODE>XmlToXXX</CODE> with the default page size.
+ */
+ public XmlToXXX()
+ {
+ this(PageSize.LETTER);
+ }//end default constructor
+
+
+/**
+ * Construct an <CODE>XmlToXXX</CODE> with the specified page size.
+ * @param pageSize <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+ public XmlToXXX(String pageSize)
+ {
+ this(getPageSize(pageSize));
+ }//end constructor(String)
+
+
+ private XmlToXXX(Rectangle pageSize)
+ {
+ this.pageSize = pageSize;
+ }//end constructor(Rectangle)
+
+
+/**
+ * Parse the XML from the specified <CODE>InputStream</CODE>, writing to the
+ * specified <CODE>OutputStream</CODE>.
+ * @param in the <CODE>InputStream</CODE> from which the XML is read.
+ * @param out the <CODE>OutputStream</CODE> to which the result is written.
+ * @throws DocumentException if document errors occur.
+ */
+ public final void parse(InputStream in, OutputStream out)
+ throws DocumentException
+ {
+ Document doc = new Document(pageSize);
+
+ addWriter(doc, out);
+ XmlParser.parse(doc, in);
+ }//end parse
+
+
+ private static Rectangle getPageSize(String pageSize)
+ {
+ Rectangle result = PageSize.LETTER;
+ Field fld = null;
+ try
+ {
+ fld = PageSize.class.getDeclaredField(pageSize.toUpperCase());
+ result = (fld != null
+ && Modifier.isStatic(fld.getModifiers())
+ && fld.getType().equals(Rectangle.class)) ? (Rectangle)(fld.get(null))
+ : result;
+ }//end try to get field
+ catch (Exception ex)
+ {
+ System.err.println(ex.getMessage());
+ }//end catch Exception
+ return result;
+ }//end getPageSize
+
+
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream to which the document will be sent
+ * @throws DocumentException if document errors occur.
+ */
+ protected abstract void addWriter(Document doc, OutputStream out)
+ throws DocumentException;
+
+}//end class XmlToXXX
diff --git a/src/main/java/com/lowagie/text/xml/XmlWriter.java b/src/main/java/com/lowagie/text/xml/XmlWriter.java
new file mode 100644
index 0000000..ac3f2d8
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/XmlWriter.java
@@ -0,0 +1,893 @@
+/*
+ * $Id: XmlWriter.java,v 1.35 2005/12/09 12:33:25 psoares33 Exp $
+ * $Name: $
+ *
+ * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.TreeMap;
+import java.util.HashMap;
+
+import com.lowagie.text.*;
+import com.lowagie.text.markup.MarkupTags;
+
+/**
+ * A <CODE>DocWriter</CODE> class for XML (Remark: this class is not finished yet!).
+ * <P>
+ * An <CODE>XmlWriter</CODE> can be added as a <CODE>DocListener</CODE>
+ * to a certain <CODE>Document</CODE> by getting an instance.
+ * Every <CODE>Element</CODE> added to the original <CODE>Document</CODE>
+ * will be written to the <CODE>OutputStream</CODE> of this <CODE>XmlWriter</CODE>.
+ * <P>
+ * Example:
+ * <BLOCKQUOTE><PRE>
+ * // creation of the document with a certain size and certain margins
+ * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ * try {
+ * // this will write XML to the Standard OutputStream
+ * <STRONG>XmlWriter.getInstance(document, System.out);</STRONG>
+ * // this will write XML to a file called text.html
+ * <STRONG>XmlWriter.getInstance(document, new FileOutputStream("text.xml"));</STRONG>
+ * // this will write XML to for instance the OutputStream of a HttpServletResponse-object
+ * <STRONG>XmlWriter.getInstance(document, response.getOutputStream());</STRONG>
+ * }
+ * catch(DocumentException de) {
+ * System.err.println(de.getMessage());
+ * }
+ * // this will close the document and all the OutputStreams listening to it
+ * <STRONG>document.close();</CODE>
+ * </PRE></BLOCKQUOTE>
+ */
+
+public class XmlWriter extends DocWriter implements DocListener {
+
+ // static membervariables (tags)
+
+/** This is the first line of the XML page. */
+ public static final byte[] PROLOG = getISOBytes("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+
+/** This is the reference to the DTD. */
+ public static final byte[] DOCTYPE = getISOBytes("<!DOCTYPE ITEXT SYSTEM \"");
+
+/** This is the place where the DTD is located. */
+ public final static byte[] DTD = getISOBytes("http://itext.sourceforge.net/itext.dtd");
+
+/** This is an array containing character to XML translations. */
+ private static final String[] xmlCode = new String[256];
+
+ static {
+ for (int i = 0; i < 10; i++) {
+ xmlCode[i] = "&#00" + i + ";";
+ }
+
+ for (int i = 10; i < 32; i++) {
+ xmlCode[i] = "&#0" + i + ";";
+ }
+
+ for (int i = 32; i < 128; i++) {
+ xmlCode[i] = String.valueOf((char)i);
+ }
+
+ // Special characters
+ xmlCode['\n'] = "<" + ElementTags.NEWLINE + " />\n";
+ xmlCode['\"'] = "&quot;"; // double quote
+ xmlCode['\''] = "&apos;"; // single quote
+ xmlCode['&'] = "&amp;"; // ampersand
+ xmlCode['<'] = "&lt;"; // lower than
+ xmlCode['>'] = "&gt;"; // greater than
+
+ for (int i = 128; i < 256; i++) {
+ xmlCode[i] = "&#" + i + ";";
+ }
+ }
+ // membervariables
+
+/** This is the meta information of the document. */
+ private TreeMap itext = new TreeMap(new com.lowagie.text.StringCompare());
+
+ // constructors
+
+/**
+ * Constructs an <CODE>XmlWriter</CODE>.
+ *
+ * @param doc The <CODE>Document</CODE> that has to be written as XML
+ * @param os The <CODE>OutputStream</CODE> the writer has to write to.
+ */
+
+ protected XmlWriter(Document doc, OutputStream os) {
+ super(doc, os);
+
+ document.addDocListener(this);
+ try {
+ os.write(PROLOG);
+ os.write(DOCTYPE);
+ os.write(DTD);
+ os.write(QUOTE);
+ os.write(GT);
+ os.write(NEWLINE);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ }
+
+/**
+ * Constructs an <CODE>XmlWriter</CODE>.
+ *
+ * @param doc The <CODE>Document</CODE> that has to be written as XML
+ * @param os The <CODE>OutputStream</CODE> the writer has to write to.
+ * @param dtd The DTD to use
+ */
+
+ protected XmlWriter(Document doc, OutputStream os, String dtd) {
+ super(doc, os);
+
+ document.addDocListener(this);
+ try {
+ os.write(PROLOG);
+ os.write(DOCTYPE);
+ os.write(getISOBytes(dtd));
+ os.write(QUOTE);
+ os.write(GT);
+ os.write(NEWLINE);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ }
+
+ // get an instance of the XmlWriter
+
+/**
+ * Gets an instance of the <CODE>XmlWriter</CODE>.
+ *
+ * @param document The <CODE>Document</CODE> that has to be written
+ * @param os The <CODE>OutputStream</CODE> the writer has to write to.
+ * @return a new <CODE>XmlWriter</CODE>
+ */
+
+ public static XmlWriter getInstance(Document document, OutputStream os) {
+ return new XmlWriter(document, os);
+ }
+
+/**
+ * Gets an instance of the <CODE>XmlWriter</CODE>.
+ *
+ * @param document The <CODE>Document</CODE> that has to be written
+ * @param os The <CODE>OutputStream</CODE> the writer has to write to.
+ * @param dtd The DTD to use
+ * @return a new <CODE>XmlWriter</CODE>
+ */
+
+ public static XmlWriter getInstance(Document document, OutputStream os, String dtd) {
+ return new XmlWriter(document, os, dtd);
+ }
+
+ // implementation of the DocListener methods
+
+/**
+ * Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
+ *
+ * @param element A high level object that will be added to the XML
+ * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
+ * @throws DocumentException when a document isn't open yet, or has been closed
+ */
+
+ public boolean add(Element element) throws DocumentException {
+ if (pause) {
+ return false;
+ }
+ try {
+ switch(element.type()) {
+ case Element.TITLE:
+ itext.put(ElementTags.TITLE, ((Meta)element).content());
+ return true;
+ case Element.SUBJECT:
+ itext.put(ElementTags.SUBJECT, ((Meta)element).content());
+ return true;
+ case Element.KEYWORDS:
+ itext.put(ElementTags.KEYWORDS, ((Meta)element).content());
+ return true;
+ case Element.AUTHOR:
+ itext.put(ElementTags.AUTHOR, ((Meta)element).content());
+ return true;
+ default:
+ write(element, 1);
+ return true;
+ }
+ }
+ catch(IOException ioe) {
+ return false;
+ }
+ }
+
+/**
+ * Signals that the <CODE>Document</CODE> has been opened and that
+ * <CODE>Elements</CODE> can be added.
+ */
+
+ public void open() {
+ super.open();
+ try {
+ itext.put(ElementTags.PRODUCER, "iTextXML by lowagie.com");
+ itext.put(ElementTags.CREATIONDATE, new Date().toString());
+ writeStart(ElementTags.ITEXT);
+ String key;
+ for (java.util.Iterator i = itext.keySet().iterator(); i.hasNext(); ) {
+ key = (String) i.next();
+ write(key, (String) itext.get(key));
+ }
+ os.write(GT);
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ }
+
+/**
+ * Signals that an new page has to be LTed.
+ *
+ * @return <CODE>true</CODE> if the page was added, <CODE>false</CODE> if not.
+ * @throws DocumentException when a document isn't open yet, or has been closed
+ */
+
+ public boolean newPage() throws DocumentException {
+ if (pause || !open) {
+ return false;
+ }
+ try {
+ writeStart(ElementTags.NEWPAGE);
+ writeEnd();
+ return true;
+ }
+ catch(IOException ioe) {
+ return false;
+ }
+ }
+
+/**
+ * Signals that the <CODE>Document</CODE> was closed and that no other
+ * <CODE>Elements</CODE> will be added.
+ */
+
+ public void close() {
+ try {
+ os.write(NEWLINE);
+ writeEnd(ElementTags.ITEXT);
+ super.close();
+ }
+ catch(IOException ioe) {
+ throw new ExceptionConverter(ioe);
+ }
+ }
+
+ // methods
+
+/**
+ * Writes the XML representation of an element.
+ *
+ * @param element the element
+ * @param indent the indentation
+ * @throws IOException
+ */
+
+ private void write(Element element, int indent) throws IOException {
+ switch(element.type()) {
+ case Element.CHUNK:
+ {
+ Chunk chunk = (Chunk) element;
+
+ // if the chunk contains an image, return the image representation
+ try {
+ Image image = chunk.getImage();
+ write(image, indent);
+ return;
+ }
+ catch(NullPointerException npe) {
+ // empty on purpose
+ }
+
+ addTabs(indent);
+ HashMap attributes = chunk.getAttributes();
+ if (chunk.font().isStandardFont() && attributes == null && !(hasMarkupAttributes(chunk))) {
+ write(encode(chunk.content(), indent));
+ return;
+ }
+ else {
+ if (attributes != null && attributes.get(Chunk.NEWPAGE) != null) {
+ writeStart(ElementTags.NEWPAGE);
+ writeEnd();
+ return;
+ }
+ writeStart(ElementTags.CHUNK);
+ if (! chunk.font().isStandardFont()) {
+ write(chunk.font());
+ }
+ if (attributes != null) {
+ for (Iterator i = attributes.keySet().iterator(); i.hasNext(); ) {
+ String key = (String) i.next();
+ if (key.equals(Chunk.LOCALGOTO)
+ || key.equals(Chunk.LOCALDESTINATION)
+ || key.equals(Chunk.GENERICTAG)) {
+ String value = (String) attributes.get(key);
+ write(key.toLowerCase(), value);
+ }
+ if (key.equals(Chunk.SUBSUPSCRIPT)) {
+ write(key.toLowerCase(), String.valueOf((Float) attributes.get(key)));
+ }
+ }
+ }
+ if (hasMarkupAttributes(chunk)) {
+ writeMarkupAttributes((MarkupAttributes)chunk);
+ }
+ os.write(GT);
+ write(encode(chunk.content(), indent));
+ writeEnd(ElementTags.CHUNK);
+ }
+ return;
+ }
+ case Element.PHRASE:
+ {
+ Phrase phrase = (Phrase) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.PHRASE);
+
+ write(ElementTags.LEADING, String.valueOf(phrase.leading()));
+ write(phrase.font());
+ if (hasMarkupAttributes(phrase)) {
+ writeMarkupAttributes((MarkupAttributes)phrase);
+ }
+ os.write(GT);
+
+ for (Iterator i = phrase.iterator(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+
+ addTabs(indent);
+ writeEnd(ElementTags.PHRASE);
+ return;
+ }
+ case Element.ANCHOR:
+ {
+ Anchor anchor = (Anchor) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.ANCHOR);
+
+ write(ElementTags.LEADING, String.valueOf(anchor.leading()));
+ write(anchor.font());
+ if (anchor.name() != null) {
+ write(ElementTags.NAME, anchor.name());
+ }
+ if (anchor.reference() != null) {
+ write(ElementTags.REFERENCE, anchor.reference());
+ }
+ if (hasMarkupAttributes(anchor)) {
+ writeMarkupAttributes((MarkupAttributes)anchor);
+ }
+ os.write(GT);
+ for (Iterator i = anchor.iterator(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.ANCHOR);
+ return;
+ }
+ case Element.PARAGRAPH:
+ {
+ Paragraph paragraph = (Paragraph) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.PARAGRAPH);
+
+ write(ElementTags.LEADING, String.valueOf(paragraph.leading()));
+ write(paragraph.font());
+ write(ElementTags.ALIGN, ElementTags.getAlignment(paragraph.alignment()));
+ if (paragraph.indentationLeft() != 0) {
+ write(ElementTags.INDENTATIONLEFT, String.valueOf(paragraph.indentationLeft()));
+ }
+ if (paragraph.indentationRight() != 0) {
+ write(ElementTags.INDENTATIONRIGHT, String.valueOf(paragraph.indentationRight()));
+ }
+ if (hasMarkupAttributes(paragraph)) {
+ writeMarkupAttributes((MarkupAttributes)paragraph);
+ }
+ os.write(GT);
+ for (Iterator i = paragraph.iterator(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.PARAGRAPH);
+ return;
+ }
+ case Element.SECTION:
+ {
+ Section section = (Section) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.SECTION);
+ writeSection(section, indent);
+ writeEnd(ElementTags.SECTION);
+ return;
+ }
+ case Element.CHAPTER:
+ {
+ Chapter chapter = (Chapter) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.CHAPTER);
+ if (hasMarkupAttributes(chapter)) {
+ writeMarkupAttributes((MarkupAttributes)chapter);
+ }
+ writeSection(chapter, indent);
+ writeEnd(ElementTags.CHAPTER);
+ return;
+
+ }
+ case Element.LIST:
+ {
+ List list = (List) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.LIST);
+ write(ElementTags.NUMBERED, String.valueOf(list.isNumbered()));
+ write(ElementTags.SYMBOLINDENT, String.valueOf(list.symbolIndent()));
+ if (list.first() != 1) {
+ write(ElementTags.FIRST, String.valueOf(list.first()));
+ }
+ if (list.indentationLeft() != 0) {
+ write(ElementTags.INDENTATIONLEFT, String.valueOf(list.indentationLeft()));
+ }
+ if (list.indentationRight() != 0) {
+ write(ElementTags.INDENTATIONRIGHT, String.valueOf(list.indentationRight()));
+ }
+ if (!list.isNumbered()) {
+ write(ElementTags.LISTSYMBOL, list.symbol().content());
+ }
+ write(list.symbol().font());
+ if (hasMarkupAttributes(list)) {
+ writeMarkupAttributes((MarkupAttributes)list);
+ }
+ os.write(GT);
+ for (Iterator i = list.getItems().iterator(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.LIST);
+ return;
+ }
+ case Element.LISTITEM:
+ {
+ ListItem listItem = (ListItem) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.LISTITEM);
+ write(ElementTags.LEADING, String.valueOf(listItem.leading()));
+ write(listItem.font());
+ write(ElementTags.ALIGN, ElementTags.getAlignment(listItem.alignment()));
+ if (listItem.indentationLeft() != 0) {
+ write(ElementTags.INDENTATIONLEFT, String.valueOf(listItem.indentationLeft()));
+ }
+ if (listItem.indentationRight() != 0) {
+ write(ElementTags.INDENTATIONRIGHT, String.valueOf(listItem.indentationRight()));
+ }
+ if (hasMarkupAttributes(listItem)) {
+ writeMarkupAttributes((MarkupAttributes)listItem);
+ }
+ os.write(GT);
+ for (Iterator i = listItem.iterator(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.LISTITEM);
+ return;
+ }
+ case Element.CELL:
+ {
+ Cell cell = (Cell) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.CELL);
+ write((Rectangle) cell);
+ write(ElementTags.HORIZONTALALIGN, ElementTags.getAlignment(cell.horizontalAlignment()));
+ write(ElementTags.VERTICALALIGN, ElementTags.getAlignment(cell.verticalAlignment()));
+ if (cell.cellWidth() != null) {
+ write(ElementTags.WIDTH, cell.cellWidth());
+ }
+ if (cell.colspan() != 1) {
+ write(ElementTags.COLSPAN, String.valueOf(cell.colspan()));
+ }
+ if (cell.rowspan() != 1) {
+ write(ElementTags.ROWSPAN, String.valueOf(cell.rowspan()));
+ }
+ if (cell.header()) {
+ write(ElementTags.HEADER, String.valueOf(true));
+ }
+ if (cell.noWrap()) {
+ write(ElementTags.NOWRAP, String.valueOf(true));
+ }
+ if (cell.leading() != -1) {
+ write(ElementTags.LEADING, String.valueOf(cell.leading()));
+ }
+ if (hasMarkupAttributes(cell)) {
+ writeMarkupAttributes((MarkupAttributes)cell);
+ }
+ os.write(GT);
+ for (Iterator i = cell.getElements(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.CELL);
+ return;
+ }
+ case Element.ROW:
+ {
+ Row row = (Row) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.ROW);
+ if (hasMarkupAttributes(row)){
+ writeMarkupAttributes((MarkupAttributes)row);
+ }
+ os.write(GT);
+ Element cell;
+ for (int i = 0; i < row.columns(); i++) {
+ if ((cell = (Element)row.getCell(i)) != null) {
+ write(cell, indent + 1);
+ }
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.ROW);
+ return;
+ }
+ case Element.TABLE:
+ {
+ Table table;
+ try {
+ table = (Table) element;
+ }
+ catch(ClassCastException cce) {
+ try {
+ table = ((SimpleTable)element).createTable();
+ } catch (BadElementException e) {
+ throw new ExceptionConverter(e);
+ }
+ }
+ table.complete();
+ addTabs(indent);
+ writeStart(ElementTags.TABLE);
+ write(ElementTags.COLUMNS, String.valueOf(table.columns()));
+ os.write(SPACE);
+ write(ElementTags.WIDTH);
+ os.write(EQUALS);
+ os.write(QUOTE);
+ if (! "".equals(table.absWidth())){
+ write(table.absWidth());
+ }
+ else{
+ write(String.valueOf(table.widthPercentage()));
+ write("%");
+ }
+ os.write(QUOTE);
+ write(ElementTags.ALIGN, ElementTags.getAlignment(table.alignment()));
+ write(ElementTags.CELLPADDING, String.valueOf(table.cellpadding()));
+ write(ElementTags.CELLSPACING, String.valueOf(table.cellspacing()));
+ os.write(SPACE);
+ write(ElementTags.WIDTHS);
+ os.write(EQUALS);
+ os.write(QUOTE);
+ float[] widths = table.getProportionalWidths();
+ write(String.valueOf(widths[0]));
+ for (int i = 1; i < widths.length; i++) {
+ write(";");
+ write(String.valueOf(widths[i]));
+ }
+ os.write(QUOTE);
+ write((Rectangle) table);
+ if (hasMarkupAttributes(table)) {
+ writeMarkupAttributes((MarkupAttributes)table);
+ }
+ os.write(GT);
+ Row row;
+ for (Iterator iterator = table.iterator(); iterator.hasNext(); ) {
+ row = (Row) iterator.next();
+ write(row, indent + 1);
+ }
+ addTabs(indent);
+ writeEnd(ElementTags.TABLE);
+ return;
+ }
+ case Element.ANNOTATION:
+ {
+ Annotation annotation = (Annotation) element;
+
+ addTabs(indent);
+ writeStart(ElementTags.ANNOTATION);
+ if (annotation.title() != null) {
+ write(ElementTags.TITLE, annotation.title());
+ }
+ if (annotation.content() != null) {
+ write(ElementTags.CONTENT, annotation.content());
+ }
+ if (hasMarkupAttributes(annotation)) {
+ writeMarkupAttributes((MarkupAttributes)annotation);
+ }
+ writeEnd();
+ return;
+ }
+ case Element.IMGRAW:
+ case Element.JPEG:
+ case Element.IMGTEMPLATE:
+ {
+ Image image = (Image) element;
+ if (image.url() == null) {
+ return;
+ }
+
+ addTabs(indent);
+ writeStart(ElementTags.IMAGE);
+ write(ElementTags.URL, image.url().toString());
+ if ((image.alignment() & Image.LEFT) > 0) {
+ write(ElementTags.ALIGN, ElementTags.ALIGN_LEFT);
+ }
+ else if ((image.alignment() & Image.RIGHT) > 0) {
+ write(ElementTags.ALIGN, ElementTags.ALIGN_RIGHT);
+ }
+ else if ((image.alignment() & Image.MIDDLE) > 0) {
+ write(ElementTags.ALIGN, ElementTags.ALIGN_MIDDLE);
+ }
+ if ((image.alignment() & Image.UNDERLYING) > 0) {
+ write(ElementTags.UNDERLYING, String.valueOf(true));
+ }
+ if ((image.alignment() & Image.TEXTWRAP) > 0) {
+ write(ElementTags.TEXTWRAP, String.valueOf(true));
+ }
+ if (image.alt() != null) {
+ write(ElementTags.ALT, image.alt());
+ }
+ if (image.hasAbsolutePosition()) {
+ write(ElementTags.ABSOLUTEX, String.valueOf(image.absoluteX()));
+ write(ElementTags.ABSOLUTEY, String.valueOf(image.absoluteY()));
+ }
+ write(ElementTags.PLAINWIDTH, String.valueOf(image.plainWidth()));
+ write(ElementTags.PLAINHEIGHT, String.valueOf(image.plainHeight()));
+ if (hasMarkupAttributes(image)) {
+ writeMarkupAttributes((MarkupAttributes)image);
+ }
+ writeEnd();
+ return;
+ }
+ default:
+ return;
+ }
+ }
+
+/**
+ * Writes the XML representation of a section.
+ *
+ * @param section the section to write
+ * @param indent the indentation
+ * @throws IOException
+ */
+
+ private void writeSection(Section section, int indent) throws IOException {
+ write(ElementTags.NUMBERDEPTH, String.valueOf(section.numberDepth()));
+ write(ElementTags.DEPTH, String.valueOf(section.depth()));
+ write(ElementTags.INDENT, String.valueOf(section.indentation()));
+ if (section.indentationLeft() != 0) {
+ write(ElementTags.INDENTATIONLEFT, String.valueOf(section.indentationLeft()));
+ }
+ if (section.indentationRight() != 0) {
+ write(ElementTags.INDENTATIONRIGHT, String.valueOf(section.indentationRight()));
+ }
+ os.write(GT);
+
+ if (section.title() != null) {
+ addTabs(indent + 1);
+ writeStart(ElementTags.TITLE);
+ write(ElementTags.LEADING, String.valueOf(section.title().leading()));
+ write(ElementTags.ALIGN, ElementTags.getAlignment(section.title().alignment()));
+ if (section.title().indentationLeft() != 0) {
+ write(ElementTags.INDENTATIONLEFT, String.valueOf(section.title().indentationLeft()));
+ }
+ if (section.title().indentationRight() != 0) {
+ write(ElementTags.INDENTATIONRIGHT, String.valueOf(section.title().indentationRight()));
+ }
+ write(section.title().font());
+ os.write(GT);
+ Iterator i = section.title().iterator();
+ if (section.depth() > 0) {
+ i.next();
+ }
+ while (i.hasNext()) {
+ write((Element) i.next(), indent + 2);
+ }
+ addTabs(indent + 1);
+ writeEnd(ElementTags.TITLE);
+ }
+ for (Iterator i = section.iterator(); i.hasNext(); ) {
+ write((Element) i.next(), indent + 1);
+ }
+ addTabs(indent);
+ }
+
+/**
+ * Writes the XML representation of this <CODE>Rectangle</CODE>.
+ *
+ * @param rectangle a <CODE>Rectangle</CODE>
+ * @throws IOException
+ */
+
+ private void write(Rectangle rectangle) throws IOException {
+ if (rectangle.borderWidth() != Rectangle.UNDEFINED) {
+ write(ElementTags.BORDERWIDTH, String.valueOf(rectangle.borderWidth()));
+ if (rectangle.hasBorder(Rectangle.LEFT)) {
+ write(ElementTags.LEFT, String.valueOf(true));
+ }
+ if (rectangle.hasBorder(Rectangle.RIGHT)) {
+ write(ElementTags.RIGHT, String.valueOf(true));
+ }
+ if (rectangle.hasBorder(Rectangle.TOP)) {
+ write(ElementTags.TOP, String.valueOf(true));
+ }
+ if (rectangle.hasBorder(Rectangle.BOTTOM)) {
+ write(ElementTags.BOTTOM, String.valueOf(true));
+ }
+ }
+ if (rectangle.borderColor() != null) {
+ write(ElementTags.RED, String.valueOf(rectangle.borderColor().getRed()));
+ write(ElementTags.GREEN, String.valueOf(rectangle.borderColor().getGreen()));
+ write(ElementTags.BLUE, String.valueOf(rectangle.borderColor().getBlue()));
+ }
+ if (rectangle.backgroundColor() != null) {
+ write(ElementTags.BGRED, String.valueOf(rectangle.backgroundColor().getRed()));
+ write(ElementTags.BGGREEN, String.valueOf(rectangle.backgroundColor().getGreen()));
+ write(ElementTags.BGBLUE, String.valueOf(rectangle.backgroundColor().getBlue()));
+ }
+ }
+
+/**
+ * Encodes a <CODE>String</CODE>.
+ *
+ * @param string the <CODE>String</CODE> to encode
+ * @param indent counter that keeps the number of tabs that has to be added for indentation
+ * @return the encoded <CODE>String</CODE>
+ */
+
+ static final String encode(String string, int indent) {
+ int n = string.length();
+ int pos = 0;
+ char character;
+ StringBuffer buf = new StringBuffer();
+ // loop over all the characters of the String.
+ for (int i = 0; i < n; i++) {
+ character = string.charAt(i);
+ // the Xmlcode of these characters are added to a StringBuffer one by one
+ switch(character) {
+ case ' ':
+ if ((i - pos) > 60) {
+ pos = i;
+ buf.append("\n");
+ addTabs(buf, indent);
+ break;
+ }
+ default:
+ buf.append(xmlCode[(int) character]);
+ }
+ }
+ return buf.toString();
+ }
+
+/**
+ * Adds a number of tabs to a <CODE>StringBuffer</CODE>.
+ *
+ * @param buf the stringbuffer
+ * @param indent the number of tabs to add
+ */
+
+ static final void addTabs(StringBuffer buf, int indent) {
+ for (int i = 0; i < indent; i++) {
+ buf.append("\t");
+ }
+ }
+
+/**
+ * Writes the XML representation of a <CODE>Font</CODE>.
+ *
+ * @param font a <CODE>Font</CODE>
+ * @throws IOException
+ */
+
+ private void write(Font font) throws IOException {
+ write(ElementTags.FONT, font.getFamilyname());
+ if (font.size() != Font.UNDEFINED) {
+ write(ElementTags.SIZE, String.valueOf(font.size()));
+ }
+ if (font.style() != Font.UNDEFINED) {
+ os.write(SPACE);
+ write(ElementTags.STYLE);
+ os.write(EQUALS);
+ os.write(QUOTE);
+ switch(font.style() & Font.BOLDITALIC) {
+ case Font.NORMAL:
+ write(MarkupTags.CSS_VALUE_NORMAL);
+ break;
+ case Font.BOLD:
+ write(MarkupTags.CSS_VALUE_BOLD);
+ break;
+ case Font.ITALIC:
+ write(MarkupTags.CSS_VALUE_ITALIC);
+ break;
+ case Font.BOLDITALIC:
+ write(MarkupTags.CSS_VALUE_BOLD);
+ write(", ");
+ write(MarkupTags.CSS_VALUE_ITALIC);
+ break;
+ }
+ if ((font.style() & Font.UNDERLINE) > 0) {
+ write(", ");
+ write(MarkupTags.CSS_VALUE_UNDERLINE);
+ }
+ if ((font.style() & Font.STRIKETHRU) > 0) {
+ write(", ");
+ write(MarkupTags.CSS_VALUE_LINETHROUGH);
+ }
+ os.write(QUOTE);
+ }
+ if (font.color() != null) {
+ write(ElementTags.RED, String.valueOf(font.color().getRed()));
+ write(ElementTags.GREEN, String.valueOf(font.color().getGreen()));
+ write(ElementTags.BLUE, String.valueOf(font.color().getBlue()));
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/xml/xmp/DublinCoreSchema.java b/src/main/java/com/lowagie/text/xml/xmp/DublinCoreSchema.java
new file mode 100644
index 0000000..53b1ade
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/DublinCoreSchema.java
@@ -0,0 +1,187 @@
+/*
+ * $Id: DublinCoreSchema.java,v 1.5 2005/09/08 07:50:15 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import java.io.IOException;
+
+/**
+ * An implementation of an XmpSchema.
+ */
+public class DublinCoreSchema extends XmpSchema {
+
+ /** default namespace identifier*/
+ public static final String DEFAULT_XPATH_ID = "dc";
+ /** default namespace uri*/
+ public static final String DEFAULT_XPATH_URI = "http://purl.org/dc/elements/1.1/";
+
+ /** External Contributors to the resource (other than the authors). */
+ public static final String CONTRIBUTOR = "dc:contributor";
+ /** The extent or scope of the resource. */
+ public static final String COVERAGE = "dc:coverage";
+ /** The authors of the resource (listed in order of precedence, if significant). */
+ public static final String CREATOR = "dc:creator";
+ /** Date(s) that something interesting happened to the resource. */
+ public static final String DATE = "dc:date";
+ /** A textual description of the content of the resource. Multiple values may be present for different languages. */
+ public static final String DESCRIPTION = "dc:description";
+ /** The file format used when saving the resource. Tools and applications should set this property to the save format of the data. It may include appropriate qualifiers. */
+ public static final String FORMAT = "dc:format";
+ /** Unique identifier of the resource. */
+ public static final String IDENTIFIER = "dc:identifier";
+ /** An unordered array specifying the languages used in the resource. */
+ public static final String LANGUAGE = "dc:language";
+ /** Publishers. */
+ public static final String PUBLISHER = "dc:publisher";
+ /** Relationships to other documents. */
+ public static final String RELATION = "dc:relation";
+ /** Informal rights statement, selected by language. */
+ public static final String RIGHTS = "dc:rights";
+ /** Unique identifier of the work from which this resource was derived. */
+ public static final String SOURCE = "dc:source";
+ /** An unordered array of descriptive phrases or keywords that specify the topic of the content of the resource. */
+ public static final String SUBJECT = "dc:subject";
+ /** The title of the document, or the name given to the resource. Typically, it will be a name by which the resource is formally known. */
+ public static final String TITLE = "dc:title";
+ /** A document type; for example, novel, poem, or working paper. */
+ public static final String TYPE = "dc:type";
+
+
+ /**
+ * @throws IOException
+ */
+ public DublinCoreSchema() throws IOException {
+ super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\"");
+ setProperty(FORMAT, "application/pdf");
+ }
+
+ /**
+ * Adds a title.
+ * @param title
+ */
+ public void addTitle(String title) {
+ setProperty(TITLE, title);
+ }
+
+ /**
+ * Adds a description.
+ * @param desc
+ */
+ public void addDescription(String desc) {
+ setProperty(DESCRIPTION, desc);
+ }
+
+ /**
+ * Adds a subject.
+ * @param subject
+ */
+ public void addSubject(String subject) {
+ XmpArray array = new XmpArray(XmpArray.UNORDERED);
+ array.add(subject);
+ setProperty(SUBJECT, array);
+ }
+
+
+ /**
+ * Adds a subject.
+ * @param subject array of subjects
+ */
+ public void addSubject(String[] subject) {
+ XmpArray array = new XmpArray(XmpArray.UNORDERED);
+ for (int i = 0; i < subject.length; i++) {
+ array.add(subject[i]);
+ }
+ setProperty(SUBJECT, array);
+ }
+
+ /**
+ * Adds a single author.
+ * @param author
+ */
+ public void addAuthor(String author) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ array.add(author);
+ setProperty(CREATOR, array);
+ }
+
+ /**
+ * Adds an array of authors.
+ * @param author
+ */
+ public void addAuthor(String[] author) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ for (int i = 0; i < author.length; i++) {
+ array.add(author[i]);
+ }
+ setProperty(CREATOR, array);
+ }
+
+ /**
+ * Adds a single publisher.
+ * @param publisher
+ */
+ public void addPublisher(String publisher) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ array.add(publisher);
+ setProperty(PUBLISHER, array);
+ }
+
+ /**
+ * Adds an array of publishers.
+ * @param publisher
+ */
+ public void addPublisher(String[] publisher) {
+ XmpArray array = new XmpArray(XmpArray.ORDERED);
+ for (int i = 0; i < publisher.length; i++) {
+ array.add(publisher[i]);
+ }
+ setProperty(PUBLISHER, array);
+ }
+}
diff --git a/src/main/java/com/lowagie/text/xml/xmp/PdfSchema.java b/src/main/java/com/lowagie/text/xml/xmp/PdfSchema.java
new file mode 100644
index 0000000..2793e57
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/PdfSchema.java
@@ -0,0 +1,105 @@
+/*
+ * $Id: PdfSchema.java,v 1.4 2005/09/08 07:50:15 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import com.lowagie.text.Document;
+import java.io.IOException;
+
+/**
+ * An implementation of an XmpSchema.
+ */
+public class PdfSchema extends XmpSchema {
+
+ /** default namespace identifier*/
+ public static final String DEFAULT_XPATH_ID = "pdf";
+ /** default namespace uri*/
+ public static final String DEFAULT_XPATH_URI = "http://ns.adobe.com/pdf/1.3/";
+
+ /** Keywords. */
+ public static final String KEYWORDS = "pdf:Keywords";
+ /** The PDF file version (for example: 1.0, 1.3, and so on). */
+ public static final String VERSION = "pdf:PDFVersion";
+ /** The Producer. */
+ public static final String PRODUCER = "pdf:Producer";
+
+
+ /**
+ * @throws IOException
+ */
+ public PdfSchema() throws IOException {
+ super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\"");
+ addProducer(Document.getVersion());
+ }
+
+ /**
+ * Adds keywords.
+ * @param keywords
+ */
+ public void addKeywords(String keywords) {
+ setProperty(KEYWORDS, keywords);
+ }
+
+ /**
+ * Adds the producer.
+ * @param producer
+ */
+ public void addProducer(String producer) {
+ setProperty(PRODUCER, producer);
+ }
+
+ /**
+ * Adds the version.
+ * @param version
+ */
+ public void addVersion(String version) {
+ setProperty(VERSION, version);
+ }
+}
diff --git a/src/main/java/com/lowagie/text/xml/xmp/XmpArray.java b/src/main/java/com/lowagie/text/xml/xmp/XmpArray.java
new file mode 100644
index 0000000..39016a7
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/XmpArray.java
@@ -0,0 +1,99 @@
+/*
+ * $Id: XmpArray.java,v 1.3 2005/09/08 07:50:15 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * StringBuffer to construct an XMP array.
+ */
+public class XmpArray extends ArrayList {
+
+ /** An array that is unordered. */
+ public static final String UNORDERED = "rdf:Bag";
+ /** An array that is ordered. */
+ public static final String ORDERED = "rdf:Seq";
+ /** An array with alternatives. */
+ public static final String ALTERNATIVE = "rdf:Alt";
+
+ /** the type of array. */
+ protected String type;
+
+ /**
+ * Creates an XmpArray.
+ * @param type the type of array: UNORDERED, ORDERED or ALTERNATIVE.
+ */
+ public XmpArray(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns the String representation of the XmpArray.
+ * @return a String representation
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer("<");
+ buf.append(type);
+ buf.append(">");
+ String s;
+ for (Iterator i = iterator(); i.hasNext(); ) {
+ s = (String) i.next();
+ buf.append("<rdf:li>");
+ buf.append(XmpSchema.escape(s));
+ buf.append("</rdf:li>");
+ }
+ buf.append("</");
+ buf.append(type);
+ buf.append(">");
+ return buf.toString();
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/xml/xmp/XmpBasicSchema.java b/src/main/java/com/lowagie/text/xml/xmp/XmpBasicSchema.java
new file mode 100644
index 0000000..03e8e54
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/XmpBasicSchema.java
@@ -0,0 +1,141 @@
+/*
+ * $Id: XmpBasicSchema.java,v 1.4 2005/09/08 07:50:15 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import java.io.IOException;
+
+/**
+ * An implementation of an XmpSchema.
+ */
+public class XmpBasicSchema extends XmpSchema {
+
+ /** default namespace identifier*/
+ public static final String DEFAULT_XPATH_ID = "xmp";
+ /** default namespace uri*/
+ public static final String DEFAULT_XPATH_URI = "http://ns.adobe.com/xap/1.0/";
+
+ /** An unordered array specifying properties that were edited outside the authoring application. Each item should contain a single namespace and XPath separated by one ASCII space (U+0020). */
+ public static final String ADVISORY = "xmp:Advisory";
+ /** The base URL for relative URLs in the document content. If this document contains Internet links, and those links are relative, they are relative to this base URL. This property provides a standard way for embedded relative URLs to be interpreted by tools. Web authoring tools should set the value based on their notion of where URLs will be interpreted. */
+ public static final String BASEURL = "xmp:BaseURL";
+ /** The date and time the resource was originally created. */
+ public static final String CREATEDATE = "xmp:CreateDate";
+ /** The name of the first known tool used to create the resource. If history is present in the metadata, this value should be equivalent to that of xmpMM:History’s softwareAgent property. */
+ public static final String CREATORTOOL = "xmp:CreatorTool";
+ /** An unordered array of text strings that unambiguously identify the resource within a given context. */
+ public static final String IDENTIFIER = "xmp:Identifier";
+ /** The date and time that any metadata for this resource was last changed. */
+ public static final String METADATADATE = "xmp:MetadataDate";
+ /** The date and time the resource was last modified. */
+ public static final String MODIFYDATE = "xmp:ModifyDate";
+ /** A short informal name for the resource. */
+ public static final String NICKNAME = "xmp:Nickname";
+ /** An alternative array of thumbnail images for a file, which can differ in characteristics such as size or image encoding. */
+ public static final String THUMBNAILS = "xmp:Thumbnails";
+
+
+ /**
+ * @throws IOException
+ */
+ public XmpBasicSchema() throws IOException {
+ super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\"");
+ }
+
+ /**
+ * Adds the creatortool.
+ * @param creator
+ */
+ public void addCreatorTool(String creator) {
+ setProperty(CREATORTOOL, creator);
+ }
+
+ /**
+ * Adds the creation date.
+ * @param date
+ */
+ public void addCreateDate(String date) {
+ setProperty(CREATEDATE, date);
+ }
+
+ /**
+ * Adds the modification date.
+ * @param date
+ */
+ public void addModDate(String date) {
+ setProperty(MODIFYDATE, date);
+ }
+
+ /**
+ * Adds the meta data date.
+ * @param date
+ */
+ public void addMetaDataDate(String date) {
+ setProperty(METADATADATE, date);
+ }
+
+ /** Adds the identifier.
+ * @param id
+ */
+ public void addIdentifiers(String[] id) {
+ XmpArray array = new XmpArray(XmpArray.UNORDERED);
+ for (int i = 0; i < id.length; i++) {
+ array.add(id[i]);
+ }
+ setProperty(IDENTIFIER, array);
+ }
+
+ /** Adds the nickname.
+ * @param name
+ */
+ public void addNickname(String name) {
+ setProperty(NICKNAME, name);
+ }
+}
diff --git a/src/main/java/com/lowagie/text/xml/xmp/XmpMMSchema.java b/src/main/java/com/lowagie/text/xml/xmp/XmpMMSchema.java
new file mode 100644
index 0000000..f19e7f0
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/XmpMMSchema.java
@@ -0,0 +1,97 @@
+/*
+ * $Id: XmpMMSchema.java,v 1.3 2005/09/08 07:50:15 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import java.io.IOException;
+
+/**
+ * An implementation of an XmpSchema.
+ */
+public class XmpMMSchema extends XmpSchema {
+
+ /** default namespace identifier*/
+ public static final String DEFAULT_XPATH_ID = "xmpMM";
+ /** default namespace uri*/
+ public static final String DEFAULT_XPATH_URI = "http://ns.adobe.com/xap/1.0/mm/";
+
+
+ /** A reference to the original document from which this one is derived. It is a minimal reference; missing components can be assumed to be unchanged. For example, a new version might only need to specify the instance ID and version number of the previous version, or a rendition might only need to specify the instance ID and rendition class of the original. */
+ public static final String DERIVEDFROM = "xmpMM:DerivedFrom";
+ /** The common identifier for all versions and renditions of a document. */
+ public static final String DOCUMENTID = "xmpMM:DocumentID";
+ /** An ordered array of high-level user actions that resulted in this resource. It is intended to give human readers a general indication of the steps taken to make the changes from the previous version to this one. The list should be at an abstract level; it is not intended to be an exhaustive keystroke or other detailed history. */
+ public static final String HISTORY = "xmpMM:History";
+ /** A reference to the document as it was prior to becoming managed. It is set when a managed document is introduced to an asset management system that does not currently own it. It may or may not include references to different management systems. */
+ public static final String MANAGEDFROM = "xmpMM:ManagedFrom";
+ /** The name of the asset management system that manages this resource. */
+ public static final String MANAGER = "xmpMM:Manager";
+ /** A URI identifying the managed resource to the asset management system; the presence of this property is the formal indication that this resource is managed. The form and content of this URI is private to the asset management system. */
+ public static final String MANAGETO = "xmpMM:ManageTo";
+ /** A URI that can be used to access information about the managed resource through a web browser. It might require a custom browser plugin. */
+ public static final String MANAGEUI = "xmpMM:ManageUI";
+ /** Specifies a particular variant of the asset management system. The format of this property is private to the specific asset management system. */
+ public static final String MANAGERVARIANT = "xmpMM:ManagerVariant";
+ /** The rendition class name for this resource.*/
+ public static final String RENDITIONCLASS = "xmpMM:RenditionClass";
+ /** Can be used to provide additional rendition parameters that are too complex or verbose to encode in xmpMM: RenditionClass. */
+ public static final String RENDITIONPARAMS = "xmpMM:RenditionParams";
+ /** The document version identifier for this resource. */
+ public static final String VERSIONID = "xmpMM:VersionID";
+ /** The version history associated with this resource.*/
+ public static final String VERSIONS = "xmpMM:Versions";
+
+ /**
+ * @throws IOException
+ */
+ public XmpMMSchema() throws IOException {
+ super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\"");
+ }
+}
diff --git a/src/main/java/com/lowagie/text/xml/xmp/XmpSchema.java b/src/main/java/com/lowagie/text/xml/xmp/XmpSchema.java
new file mode 100644
index 0000000..1b66cc8
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/XmpSchema.java
@@ -0,0 +1,158 @@
+/*
+ * $Id: XmpSchema.java,v 1.5 2005/09/08 10:27:29 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * Abstract superclass of the XmpSchemas supported by iText.
+ */
+public abstract class XmpSchema extends Properties {
+
+ /** the namesspace */
+ protected String xmlns;
+
+ /** Constructs an XMP schema.
+ * @param xmlns
+ */
+ public XmpSchema(String xmlns) {
+ super();
+ this.xmlns = xmlns;
+ }
+ /**
+ * The String representation of the contents.
+ * @return a String representation.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ for (Enumeration e = this.propertyNames(); e.hasMoreElements(); ) {
+ process(buf, e.nextElement());
+ }
+ return buf.toString();
+ }
+ /**
+ * Processes a property
+ * @param buf
+ * @param p
+ */
+ protected void process(StringBuffer buf, Object p) {
+ buf.append("<");
+ buf.append(p);
+ buf.append(">");
+ buf.append(this.get(p));
+ buf.append("</");
+ buf.append(p);
+ buf.append(">");
+ }
+ /**
+ * @return Returns the xmlns.
+ */
+ public String getXmlns() {
+ return xmlns;
+ }
+
+ /**
+ * @param key
+ * @param value
+ * @return the previous property (null if there wasn't one)
+ */
+ public synchronized Object addProperty(String key, String value) {
+ return this.setProperty(key, value);
+ }
+
+ /**
+ * @see java.util.Properties#setProperty(java.lang.String, java.lang.String)
+ */
+ public synchronized Object setProperty(String key, String value) {
+ return super.setProperty(key, escape(value));
+ }
+
+ /**
+ * @see java.util.Properties#setProperty(java.lang.String, java.lang.String)
+ *
+ * @param key
+ * @param value
+ * @return the previous property (null if there wasn't one)
+ */
+ public synchronized Object setProperty(String key, XmpArray value) {
+ return super.setProperty(key, value.toString());
+ }
+ /**
+ * @param content
+ * @return an escaped string
+ */
+ public static String escape(String content) {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < content.length(); i++) {
+ switch(content.charAt(i)) {
+ case '<':
+ buf.append("&lt;");
+ break;
+ case '>':
+ buf.append("&gt;");
+ break;
+ case '\'':
+ buf.append("&apos;");
+ break;
+ case '\"':
+ buf.append("&quot;");
+ break;
+ case '&':
+ buf.append("&amp;");
+ break;
+ default:
+ buf.append(content.charAt(i));
+ }
+ }
+ return buf.toString();
+ }
+}
diff --git a/src/main/java/com/lowagie/text/xml/xmp/XmpWriter.java b/src/main/java/com/lowagie/text/xml/xmp/XmpWriter.java
new file mode 100644
index 0000000..8cec5f8
--- /dev/null
+++ b/src/main/java/com/lowagie/text/xml/xmp/XmpWriter.java
@@ -0,0 +1,276 @@
+/*
+ * $Id: XmpWriter.java,v 1.8 2005/11/14 15:21:45 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2005 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml.xmp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Map;
+import java.util.Iterator;
+
+import com.lowagie.text.pdf.PdfDate;
+import com.lowagie.text.pdf.PdfDictionary;
+import com.lowagie.text.pdf.PdfName;
+import com.lowagie.text.pdf.PdfObject;
+import com.lowagie.text.pdf.PdfString;
+
+/**
+ * With this class you can create an Xmp Stream that can be used for adding
+ * Metadata to a PDF Dictionary. Remark that this class doesn't cover the
+ * complete XMP specification.
+ */
+public class XmpWriter {
+
+ /** A possible charset for the XMP. */
+ public static final String UTF8 = "UTF-8";
+ /** A possible charset for the XMP. */
+ public static final String UTF16 = "UTF-16";
+ /** A possible charset for the XMP. */
+ public static final String UTF16BE = "UTF-16BE";
+ /** A possible charset for the XMP. */
+ public static final String UTF16LE = "UTF-16LE";
+
+ /** String used to fill the extra space. */
+ public static final String EXTRASPACE = " \n";
+
+ /** You can add some extra space in the XMP packet; 1 unit in this variable represents 100 spaces and a newline. */
+ protected int extraSpace;
+
+ /** The writer to which you can write bytes for the XMP stream. */
+ protected OutputStreamWriter writer;
+
+ /** The about string that goes into the rdf:Description tags. */
+ protected String about;
+
+ /** The end attribute. */
+ protected char end = 'w';
+
+ /**
+ * Creates an XmpWriter.
+ * @param os
+ * @param utfEncoding
+ * @param extraSpace
+ * @throws IOException
+ */
+ public XmpWriter(OutputStream os, String utfEncoding, int extraSpace) throws IOException {
+ this.extraSpace = extraSpace;
+ writer = new OutputStreamWriter(os, utfEncoding);
+ writer.write("<?xpacket begin='\uFEFF' id='W5M0MpCehiHzreSzNTczkc9d' ?>\n");
+ writer.write("<x:xmpmeta xmlns:x='adobe:ns:meta/'>\n");
+ writer.write("<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n");
+ about = "";
+ }
+
+ /**
+ * Creates an XmpWriter.
+ * @param os
+ * @throws IOException
+ */
+ public XmpWriter(OutputStream os) throws IOException {
+ this(os, UTF8, 20);
+ }
+
+ /** Sets the XMP to read-only */
+ public void setReadOnly() {
+ end = 'r';
+ }
+
+ /**
+ * @param about The about to set.
+ */
+ public void setAbout(String about) {
+ this.about = about;
+ }
+
+ /**
+ * Adds an rdf:Description.
+ * @param xmlns
+ * @param content
+ * @throws IOException
+ */
+ public void addRdfDescription(String xmlns, String content) throws IOException {
+ writer.write("<rdf:Description rdf:about='");
+ writer.write(about);
+ writer.write("' ");
+ writer.write(xmlns);
+ writer.write(">");
+ writer.write(content);
+ writer.write("</rdf:Description>\n");
+ }
+
+ /**
+ * Adds an rdf:Description.
+ * @param s
+ * @throws IOException
+ */
+ public void addRdfDescription(XmpSchema s) throws IOException {
+ writer.write("<rdf:Description rdf:about='");
+ writer.write(about);
+ writer.write("' ");
+ writer.write(s.getXmlns());
+ writer.write(">");
+ writer.write(s.toString());
+ writer.write("</rdf:Description>\n");
+ }
+
+ /**
+ * Flushes and closes the XmpWriter.
+ * @throws IOException
+ */
+ public void close() throws IOException {
+ writer.write("</rdf:RDF>");
+ writer.write("</x:xmpmeta>\n");
+ for (int i = 0; i < extraSpace; i++) {
+ writer.write(EXTRASPACE);
+ }
+ writer.write("<?xpacket ends='" + end + "' ?>");
+ writer.flush();
+ writer.close();
+ }
+
+ /**
+ * @param os
+ * @param info
+ * @throws IOException
+ */
+ public XmpWriter(OutputStream os, PdfDictionary info) throws IOException {
+ this(os);
+ if (info != null) {
+ DublinCoreSchema dc = new DublinCoreSchema();
+ PdfSchema p = new PdfSchema();
+ XmpBasicSchema basic = new XmpBasicSchema();
+ PdfName key;
+ PdfObject obj;
+ for (Iterator it = info.getKeys().iterator(); it.hasNext();) {
+ key = (PdfName)it.next();
+ obj = info.get(key);
+ if (obj == null)
+ continue;
+ if (PdfName.TITLE.equals(key)) {
+ dc.addTitle(((PdfString)obj).toUnicodeString());
+ }
+ if (PdfName.AUTHOR.equals(key)) {
+ dc.addAuthor(((PdfString)obj).toUnicodeString());
+ }
+ if (PdfName.SUBJECT.equals(key)) {
+ dc.addSubject(((PdfString)obj).toUnicodeString());
+ }
+ if (PdfName.KEYWORDS.equals(key)) {
+ p.addKeywords(((PdfString)obj).toUnicodeString());
+ }
+ if (PdfName.CREATOR.equals(key)) {
+ basic.addCreatorTool(((PdfString)obj).toUnicodeString());
+ }
+ if (PdfName.PRODUCER.equals(key)) {
+ p.addProducer(((PdfString)obj).toUnicodeString());
+ }
+ if (PdfName.CREATIONDATE.equals(key)) {
+ basic.addCreateDate(((PdfDate)obj).getW3CDate());
+ }
+ if (PdfName.MODDATE.equals(key)) {
+ basic.addModDate(((PdfDate)obj).getW3CDate());
+ }
+ }
+ if (dc.size() > 0) addRdfDescription(dc);
+ if (p.size() > 0) addRdfDescription(p);
+ if (basic.size() > 0) addRdfDescription(basic);
+ }
+ }
+
+ /**
+ * @param os
+ * @param info
+ * @throws IOException
+ */
+ public XmpWriter(OutputStream os, Map info) throws IOException {
+ this(os);
+ if (info != null) {
+ DublinCoreSchema dc = new DublinCoreSchema();
+ PdfSchema p = new PdfSchema();
+ XmpBasicSchema basic = new XmpBasicSchema();
+ String key;
+ String value;
+ for (Iterator it = info.keySet().iterator(); it.hasNext();) {
+ key = (String)it.next();
+ value = (String)info.get(key);
+ if (value == null)
+ continue;
+ if ("Title".equals(key)) {
+ dc.addTitle(value);
+ }
+ if ("Author".equals(key)) {
+ dc.addAuthor(value);
+ }
+ if ("Subject".equals(key)) {
+ dc.addSubject(value);
+ }
+ if ("Keywords".equals(key)) {
+ p.addKeywords(value);
+ }
+ if ("Creator".equals(key)) {
+ basic.addCreatorTool(value);
+ }
+ if ("Producer".equals(key)) {
+ p.addProducer(value);
+ }
+ if ("CreationDate".equals(key)) {
+ basic.addCreateDate(PdfDate.getW3CDate(value));
+ }
+ if ("ModDate".equals(key)) {
+ basic.addModDate(PdfDate.getW3CDate(value));
+ }
+ }
+ if (dc.size() > 0) addRdfDescription(dc);
+ if (p.size() > 0) addRdfDescription(p);
+ if (basic.size() > 0) addRdfDescription(basic);
+ }
+ }
+} \ No newline at end of file