aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/lowagie/text/xml/XmlWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/lowagie/text/xml/XmlWriter.java')
-rw-r--r--src/main/java/com/lowagie/text/xml/XmlWriter.java893
1 files changed, 893 insertions, 0 deletions
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