diff options
Diffstat (limited to 'xmerge/java/org/openoffice/xmerge/converter')
564 files changed, 59580 insertions, 0 deletions
diff --git a/xmerge/java/org/openoffice/xmerge/converter/dom/DOMDocument.java b/xmerge/java/org/openoffice/xmerge/converter/dom/DOMDocument.java new file mode 100644 index 000000000000..8e753a993928 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/dom/DOMDocument.java @@ -0,0 +1,385 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DOMDocument.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.dom; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; + + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.openoffice.xmerge.util.Resources; +import org.openoffice.xmerge.util.Debug; + +/** + * An implementation of <code>Document</code> for + * StarOffice documents. + */ +public class DOMDocument + implements org.openoffice.xmerge.Document { + + /** Factory for <code>DocumentBuilder</code> objects. */ + private static DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + + /** DOM <code>Document</code> of content.xml. */ + private Document contentDoc = null; + + /** DOM <code>Document</code> of content.xml. */ + private Document styleDoc = null; + + private String documentName = null; + private String fileName = null; + private String fileExt = null; + + /** Resources object. */ + private Resources res = null; + + + /** + * Default constructor. + * + * @param name <code>Document</code> name. + * @param ext <code>Document</code> extension. + */ + public DOMDocument(String name,String ext) + { + this(name,ext,true, false); + } + + /** + * Returns the file extension of the <code>Document</code> + * represented. + * + * @return file extension of the <code>Document</code>. + */ + protected String getFileExtension() { + return fileExt; + } + + + /** + * Constructor with arguments to set <code>namespaceAware</code> + * and <code>validating</code> flags. + * + * @param name <code>Document</code> name (may or may not + * contain extension). + * @param ext <code>Document</code> extension. + * @param namespaceAware Value for <code>namespaceAware</code> flag. + * @param validating Value for <code>validating</code> flag. + */ + public DOMDocument(String name, String ext,boolean namespaceAware, boolean validating) { + + res = Resources.getInstance(); + factory.setValidating(validating); + factory.setNamespaceAware(namespaceAware); + this.fileExt = ext; + this.documentName = trimDocumentName(name); + this.fileName = documentName + getFileExtension(); + } + + + /** + * Removes the file extension from the <code>Document</code> + * name. + * + * @param name Full <code>Document</code> name with extension. + * + * @return Name of <code>Document</code> without the extension. + */ + private String trimDocumentName(String name) { + String temp = name.toLowerCase(); + String ext = getFileExtension(); + + if (temp.endsWith(ext)) { + // strip the extension + int nlen = name.length(); + int endIndex = nlen - ext.length(); + name = name.substring(0,endIndex); + } + + return name; + } + + + /** + * Return a DOM <code>Document</code> object of the document content + * file. Note that a content DOM is not created when the constructor + * is called. So, either the <code>read</code> method or the + * <code>initContentDOM</code> method will need to be called ahead + * on this object before calling this method. + * + * @return DOM <code>Document</code> object. + */ + public Document getContentDOM() { + + return contentDoc; + } + + /** + * Sets the Content of the <code>Document</code> to the contents of the + * supplied <code>Node</code> list. + * + * @return DOM <code>Document</code> object. + */ + public void setContentDOM( Node newDom) { + contentDoc=(Document)newDom; + } + + + /** + * Return the name of the <code>Document</code>. + * + * @return The name of <code>Document</code>. + */ + public String getName() { + + return documentName; + } + + + /** + * Return the file name of the <code>Document</code>, possibly + * with the standard extension. + * + * @return The file name of <code>Document</code>. + */ + public String getFileName() { + + return fileName; + } + + + /** + * Read the Office <code>Document</code> from the specified + * <code>InputStream</code>. + * + * @param is Office document <code>InputStream</code>. + * + * @throws IOException If any I/O error occurs. + */ + public void read(InputStream is) throws IOException { + Debug.log(Debug.INFO, "reading file"); + DocumentBuilder builder = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + System.out.println("Error:"+ ex); + //throw new OfficeDocumentException(ex); + } + try { + + contentDoc= builder.parse(is); + + + } catch (SAXException ex) { + System.out.println("Error:"+ ex); + //throw new OfficeDocumentException(ex); + } + } + + + /** + * Write out content to the supplied <code>OutputStream</code>. + * + * @param os XML <code>OutputStream</code>. + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream os) throws IOException { + + // set bytes for writing to output stream + byte contentBytes[] = docToBytes(contentDoc); + + os.write(contentBytes); + } + + + /** + * <p>Write out a <code>org.w3c.dom.Document</code> object into a + * <code>byte</code> array.</p> + * + * <p>TODO: remove dependency on com.sun.xml.tree.XmlDocument + * package!</p> + * + * @param Document DOM <code>Document</code> object. + * + * @return <code>byte</code> array of DOM <code>Document</code> + * object. + * + * @throws IOException If any I/O error occurs. + */ + private byte[] docToBytes(Document doc) + throws IOException { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + java.lang.reflect.Constructor con; + java.lang.reflect.Method meth; + + String domImpl = doc.getClass().getName(); + + /* + * We may have multiple XML parsers in the Classpath. + * Depending on which one is first, the actual type of + * doc may vary. Need a way to find out which API is being + * used and use an appropriate serialization method. + */ + try { + // First of all try for JAXP 1.0 + if (domImpl.equals("com.sun.xml.tree.XmlDocument")) { + System.out.println("Using JAXP"); + Class jaxpDoc = Class.forName("com.sun.xml.tree.XmlDocument"); + + // The method is in the XMLDocument class itself, not a helper + meth = jaxpDoc.getMethod("write", + new Class[] { Class.forName("java.io.OutputStream") } ); + + meth.invoke(doc, new Object [] { baos } ); + } + else if (domImpl.equals("org.apache.crimson.tree.XmlDocument")) + { + System.out.println("Using Crimson"); + Class crimsonDoc = Class.forName("org.apache.crimson.tree.XmlDocument"); + // The method is in the XMLDocument class itself, not a helper + meth = crimsonDoc.getMethod("write", + new Class[] { Class.forName("java.io.OutputStream") } ); + + meth.invoke(doc, new Object [] { baos } ); + } + else if (domImpl.equals("org.apache.xerces.dom.DocumentImpl") + || domImpl.equals("org.apache.xerces.dom.DeferredDocumentImpl")) { + System.out.println("Using Xerces"); + // Try for Xerces + Class xercesSer = + Class.forName("org.apache.xml.serialize.XMLSerializer"); + + // Get the OutputStream constructor + // May want to use the OutputFormat parameter at some stage too + con = xercesSer.getConstructor(new Class [] + { Class.forName("java.io.OutputStream"), + Class.forName("org.apache.xml.serialize.OutputFormat") } ); + + + // Get the serialize method + meth = xercesSer.getMethod("serialize", + new Class [] { Class.forName("org.w3c.dom.Document") } ); + + + // Get an instance + Object serializer = con.newInstance(new Object [] { baos, null } ); + + + // Now call serialize to write the document + meth.invoke(serializer, new Object [] { doc } ); + } + else { + // We dont have another parser + throw new IOException("No appropriate API (JAXP/Xerces) to serialize XML document: " + domImpl); + } + } + catch (ClassNotFoundException cnfe) { + throw new IOException(cnfe.toString()); + } + catch (Exception e) { + // We may get some other errors, but the bottom line is that + // the steps being executed no longer work + throw new IOException(e.toString()); + } + + byte bytes[] = baos.toByteArray(); + + return bytes; + } + + + /** + * Initializes a new DOM <code>Document</code> with the content + * containing minimum XML tags. + * + * @throws IOException If any I/O error occurs. + */ + public final void initContentDOM() throws IOException { + contentDoc = createDOM(""); + + } + + /** + * <p>Creates a new DOM <code>Document</code> containing minimum + * OpenOffice XML tags.</p> + * + * <p>This method uses the subclass + * <code>getOfficeClassAttribute</code> method to get the + * attribute for <i>office:class</i>.</p> + * + * @param rootName root name of <code>Document</code>. + * + * @throws IOException If any I/O error occurs. + */ + private final Document createDOM(String rootName) throws IOException { + + Document doc = null; + + try { + + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.newDocument(); + + } catch (ParserConfigurationException ex) { + System.out.println("Error:"+ ex); + + + } + + Element root = (Element) doc.createElement(rootName); + doc.appendChild(root); + + + return doc; + } + +} + + + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/dom/build.xml b/xmerge/java/org/openoffice/xmerge/converter/dom/build.xml new file mode 100644 index 000000000000..b99aa17f9857 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/dom/build.xml @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxc_dom" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxc_dom"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/dom"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set whether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/DOMDocument.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/dom/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/dom/makefile.mk new file mode 100644 index 000000000000..84c4a4bf9d36 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/dom/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxc_dom +PRJ=../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/dom/package.html b/xmerge/java/org/openoffice/xmerge/converter/dom/package.html new file mode 100644 index 000000000000..bb88d22ce5a3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/dom/package.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + <title>org.openoffice.xmerge.converter.palm package</title> + +</head> + <body bgcolor="white"> +<p>Provides classes for converting basic document types to/from a <code> +DOMDocument</code> object, which can be used by the framework. </p> +<p>This package provides classes that handle the writing of data to an <code> + OutputStream</code> object for the {@link org.openoffice.xmerge.DocumentSerializer +DocumentSerializer} interface for; as well as the reading of data from an +<code>InputStream</code> object for the framework's {@link org.openoffice.xmerge.DocumentDeserializer +DocumentDeserializer} interface. Both these framework interfaces are simply +converters from server-side documents to device specific documents and vice-versa. + </p> +<a name="streamformat"> +<h2></h2> +</a> +<p></p> +<h2>Important Note</h2> +<p>Methods in these classes are not thread safe for performance reasons. +Users of these classes will have to make sure that the usage of these classes +are done in a proper manner. Possibly more on this later.</p> +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java b/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java new file mode 100644 index 000000000000..4c0ab0ffaeaf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java @@ -0,0 +1,472 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PalmDB.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.palm; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.DataOutputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +/** + * <p>This class contains data for a single Palm database for use during + * a conversion process.</p> + * + * <p>It contains zero or more <code>Record</code> objects stored in an + * array. The index of the <code>Record</code> object in the array is + * the <code>Record</code> id or number for that specific <code>Record</code> object. + * Note that this class does not check for maximum number of Records + * allowable in an actual PDB.</p> + * + * <p>This class also contains the PDB name associated with the Palm + * database it represents. A PDB name consists of 32 bytes of a + * certain encoding (extended ASCII in this case).</p> + * + * <p>The non default constructors take in a name parameter which may not + * be the exact PDB name to be used. The name parameter in + * <code>String</code> or <code>byte</code> array are converted to an exact + * <code>NAME_LENGTH</code> byte array. If the length of the name is less + * than <code>NAME_LENGTH</code>, it is padded with '\0' characters. If it + * is more, it gets truncated. The last character in the resulting byte + * array is always a '\0' character. The resulting byte array is stored in + * <code>bName</code>, and a corresponding String object <code>sName</code> + * that contains characters without the '\0' characters.</p> + * + * <p>The {@link #write write} method is called within the + * {@link org.openoffice.xmerge.converter.palm.PalmDocument#write + * PalmDocument.write} method for writing out its data to the <code>OutputStream</code> + * object.</p> + * + * <p>The {@link #read read} method is called within the + * {@link org.openoffice.xmerge.converter.palm.PalmDocument#read + * PalmDocument.read} method for reading in its data from the <code>InputStream</code> + * object.</p> + * + * @author Akhil Arora, Herbie Ong + * @see PalmDocument + * @see Record + */ + +public final class PalmDB { + + /* Backup attribute for a PDB. This corresponds to dmHdrAttrBackup. */ + public final static short PDB_HEADER_ATTR_BACKUP = 0x0008; + + /** Number of bytes for the name field in the PDB. */ + public final static int NAME_LENGTH = 32; + + /** List of <code>Record</code> objects. */ + private Record[] records; + + /** PDB name in bytes. */ + private byte[] bName = null; + + /** PDB name in String. */ + private String sName = null; + + /** Creator ID. */ + private int creatorID = 0; + + /** Type ID */ + private int typeID = 0; + + /** + * PDB version. Palm UInt16. + * It is treated as a number here, since there is no unsigned 16 bit + * in Java, int is used instead, but only 2 bytes are written out or + * read in. + */ + private int version = 0; + + /** + * PDB attribute - flags for the database. + * Palm UInt16. Unsignedness should be irrelevant. + */ + private short attribute = 0; + + + /** + * Default constructor. + * + * @param creatorID The PDB Creator ID. + * @param typeID The PDB Type ID. + * @param version The PDB header version. + * @param attribute The PDB header attribute. + */ + public PalmDB(int creatorID, int typeID, int version, short attribute) { + + records = new Record[0]; + setAttributes(creatorID, typeID, version, attribute); + } + + + /** + * Constructor to create <code>PalmDB</code> object with + * <code>Record</code> objects. <code>recs.length</code> + * can be zero for an empty PDB. + * + * @param name Suggested PDB name in a <code>String</code>. + * @param creatorID The PDB Creator ID. + * @param typeID The PDB Type ID. + * @param version The PDB header version. + * @param attribute The PDB header attribute. + * @param recs Array of <code>Record</code> objects. + * + * @throws UnsupportedEncodingException If <code>name</code> is + * not properly encoded. + * @throws NullPointerException If <code>recs</code> is null. + */ + public PalmDB(String name, int creatorID, int typeID, int version, + short attribute, Record[] recs) + throws UnsupportedEncodingException { + + this(name.getBytes(PdbUtil.ENCODING), creatorID, typeID, version, + attribute, recs); + } + + + /** + * Constructor to create object with <code>Record</code> + * objects. <code>recs.length</code> can be zero for an + * empty PDB. + * + * @param name Suggested PDB name in a <code>byte</code> + * array. + * @param creatorID The PDB Creator ID. + * @param typeID The PDB Type ID. + * @param version The PDB header version. + * @param attribute The PDB header attribute. + * @param recs Array of <code>Record</code> objects. + * + * @throws UnsupportedEncodingException If <code>name</code> is + * not properly encoded. + * @throws NullPointerException If recs is null. + */ + public PalmDB(byte[] name, int creatorID, int typeID, int version, + short attribute, Record[] recs) throws UnsupportedEncodingException { + + store(name); + + records = new Record[recs.length]; + System.arraycopy(recs, 0, records, 0, recs.length); + setAttributes(creatorID, typeID, version, attribute); + } + + + /** + * Set the attributes for the <code>PalmDB</code> object. + * + * @param creatorID The PDB Creator ID. + * @param typeID The PDB Type ID. + * @param version The PDB header version. + * @param attribute The PDB header attribute. + */ + public void setAttributes (int creatorID, int typeID, int version, short attribute) { + this.creatorID = creatorID; + this.typeID = typeID; + this.version = version; + this.attribute = attribute; + } + + + /** + * This private method is mainly used by the constructors above. + * to store bytes into name and also create a <code>String</code> + * representation. and also by the <code>read</code> method. + * + * TODO: Note that this method assumes that the <code>byte</code> + * array parameter contains one character per <code>byte</code>, + * else it would truncate improperly. + * + * @param bytes PDB name in <code>byte</code> array. + * + * @throws UnsupportedEncodingException If ENCODING is + * not supported. + */ + private void store(byte[] bytes) throws UnsupportedEncodingException { + + // note that this will initialize all bytes in name to 0. + bName = new byte[NAME_LENGTH]; + + // determine minimum length to copy over from bytes to bName. + // Note that the last byte in bName has to be '\0'. + + int lastIndex = NAME_LENGTH - 1; + + int len = (bytes.length < lastIndex)? bytes.length: lastIndex; + + int i; + + for (i = 0; i < len; i++) { + + if (bytes[i] == 0) { + break; + } + + bName[i] = bytes[i]; + } + + // set sName, no need to include the '\0' character. + sName = new String(bName, 0, i, PdbUtil.ENCODING); + } + + + /** + * Returns creator ID. + * + * @return The creator ID. + */ + public int getCreatorID() { + + return creatorID; + } + + + /** + * Returns type ID. + * + * @return The type ID. + */ + public int getTypeID() { + + return typeID; + } + + + /** + * Returns attribute flag. + * + * @return The attribute flag. + */ + public short getAttribute() { + + return attribute; + } + + + /** + * Returns version. + * + * @return The version. + */ + public int getVersion() { + + return version; + } + + + /** + * Return the number of Records contained in this + * PDB <code>PalmDB</code> object. + * + * @return Number of <code>Record</code> objects. + */ + public int getRecordCount() { + + return records.length; + } + + + /** + * Return the specific <code>Record</code> object associated + * with the <code>Record</code> number. + * + * @param index <code>Record</code> index number. + * + * @return The <code>Record</code> object in the specified index + * + * @throws ArrayIndexOutOfBoundsException If index is out of bounds. + */ + public Record getRecord(int index) { + + return records[index]; + } + + + /** + * Return the list of <code>Record</code> objects. + * + * @return The array of <code>Record</code> objects. + */ + public Record[] getRecords() { + + return records; + } + + /** + * Return the PDB name associated with this object. + * + * @return The PDB name. + */ + public String getPDBNameString() { + + return sName; + } + + + /** + * Return the PDB name associated with this object in + * <code>byte</code> array of exact length of 32 bytes. + * + * @return The PDB name in <code>byte</code> array of + * length 32. + */ + public byte[] getPDBNameBytes() { + + return bName; + } + + + /** + * Write out the number of Records followed by what + * will be written out by each <code>Record</code> object. + * + * @param os The <code>OutputStream</code> to write the + * object. + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream os) throws IOException { + + DataOutputStream out = new DataOutputStream(os); + + // write out PDB name + out.write(bName); + + // write out 2 bytes for number of records + out.writeShort(records.length); + + // let each Record object write out its own info. + for (int i = 0; i < records.length; i++) + records[i].write(out); + } + + /** + * Read the necessary data to create a PDB from + * the <code>InputStream</code>. + * + * @param is The <code>InputStream</code> to read data + * in order to restore the object. + * + * @throws IOException If any I/O error occurs. + */ + public void read(InputStream is) throws IOException { + + DataInputStream in = new DataInputStream(is); + + // read in the PDB name. + byte[] bytes = new byte[NAME_LENGTH]; + in.readFully(bytes); + store(bytes); + + // read in number of records + int nrec = in.readUnsignedShort(); + records = new Record[nrec]; + + // read in the Record infos + for (int i = 0; i < nrec; i++) { + + records[i] = new Record(); + records[i].read(in); + } + } + + /** + * Override equals method of <code>Object</code>. + * + * Two <code>PalmDB</code> objects are equal if they contain + * the same information, i.e. PDB name and Records. + * + * This is used primarily for testing purposes only for now. + * + * @param obj A <code>PalmDB</code> <code>Object</code> to + * compare. + * + * @return true if <code>obj</code> is equal to this, otherwise + * false. + */ + public boolean equals(Object obj) { + + boolean bool = false; + + if (obj instanceof PalmDB) { + + PalmDB pdb = (PalmDB) obj; + + checkLabel: { + + // compare sName + + if (!sName.equals(pdb.sName)) { + + break checkLabel; + } + + // compare bName + + if (bName.length != pdb.bName.length) { + + break checkLabel; + } + + for (int i = 0; i < bName.length; i++) { + + if (bName[i] != pdb.bName[i]) { + + break checkLabel; + } + } + + // compare each Record + + if (records.length != pdb.records.length) { + + break checkLabel; + } + + for (int i = 0; i < records.length; i++) { + + if (!records[i].equals(pdb.records[i])) { + + break checkLabel; + } + } + + // all checks done + bool = true; + } + } + + return bool; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java b/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java new file mode 100644 index 000000000000..d26b2d5ef7e9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java @@ -0,0 +1,183 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PalmDocument.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.palm; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ByteArrayOutputStream; + +import java.io.OutputStream; +import java.io.Reader; +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; + +import org.openoffice.xmerge.Document; + +/** + * <p> A <code>PalmDocument</code> is palm implementaion of the + * <code>Docuemnt</code> interface.</p> + * + * <p>This implementation allows the Palm device format to be + * read via an <code>InputStream</code> and written via an + * <code>OutputStream</code>.</p> + * + * @author Martin Maher + */ + +public class PalmDocument + implements Document { + + /** + * The internal representation of a pdb. + */ + private PalmDB pdb; + + /** + * The file name. + */ + private String fileName; + + /** + * Constructor to create a <code>PalmDocument</code> + * from an <code>InputStream</code>. + * + * @param is <code>InputStream</code> containing a PDB. + * + * @throws IOException If any I/O error occurs. + */ + public PalmDocument(InputStream is) throws IOException { + read(is); + } + + + /** + * Constructor to create a <code>PalmDocument</code> with + * <code>Record</code> objects. <code>recs.length</code> + * can be zero for an empty PDB. + * + * @param name Suggested PDB name in <code>String</code>. + * @param creatorID The PDB Creator ID. + * @param typeID The PDB Type ID. + * @param version The PDB header version. + * @param attribute The PDB header attribute. + * @param recs Array of <code>Record</code> objects. + * + * @throws NullPointerException If <code>recs</code> is null. + */ + public PalmDocument(String name, int creatorID, int typeID, int version, + short attribute, Record[] recs) + throws UnsupportedEncodingException { + pdb = new PalmDB(name, creatorID, typeID, version, attribute, recs); + fileName = pdb.getPDBNameString(); + } + + + /** + * Reads in a file from the <code>InputStream</code>. + * + * @param is <code>InputStream</code> to read in its content. + * + * @throws IOException If any I/O error occurs. + */ + + public void read(InputStream is) throws IOException { + PdbDecoder decoder = new PdbDecoder(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int b; + while (is.available()>0) + { + baos.write(is.read()); + } + byte[] bytearr = baos.toByteArray(); + pdb = decoder.parse(bytearr); + fileName = pdb.getPDBNameString(); + } + + + /** + * Writes the <code>PalmDocument</code> to an <code>OutputStream</code>. + * + * @param is The <code>OutputStream</code> to write the content. + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream os) throws IOException { + PdbEncoder encoder = new PdbEncoder(pdb); + encoder.write(os); + } + + + /** + * Returns the <code>PalmDB</code> contained in this object. + * + * @return The <code>PalmDB</code>. + */ + public PalmDB getPdb() { + return pdb; + } + + + /** + * Sets the <code>PalmDocument</code> to a new <code>PalmDB</code> + * value. + * + * @param pdb The new <code>PalmDB</code> value. + */ + public void setPdb(PalmDB pdb) { + this.pdb = pdb; + + String name = pdb.getPDBNameString(); + fileName = name; + } + + + /** + * Returns the name of the file. + * + * @return The name of the file represented in the + * <code>PalmDocument</code>. + */ + public String getFileName() { + return fileName + ".pdb"; + } + + + /** + * Returns the <code>Document</code> name. + * + * @return The <code>Document</code> name. + */ + public String getName() { + return fileName; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java new file mode 100755 index 000000000000..0eed10bd3417 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java @@ -0,0 +1,238 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PdbDecoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.palm; + +import java.io.RandomAccessFile; +import java.io.IOException; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; + +import org.openoffice.xmerge.converter.palm.*; + +/** + * <p>Provides functionality to decode a PDB formatted file into + * a <code>PalmDB</code> object given an <code>InputStream</code>. + * This class is only used by the <code>PalmDB</code> object.</p> + * + * <p>Sample usage:</p> + * + * <blockquote><pre><code> + * PdbDecoder decoder = new PdbDecoder("sample.pdb"); + * PalmDB palmDB = decoder.parse(); + * </code></pre></blockquote> + * + * <p>This decoder has the following assumptions on the PDB file:</p> + * + * <p><ol> + * <li>There is only one RecordList section in the PDB.</li> + * <li>The <code>Record</code> indices in the RecordList are sorted in + * order, i.e. the first <code>Record</code> index refers to + * <code>Record</code> 0, and so forth.</li> + * <li>The raw <code>Record</code> in the <code>Record</code> section + * are sorted as well in order, i.e. first <code>Record</code> + * comes ahead of second <code>Record</code>, etc.</li> + * </ol></p> + * + * <p>Other decoders assume these as well.</p> + * + * @author Herbie Ong + * @see PalmDB + * @see Record + */ +public final class PdbDecoder { + + + /** + * <p>This method decodes a PDB file into a <code>PalmDB</code> + * object.</p> + * + * <p>First, the header data is read using the <code>PdbHeader</code> + * <code>read</code> method. Next, the RecordList section is + * read and the <code>Record</code> offsets are stored for use when + * parsing the Records. Based on these offsets, the bytes + * corresponding to each <code>Record</code> are read and each is + * stored in a <code>Record</code> object. Lastly, the data is + * used to create a <code>PalmDB</code> object.</p> + * + * @param fileName PDB file name. + * + * @throws IOException If I/O error occurs. + */ + public PalmDB parse(String fileName) throws IOException { + + RandomAccessFile file = new RandomAccessFile(fileName, "r"); + + // read the PDB header + PdbHeader header = new PdbHeader(); + header.read(file); + + Record recArray[] = new Record[header.numRecords]; + if (header.numRecords != 0) { + + // read in the record indices + offsets + + int recOffset[] = new int[header.numRecords]; + byte recAttrs[] = new byte[header.numRecords]; + + for (int i = 0; i < header.numRecords; i++) { + + recOffset[i] = file.readInt(); + + // read in attributes (1 byte) + unique id (3 bytes) + // take away the unique id, store the attributes + + int attr = file.readInt(); + recAttrs[i] = (byte) (attr >>> 24); + } + + + // read the records + + int len = 0; + byte[] bytes = null; + + int lastIndex = header.numRecords - 1; + + for (int i = 0; i < lastIndex; i++) { + + file.seek(recOffset[i]); + len = recOffset[i+1] - recOffset[i]; + bytes = new byte[len]; + file.readFully(bytes); + recArray[i] = new Record(bytes, recAttrs[i]); + } + + // last record + file.seek(recOffset[lastIndex]); + len = (int) file.length() - recOffset[lastIndex]; + bytes = new byte[len]; + file.readFully(bytes); + recArray[lastIndex] = new Record(bytes, recAttrs[lastIndex]); + + } + + file.close(); + + // create PalmDB and return it + PalmDB pdb = new PalmDB(header.pdbName, header.creatorID, + header.typeID, header.version, header.attribute, recArray); + + return pdb; + } + + /** + * <p>This method decodes a PDB file into a <code>PalmDB</code> + * object.</p> + * + * <p>First, the header data is read using the <code>PdbHeader</code> + * <code>read</code> method. Next, the RecordList section is + * read and the <code>Record</code> offsets are stored for use when + * parsing the Records. Based on these offsets, the bytes + * corresponding to each <code>Record</code> are read and each is + * stored in a <code>Record</code> object. Lastly, the data is + * used to create a <code>PalmDB</code> object.</p> + * + * @param b <code>byte[]</code> containing PDB. + * + * @throws IOException If I/O error occurs. + */ + + public PalmDB parse(byte[] b) throws IOException { + + ByteArrayInputStream bais = new ByteArrayInputStream(b); + DataInputStream dis = new DataInputStream(bais); + + // read the PDB header + + PdbHeader header = new PdbHeader(); + header.read(dis); + + Record recArray[] = new Record[header.numRecords]; + if (header.numRecords != 0) { + + // read in the record indices + offsets + + int recOffset[] = new int[header.numRecords]; + byte recAttrs[] = new byte[header.numRecords]; + + for (int i = 0; i < header.numRecords; i++) { + + recOffset[i] = dis.readInt(); + + // read in attributes (1 byte) + unique id (3 bytes) + // take away the unique id, store the attributes + + int attr = dis.readInt(); + recAttrs[i] = (byte) (attr >>> 24); + } + + // read the records + + int len = 0; + byte[] bytes = null; + + int lastIndex = header.numRecords - 1; + + for (int i = 0; i < lastIndex; i++) { + + //dis.seek(recOffset[i]); + dis.reset(); + dis.skip(recOffset[i]); + len = recOffset[i+1] - recOffset[i]; + bytes = new byte[len]; + dis.readFully(bytes); + recArray[i] = new Record(bytes, recAttrs[i]); + } + + // last record + + dis.reset(); + len = (int) dis.available() - recOffset[lastIndex]; + dis.skip(recOffset[lastIndex]); + bytes = new byte[len]; + dis.readFully(bytes); + recArray[lastIndex] = new Record(bytes, recAttrs[lastIndex]); + } + + + + // create PalmDB and return it + + PalmDB pdb = new PalmDB(header.pdbName, header.creatorID, + header.typeID, header.version, header.attribute, recArray); + + return pdb; + } + + + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java new file mode 100755 index 000000000000..5a1d81a475b9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java @@ -0,0 +1,199 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PdbEncoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.palm; + +import java.io.OutputStream; +import java.io.BufferedOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Date; + +/** + * <p>Provides functionality to encode a <code>PalmDB</code> object + * into a PDB formatted file given a file <code>OutputStream</code>. + * This class is only used by the <code>PalmDB</code> object.</p> + * + * <p>One needs to create one <code>PdbEncoder</code> object per + * <code>PalmDB</code> object to be encoded. This class keeps + * the PDB header data and functionality in the <code>PdbHeader</code> + * class.</p> + * + * <p>Sample usage:</p> + * + * <blockquote><pre><code> + * PdbEncoder encoder = new PdbEncoder(palmDB, "STRW", "data"); + * encoder.write(new FileOutputStream("sample.pdb")); + * </code></pre></blockquote> + * + * @author Herbie Ong + * @see PalmDB + * @see Record + */ +public final class PdbEncoder { + + /** PDB header. */ + private PdbHeader header = null; + + /** the PalmDB object. */ + private PalmDB db = null; + + /** + * The pattern for unique_id=0x00BABE(start). + */ + private final static int START_UNIQUE_ID = 0x00BABE; + + + /** + * Constructor. + * + * @param db The <code>PalmDB</code> to be encoded. + */ + public PdbEncoder(PalmDB db) { + + header = new PdbHeader(); + header.version = db.getVersion(); + + header.attribute = db.getAttribute(); + + this.db = db; + + header.pdbName = db.getPDBNameBytes(); + header.creatorID = db.getCreatorID(); + header.typeID = db.getTypeID(); + + // set the following dates to current date + Date date = new Date(); + header.creationDate = (date.getTime() / 1000) + PdbUtil.TIME_DIFF; + header.modificationDate = header.creationDate; + + header.numRecords = db.getRecordCount(); + } + + + /** + * <p>Write out a PDB into the given <code>OutputStream</code>.</p> + * + * <p>First, write out the header data by using the + * <code>PdbHeader</code> <code>write</code> method. Next, + * calculate the RecordList section and write it out. + * Lastly, write out the bytes corresponding to each + * <code>Record</code>.</p> + * + * <p>The RecordList section contains a list of + * <code>Record</code> index info, where each <code>Record</code> + * index info contains:</p> + * + * <p><ul> + * <li>4 bytes local offset of the <code>Record</code> from the + * top of the PDB.</li> + * <li>1 byte of <code>Record</code> attribute.</li> + * <li>3 bytes unique <code>Record</code> ID.</li> + * </ul></p> + * + * <p>There should be a total of <code>header.numRecords</code> + * of <code>Record</code> index info</p>. + * + * @param os <code>OutputStream</code> to write out PDB. + * + * @throws IOException If I/O error occurs. + */ + public void write(OutputStream os) throws IOException { + + BufferedOutputStream bos = new BufferedOutputStream(os); + DataOutputStream dos = new DataOutputStream(bos); + + // write out the PDB header + header.write(dos); + + if (header.numRecords > 0) { + + // compute for recOffset[] + + int recOffset[] = new int[header.numRecords]; + byte recAttr[] = new byte[header.numRecords]; + + // first recOffset will be at PdbUtil.HEADER_SIZE + all the + // record indices (@ 8 bytes each) + recOffset[0] = PdbUtil.HEADER_SIZE + (header.numRecords * 8); + + int lastIndex = header.numRecords - 1; + + for (int i = 0; i < lastIndex; i++) { + + Record rec = db.getRecord(i); + int size = rec.getSize(); + recAttr[i] = rec.getAttributes(); + + recOffset[i+1] = recOffset[i] + size; + } + + // grab the last record's attribute. + + Record lastRec = db.getRecord(lastIndex); + recAttr[lastIndex] = lastRec.getAttributes(); + + + int uid = START_UNIQUE_ID; + + for (int i = 0; i < header.numRecords; i++) { + + // write out each record offset + dos.writeInt(recOffset[i]); + + // write out record attribute (recAttr) and + // unique ID (uid) in 4 bytes (int) chunk. + // unique ID's have to be unique, thus + // increment each time. + int attr = (((int) recAttr[i]) << 24 ); + attr |= uid; + dos.writeInt(attr); + uid++; + } + + // write out the raw records + + for (int i = 0; i < header.numRecords; i++) { + + Record rec = db.getRecord(i); + byte bytes[] = rec.getBytes(); + dos.write(bytes); + } + + } else { + + // placeholder bytes if there are no records in the list. + dos.writeShort(0); + } + + dos.flush(); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java new file mode 100755 index 000000000000..40a54730a320 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java @@ -0,0 +1,165 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PdbHeader.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.palm; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** + * <p>Class used only internally by <code>PdbEncoder</code> and + * <code>PdbDecoder</code> to store, read and write a PDB header.</p> + * + * <p>Note that fields are intended to be accessible only at the + * package level.</p> + * + * <p>Some of the fields are internally represented using a + * larger type since Java does not have unsigned types. + * Some are not since they are not relevant for now. + * The <code>read</code> and <code>write</code> methods should + * handle them properly.</p> + * + * @author Herbie Ong + * @see PalmDB + * @see Record + */ +final class PdbHeader { + + + /** Name of the database. 32 bytes. */ + byte[] pdbName = null; + + /** + * Flags for the database. Palm UInt16. Unsignedness should be + * irrelevant. + */ + short attribute = 0; + + /** Application-specific version for the database. Palm UInt16. */ + int version = 0; + + /** Date created. Palm UInt32. */ + long creationDate = 0; + + /** Date last modified. Palm UInt32. */ + long modificationDate = 0; + + /** Date last backup. Palm UInt32. */ + long lastBackupDate = 0; + + /** + * Incremented every time a <code>Record</code> is + * added, deleted or modified. Palm UInt32. + */ + long modificationNumber = 0; + + /** Optional field. Palm UInt32. Unsignedness should be irrelevant. */ + int appInfoID = 0; + + /** Optional field. Palm UInt32. Unsignedness should be irrelevant. */ + int sortInfoID = 0; + + /** Database type ID. Palm UInt32. Unsignedness should be irrelevant. */ + int typeID = 0; + + /** Database creator ID. Palm UInt32. Unsignedness should be irrelevant. */ + int creatorID = 0; + + /** ??? */ + int uniqueIDSeed = 0; + + /** See numRecords. 4 bytes. */ + int nextRecordListID = 0; + + /** + * Number of Records stored in the database header. + * If all the <code>Record</code> entries cannot fit in the header, + * then <code>nextRecordList</code> has the local ID of a + * RecordList that contains the next set of <code>Record</code>. + * Palm UInt16. + */ + int numRecords = 0; + + + /** + * Read in the data for the PDB header. Need to + * preserve the unsigned value for some of the fields. + * + * @param di A <code>DataInput</code> object. + * + * @throws IOException If any I/O error occurs. + */ + public void read(DataInput in) throws IOException { + + pdbName = new byte[PalmDB.NAME_LENGTH]; + in.readFully(pdbName); + attribute = in.readShort(); + version = in.readUnsignedShort(); + creationDate = ((long) in.readInt()) & 0xffffffffL; + modificationDate = ((long) in.readInt()) & 0xffffffffL; + lastBackupDate = ((long) in.readInt()) & 0xffffffffL; + modificationNumber = ((long) in.readInt()) & 0xffffffffL; + appInfoID = in.readInt(); + sortInfoID = in.readInt(); + creatorID = in.readInt(); + typeID = in.readInt(); + uniqueIDSeed = in.readInt(); + nextRecordListID = in.readInt(); + numRecords = in.readUnsignedShort(); + } + + + /** + * Write out PDB header data. + * + * @param out A <code>DataOutput</code> object. + * + * @throws IOException If any I/O error occurs. + */ + public void write(DataOutput out) throws IOException { + + out.write(pdbName); + out.writeShort(attribute); + out.writeShort(version); + out.writeInt((int) creationDate); + out.writeInt((int) modificationDate); + out.writeInt((int) lastBackupDate); + out.writeInt((int) modificationNumber); + out.writeInt(appInfoID); + out.writeInt(sortInfoID); + out.writeInt(typeID); + out.writeInt(creatorID); + out.writeInt(uniqueIDSeed); + out.writeInt(nextRecordListID); + out.writeShort(numRecords); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java new file mode 100755 index 000000000000..69cae6d69e58 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java @@ -0,0 +1,109 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PdbUtil.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.palm; + +/** + * Contains common static methods and constants for use within the package. + * + * @author Herbie Ong + */ +public final class PdbUtil { + + /** Difference in seconds from Jan 01, 1904 to Jan 01, 1970. */ + final static long TIME_DIFF = 2082844800; + + /** Encoding scheme used. */ + final static String ENCODING = "8859_1"; + + /** Size of a PDB header in bytes. */ + final static int HEADER_SIZE = 78; + + + /** + * <p>This method converts a 4 letter string into the Palm ID + * integer.</p> + * + * <p>It is normally used to convert the Palm creator ID string into + * the integer version of it. Also use for data types, etc.</p> + * + * @param s Four character <code>String</code>. + * + * @return Palm ID representing the <code>String</code>. + * + * @throws ArrayIndexOutOfBoundsException If <code>String</code> + * parameter contains less than four characters. + */ + public static int intID(String s) { + + int id = -1; + int temp = 0; + + // grab the first char and put it in the high bits + // note that we only want 8 lower bits of it. + temp = (int) s.charAt(0); + id = temp << 24; + + // grab the second char and add it in. + temp = ((int) s.charAt(1)) & 0x00ff; + id += temp << 16; + + // grab the second char and add it in. + temp = ((int) s.charAt(2)) & 0x00ff; + id += temp << 8; + + // grab the last char and add it in + id += ((int) s.charAt(3)) & 0x00ff; + + return id; + } + + + /** + * This method converts an integer into a <code>String</code> + * given the Palm ID format. + * + * @param i Palm ID. + * + * @return <code>String</code> representation. + */ + public static String stringID(int i) { + + char ch[] = new char[4]; + ch[0] = (char) (i >>> 24); + ch[1] = (char) ((i >> 16) & 0x00ff); + ch[2] = (char) ((i >> 8) & 0x00ff); + ch[3] = (char) (i & 0x00ff); + + return new String(ch); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java b/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java new file mode 100644 index 000000000000..41b2a289a8c5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java @@ -0,0 +1,219 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Record.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.palm; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.DataOutputStream; +import java.io.DataInputStream; +import java.io.IOException; + +/** + * <p>Contains the raw bytes for a <code>Record</code> in a PDB.</p> + * + * <p>Note that it is not associated with a <code>Record</code> number + * or ID.</p> + * + * @author Akhil Arora, Herbie Ong + * @see PalmDocument + * @see PalmDB + */ +public final class Record { + + /** <code>Record</code> <code>byte</code> array. */ + private byte[] data; + + /** <code>Record</code> attributes. */ + private byte attributes = 0; + + + /** + * Default constructor. + */ + public Record() { + + data = new byte[0]; + } + + + /** + * <p>Constructor to create a <code>Record</code> filled with + * bytes.</p> + * + * <p>Note that this does not check for 64k <code>Record</code> + * sizes. User of this class must check for that.</p> + * + * @param d <code>byte</code> array contents for this object. + */ + public Record(byte[] d) { + + this(d, (byte) 0); + } + + + /** + * <p>Constructor to create a <code>Record</code> filled with + * bytes and assign <code>Record</code> attributes.</p> + * + * <p>Note that this does not check for 64k <code>Record</code> + * sizes. User of this class must check for that.</p> + * + * @param d <code>byte</code> array contents for this object. + * @param attrs <code>Record</code> attributes. + */ + public Record(byte[] d, byte attrs) { + + data = new byte[d.length]; + attributes = attrs; + System.arraycopy(d, 0, data, 0, d.length); + } + + + /** + * This method returns the number of bytes in this object. + * + * @return Number of bytes in this object. + */ + public int getSize() { + + return data.length; + } + + + /** + * This method returns the contents of this <code>Object</code>. + * + * @return Contents in <code>byte</code> array + */ + public byte[] getBytes() { + + return data; + } + + + /** + * <p>This method returns the <code>Record</code> attributes.</p> + * + * <blockquote><pre> + * <code>Record</code> attributes consists of (from high to low bit) + * + * delete (1) - dirty (1) - busy (1) - secret (1) - category (4) + * </pre></blockquote> + * + * @return <code>Record</code> attribute. + */ + public byte getAttributes() { + + return attributes; + } + + + /** + * Write out the <code>Record</code> attributes and + * <code>Record</code> length followed by the data in this + * <code>Record</code> object. + * + * @param out The <code>OutputStream</code> to write the object. + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream outs) throws IOException { + + DataOutputStream out = new DataOutputStream(outs); + out.writeByte(attributes); + out.writeShort(data.length); + out.write(data); + } + + + /** + * Read the necessary data to create a PDB from + * the <code>InputStream</code>. + * + * @param in The <code>InputStream</code> to read data from + * in order to restore the <code>object</code>. + * + * @throws IOException If any I/O error occurs. + */ + public void read(InputStream ins) throws IOException { + + DataInputStream in = new DataInputStream(ins); + attributes = in.readByte(); + int len = in.readUnsignedShort(); + data = new byte[len]; + in.readFully(data); + } + + + /** + * <p>Override equals method of <code>Object</code>.</p> + * + * <p>Two <code>Record</code> objects are equal if they contain + * the same bytes in the array and the same attributes.</p> + * + * <p>This is used primarily for testing purposes only for now.</p> + * + * @param obj A <code>Record</code> object to compare with + * + * @return true if obj is equal, otherwise false. + */ + public boolean equals(Object obj) { + + boolean bool = false; + + if (obj instanceof Record) { + + Record rec = (Record) obj; + + checkLabel: { + + if (rec.getAttributes() != attributes) { + + break checkLabel; + } + + if (rec.getSize() == data.length) { + + for (int i = 0; i < data.length; i++) { + + if (data[i] != rec.data[i]) { + break checkLabel; + } + } + + bool = true; + } + } + } + return bool; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/build.xml b/xmerge/java/org/openoffice/xmerge/converter/palm/build.xml new file mode 100644 index 000000000000..21e3905c1445 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/build.xml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxc_palm" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxc_palm"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/palm"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + </path> + + <!-- set whether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/PalmDB.java"/> + <include name="${package}/PdbDecoder.java"/> + <include name="${package}/PdbEncoder.java"/> + <include name="${package}/PdbHeader.java"/> + <include name="${package}/PdbUtil.java"/> + <include name="${package}/Record.java"/> + <include name="${package}/PalmDocument.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/palm/makefile.mk new file mode 100644 index 000000000000..23caa32f98a3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxc_palm +PRJ=../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/package.html b/xmerge/java/org/openoffice/xmerge/converter/palm/package.html new file mode 100644 index 000000000000..89fbd4580c9c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/package.html @@ -0,0 +1,144 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.palm package</title> +</head> + +<body bgcolor="white"> + +<p>Provides classes for converting Palm database data to/from a +<code>PalmDocument</code> object, which can be used by the framework. + +<p>This package provides classes that handle the writing of data to +an <code>OutputStream</code> object for the +{@link org.openoffice.xmerge.DocumentSerializer DocumentSerializer} +interface for; as well as the reading of data from an <code>InputStream</code> +object for the framework's +{@link org.openoffice.xmerge.DocumentDeserializer DocumentDeserializer} +interface. Both these framework interfaces are simply converters from +server-side documents to device specific documents and vice-versa. +Since all Palm databases have a general record oriented format, a Palm +database converter specific I/O stream format is specified for the Palm +sync client application to handle the byte stream in a generic way. +This also means that Palm database converters should read and/or write +using this I/O stream format as specified in the next section.</p> + +<a name="streamformat"> +<h2>Palm database converter specific I/O stream format</h2> +</a> + +<p>Note that the format of the byte stream is not exactly that of a PDB +file encoding. It does not need to contain the PDB header information +nor record indices section. Instead, it contains the following ...</p> + +<pre> + set header + 4 bytes - creator id + 4 bytes - type id + 2 bytes - PDB header version + 2 bytes - PDB header attribute + unsigned 2 bytes - number of PDB data to follow + + for each PDB, + 32 bytes - name of PDB i + unsigned 2 bytes - number of records in PDB i + + for each record contained in PDB i, + 1 byte - record attributes + unsigned 2 bytes - size of record j in PDB i + x bytes - data +</pre> + +<p>Note that each PDB section is appended by another if there is more +than one.</p> + +<p>Since the <code>PalmDocument</code> class takes care of the writing +and reading of this format through its <code>write</code> and +<code>read</code> methods, respectively, this format shall also be +referred to as the <b>PalmDocument stream format</b>.</p> + +<h2>Usage of the classes for the specified I/O stream</h2> + +<p>When converting from a server document to device document(s), the +framework requires writing the device document(s) to an +<code>OutputStream</code> object via the <code>DocumentSerializer</code> +interface. Note that a single server document may be converted +into multiple PDB's on the Palm device. Each worksheet in the document +is converted into a <code>PalmDocument</code> . Thus, if there is more +than one worksheet in the document, more than one <code>PalmDocument</code> +will be produced by the <code>DocumentSerializer</code>.</p> + +<p>A <code>DocumentSerializer</code> creates a <code>ConvertData</code> object, +which contains all of the <code>PalmDocuments</code>. The +{@link org.openoffice.xmerge.converter.palm.PalmDocument#write write} +method to write to the given <code>OutputStream</code>. The <code>PalmDocument</code> +object will take care of writing the data in the +<a href=#streamformat>specified format</a>.</p> + +<p>A <code>DocumentDeserializer</code> can use the <code>PalmDocument</code> object's +{@link org.openoffice.xmerge.converter.palm.PalmDocument#read read} +method to fill in all the <code>PalmDocument</code> object's data.</p> + +<h2>PDB file encoding/decoding</h2> + +<p>The <code>PalmDocument</code> object's read and write functions are provided +by the <code>PdbDecoder</code> and <code>PdbEncoder</code> objects. The +<code>PdbEncoder</code> class provides the functionality of encoding a +<code>PalmDB</code> object into an <code>InputStream</code>, while the +<code>PdbDecoder</code> class provides the functionality of decoding a +PDB file into an <code>OutputStream</code>.</p> + +<p>Refer to the class description of each for usage.</p> + +<h2>Important Note</h2> + +<p>Methods in these classes are not thread safe for performance reasons. +Users of these classes will have to make sure that the usage of these classes +are done in a proper manner. Possibly more on this later.</p> + +<h2>TODO list</h2> + +<p><ol> +<li>Merge the PalmDB, PdbDecoder and PdbEncoder classes into the + PalmDocument class.</li> +<li>After reading more on the palm file format spec, I realized + that there are certain optional fields that may need to be addressed + still, like the appInfo block and sortInfo block.</li> +<li>The current PdbDecoder only returns a PalmDB object. There are other + information that we may want to expose from the PDB decoding process.</li> +<li>Investigate on different language encoding on the Palm and how that + affects the PDB name.</li> +</ol></p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/README b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/README new file mode 100644 index 000000000000..924f32fe0824 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/README @@ -0,0 +1,50 @@ +The following is an outline of the usage of this test suite. + +Requirements +^^^^^^^^^^^^ +The following are required for these qa scripts to run correctly. + 1. POSE: the Palm OS Emulator. This is available from the PalmOS website. + 2. A Palm pilot rom. Also available from Palm. + 3. Compiled xmerge jar files (xmerge.jar, aportisdoc.jar etc.) + 4. Xerces.jar: required by the xmerge framework. This is available from org.apache.com. + + + +Test directory Contents +^^^^^^^^^^^^^^^^^^^^^^^ +This test environment consists on 3 directories. + 1. bin : This contains some helper scripts that are used by the test environment but can be used in a standalone fashion. + 2. qa : This directory contains the files necessary to run the POSE emulator and to compare this results of tests with a set of verified (golden-data) files. + 3. qa-wrapper: This directory contains some wrapper scripts and environment files, that allow a user to change the environment settings, without have to change the POSE control code itself. + +Setting up the environment +^^^^^^^^^^^^^^^^^^^^^^^^^^ + The environment can be changes to reflect a particular users environment, by editing or creating an environment file. This files are usually kept in the qa-wrapper/env directory. These environment settings can then be used when running the scripts. + +Running the Scripts +^^^^^^^^^^^^^^^^^^^ + Once the environment file has been created, the test scripts can be run by executing the "run-convtest" script in the qa-wrapper/bin directory. This file takes the following arguments + + run-convtest -env <ENVFILE> [-name RUNNAME] + +<ENVFILE> is the environment file to use +optional <RUNNAME> This can be the name of the user running the scripts. This is used to name a directory for the test results to be kept in. + + e.g. run-convtest -env ../env/master.env + + + + + + + + + + + + + + + + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/README b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/README new file mode 100644 index 000000000000..36fbcc6e1298 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/README @@ -0,0 +1,6 @@ +To run the spose script, you must set the following environmental variables: + + POSE2_EXE = Directory and name of the POSE executable file. + POSE3_EXE = Directory and name of the POSE executable file. + POSE_PRC = Directory containing the PRC files to be loaded + into the emulator diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/rd b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/rd new file mode 100755 index 000000000000..db2dc56aee6b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/rd @@ -0,0 +1,24 @@ +#!/bin/ksh +# +# Directories commonly used by this script... +# + +#export LBHOME=$ZPHOME/lib +#export CVHOME=$ZPHOME/converters +#export CVHOME=/export/home/test/qadir/qa-new/classes + +# Set up classpath to include needed ZenSync jars. Honor the users +# CLASSPATH by leaving it first. This allows users to specify their +# own versions of the jar files in their CLASSPATH if they wish to +# override these defaults. +# + +export CLASSPATH=$CLASSES_DIR/xerces.jar:$CLASSES_DIR/jmc.jar:$CLASSES_DIR/xmerge.jar:$CLASSES_DIR/minicalc.jar:$CLASSES_DIR/aportisdoc.jar:$CLASSES_DIR/wordsmith.jar + +echo "The classpath is $CLASSPATH" + +# Run the test driver, passing along args. +# +# java com.sun.star.comp.documentconversion.test.Driver $* +java -cp $CLASSPATH org.openoffice.xmerge.test.Driver $* + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/spose b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/spose new file mode 100755 index 000000000000..29f6a9fe5218 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/spose @@ -0,0 +1,108 @@ +#!/bin/perl +# +# spose - start pose +# + +use Getopt::Std; + +# Location of needed files +# +$pose2_exe = $ENV{'POSE2_EXE'}; +$pose3_exe = $ENV{'POSE3_EXE'}; +$pose_prc = $ENV{'POSE_PRC'}; + + +if (getopts('23qmwo:r:d:v') != 1) +{ + &usage(); +} + +$apps_load = ""; + +if ($opt_q) +{ + &add_app("$pose_prc/Quickword.PRC"); +} +if ($opt_m) +{ + &add_app("$pose_prc/MiniCalc.prc"); +} +if ($opt_w) +{ + &add_app("$pose_prc/WordSmith.PRC"); +} +if ($opt_o) +{ + &add_app("$opt_o"); +} +if ($opt_r) +{ + $run_prog .= "-run_app $opt_r"; +} +if ($opt_d) +{ + $directory = $opt_d; + @files = `/bin/ls -1 $directory/*.pdb`; + + for ($i=0; $i <= $#files; $i++) + { + $add_file = "$files[$i]"; + chomp $add_file; + &add_app("$add_file"); + } +} + +if ($opt_3) +{ + $pose_exe = $pose3_exe; +} +else +{ + $pose_exe = $pose2_exe; +} +if ($pose_exe eq "") +{ + print "\nPose not found: Please set \n POSE2_EXE\n or POSE3_EXE\n"; + exit 0; +} +if ($opt_v) +{ + print ("\n$pose_exe $apps_load $run_prog &\n\n"); +} +else +{ + system ("$pose_exe $apps_load $run_prog &"); +} + +exit 0; + +sub usage +{ + print "\nUsage: getopt [ -m ] [ -q ] [ -w ] [ -o <PrcFile> ] [ -r <RunProg> ]\n"; + print " -2 Runs pose version 3.2 [ current default ]\n"; + print " -3 Runs pose version 3.3\n"; + print " -d Load all PDB files in specified directory\n"; + print " -m Load MiniCalc PRC file\n"; + print " -q Load QuickWord PRC file\n"; + print " -w Load WordSmith PRC file\n"; + print " -o <PrcFile> Other PRC files to load\n"; + print " -r <RunProg> Program to run on startup\n"; + print " -v Display the command instead of running\n\n"; + exit(-1); +} + +sub add_app +{ + my $new_app = $_[0]; + + if ($apps_load ne "") + { + $apps_load .= ","; + } + else + { + $apps_load = "-load_apps "; + } + + $apps_load .= "$new_app"; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/verify_sane.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/verify_sane.pl new file mode 100755 index 000000000000..e0f5e4605cc3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/bin/verify_sane.pl @@ -0,0 +1,112 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: verify_sane.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#################################################################### +# File Name: template.pl +# Version : 1.0 +# Project : XMerge +# Author : Brian Cameron +# Date : 5th Sept. 2001 +# +# +# Takes x and y from the command line and taps the screen there. +# Assumes pose is already running. +# +########################################################################## + +use POSIX "sys_wait_h"; # Need this for waitpid with WNOHANG +use EmRPC; # EmRPC::OpenConnection, CloseConnection +use EmFunctions; +use EmUtils; + +if ($#ARGV != 0) +{ + print "\nUsage: $0 timeout\n\n"; + exit -1; +} + +$timeout = $ARGV[0]; + +if (!defined($up_pid = fork())) +{ + print "ERROR, problem forking.\n" +} +elsif ($up_pid) +{ + print "\nChecking to see if pose is started properly.\n"; + + # Parent process + # + sleep($timeout); + + waitpid($up_pid, WNOHANG); + + if (kill(0, $up_pid)) + { + print "Pose did not start successfully...\n"; + kill(9, $up_pid); + exit(-1); + } + else + { + # The child process exited okay, so we know it will not + # hang...but the open_connection will just die if pose + # isn't started...so try it in the parent. + # + open_connection(); + close_connection(); + + print "Verified pose started successfully...\n"; + exit(0); + } +} +else +{ + # Child process - Try to open/close the connection. This + # can hang if pose did not start properly... + # + open_connection(); + close_connection(); +} + +sub open_connection +{ + print "opening connection\n"; + EmRPC::OpenConnection(6415, "localhost"); +} + +sub close_connection +{ + print "closing connection\n"; + EmRPC::CloseConnection(); +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/qa_comparator.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/qa_comparator.pl new file mode 100755 index 000000000000..67ab1d43dbcd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/qa_comparator.pl @@ -0,0 +1,259 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: qa_comparator.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$compare_home = $ENV{'QA_COMPARATOR_HOME'}; + +if ($ENV{'CLASSPATH'}) +{ + $classpath_val = "$compare_home:$ENV{'CLASSPATH'}"; +} +else +{ + $classpath_val = "$compare_home"; +} + +print "classpath is $classpath_val\n"; + +$list_file=""; +$orig_dir=""; +$new_dir=""; +$diff_type=""; + +####### BEGIN MAIN ############## +$cmdline_len = @ARGV; +if ($cmdline_len <= 0) +{ + print_usage(); + exit (0); +} + +process_cmdline(@ARGV); +print_env(); +open (LOGFILE, ">$logfile") || die "Cannot open log file $logfile"; +if ($test_list ne "") +{ + open (TESTLIST, $test_list) || die "Couldn't open diff list file $test_list"; + + while (<TESTLIST>) + { + chomp $_; + process_diff(get_file_title($_)); + } +} +close TESTLIST; +close LOGFILE; + +####### END MAIN ############## + +sub process_diff +{ +# $_[0] =~ tr/A-Z/a-z/; + + # chdir to the output directory so the temporary files created by + # the java programs are put in the right place. + # + chdir ($xml_new); + + if ($diff_type eq "xml") + { + # Ugly hack, probably a way to tell xerces directly that the dtd's + # are in $compare_home/dtd. + # + `cp $compare_home/dtd/* $xml_new`; + +# $cmd = "java -classpath $classpath_val XmlWrapper $xml_orig/$_[0].sxw $xml_new/$_[0].sxw"; + $cmd = "java -classpath $classpath_val XmlWrapper $xml_orig/$_[0] $xml_new/$_[0]"; + print "Executing: $cmd\n"; + $val = system($cmd)/256; + if ($val == 2) + { +# print LOGFILE "$_[0]|TRUE|$xml_orig/$_[0].sxw|$xml_new/$_[0].sxw\n"; + print LOGFILE "$_[0]|TRUE|$xml_orig/$_[0]|$xml_new/$_[0]\n"; + } + elsif($val == 3) + { +# print LOGFILE "$_[0]|FALSE|$xml_orig/$_[0].sxw|$xml_new/$_[0].sxw\n"; + print LOGFILE "$_[0]|FALSE|$xml_orig/$_[0]|$xml_new/$_[0]\n"; + } + else + { +# print LOGFILE "$_[0]|ERROR|$xml_orig/$_[0].sxw|$xml_new/$_[0].sxw\n"; + print LOGFILE "$_[0]|ERROR|$xml_orig/$_[0]|$xml_new/$_[0]\n"; + } + } + elsif ($diff_type eq "pdb") + { +# $cmd = "java -classpath $classpath_val SimplePdbCompare $pdb_orig/$_[0].pdb $pdb_new/$_[0].pdb\n"; + $cmd = "java -classpath $classpath_val SimplePdbCompare $pdb_orig/$_[0] $pdb_new/$_[0]\n"; + print "Executing: $cmd\n"; + $val = system($cmd)/256; + if ($val == 2) + { +# print LOGFILE "$_[0]|TRUE|$pdb_orig/$_[0].pdb|$pdb_new/$_[0].pdb\n"; + print LOGFILE "$_[0]|TRUE|$pdb_orig/$_[0]|$pdb_new/$_[0]\n"; + } + elsif($val == 3) + { +# print LOGFILE "$_[0]|FALSE|$pdb_orig/$_[0].pdb|$pdb_new/$_[0].pdb\n"; + print LOGFILE "$_[0]|FALSE|$pdb_orig/$_[0]|$pdb_new/$_[0]\n"; + } + else + { +# print LOGFILE "$_[0]|ERROR|$pdb_orig/$_[0].pdb|$pdb_new/$_[0].pdb\n"; + print LOGFILE "$_[0]|ERROR|$pdb_orig/$_[0]|$pdb_new/$_[0]\n"; + } + } + else + { + die "Don't understand test type of $diff_type."; + } +} + +sub process_cmdline +{ + foreach $i (@_) + { + @arg= split('=', $i); + @arg[0] =~ tr/A-Z/a-z/; + + if (@arg[0] eq "-pdb-orig") + { + $pdb_orig=$arg[1]; + } + elsif (@arg[0] eq "-pdb-new") + { + $pdb_new=$arg[1]; + } + elsif (@arg[0] eq "-xml-orig") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "-xml-new") + { + $xml_new=$arg[1]; + } + elsif (@arg[0] eq "-env") + { + set_env_from_props($arg[1]); + } + elsif (@arg[0] eq "-list") + { + $test_list = $arg[1]; + } + elsif (@arg[0] eq "-one") + { + $infile = $arg[1]; + } + elsif (@arg[0] eq "-type") + { + $diff_type = $arg[1]; + chomp $diff_type; + } + elsif (@arg[0] eq "-log") + { + $logfile = $arg[1]; + } + else + { + print_usage(); + die "Incorrect command line. Don't understand $i"; + } + } +} + +sub set_env_from_props +{ + open(PROPSFILE, $_[0]) || die "Could not open properties file"; + + while (<PROPSFILE>) + { + chomp $_; + @arg = split('=', $_); + @arg[0] =~ tr/a-z/A-Z/; + $len = @arg; + if ($len != 2) + { + die "Malformed property in $ARGV[0]"; + } + + if (@arg[0] eq "PDB_ORIG") + { + $pdb_orig=$arg[1]; + } + elsif (@arg[0] eq "PDB_NEW") + { + $pdb_new=$arg[1]; + } + elsif (@arg[0] eq "XML_ORIG") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "XML_NEW") + { + $xml_new=$arg[1]; + } + + } + close PROPSFILE; +} + +sub print_usage +{ + print "Usage : compartor.pl - compare Office or pdb files\n"; + print "\t-one=<file> :\t\t individual test case file to run\n"; + print "\t-list=<file> :\t\t list of test case files\n"; + print "\t-env=<file> :\t\t Properites like file defining env\n"; + print "\t-pdb-orig=<path> :\t directory to hold original pdb files\n"; + print "\t-pdb-new=<path> :\t directory to hold new pdb files\n"; + print "\t-xml-orig=<path> :\t directory to hold original office documents\n"; + print "\t-xml-new=<path> :\t directory to hold new office documents\n"; + print "\t-type=<xml|pdb> :\t Invokes the merge option when converting\n"; + print "\t-log=<logfile> :\t Save results to logfile.\n"; +} + +sub print_env +{ + print "Using the following environment:\n"; + print "\tPDB_ORIG = $pdb_orig\n"; + print "\tPDB_NEW = $pdb_new\n"; + print "\tXML_ORIG = $xml_orig\n"; + print "\tXML_NEW = $xml_new\n\n"; +} + +sub get_file_title +{ + @paths = split('\/', $_[0]); + $len = @paths; + return @paths[$len-1]; +# @names = split('\.', @paths[$len-1]); +# return $names[0]; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/qa_test_driver.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/qa_test_driver.pl new file mode 100755 index 000000000000..f3ca7195b975 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/qa_test_driver.pl @@ -0,0 +1,848 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: qa_test_driver.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#################################################################### +# File Name: test_driver.pl +# Version : 1.0 +# Project : Xmerge +# Author : Brian Cameron +# Date : 5th Sept. 2001 +# +# +# This script does the following: +# +# Processes the input file, and runs the tests specified in that +# file. This will do the following for each test: +# +# 1. Convert a file from XML to PDB format +# 2. Starts up the Palm OS emulator with the appropriate program +# running and the converted file loaded the program. +# 3. Makes automated changes as specified in the inputfile to +# this script.. +# 4. Returns to the main applications window. +# +# Parameter +# Filename to convert and change +# +########################################################################## + +# Turn on auto-flushing +# +$|=1; + +use EmRPC; + +# Directory where converterlib is located... +# +#use lib "/export/home/test/qadir/qa/lib"; +use lib $ENV{'QA_LIB_HOME'}; +use converterlib; + +#-------------------- Start of main script ------------------------------------ + +# Environmental Settings + +$pose_exe = ""; +$pose_prc = ""; +$test_list = ""; +$infile = ""; +$merge_opt = 0; +# if testcase hasn't completed in 10 mins, then kill it off +$testcase_timeout=600; + +# You may need to change this from the default if your pose emulator +# starts faster or slower than mine. +# +if ($ENV{'POSE_TIMEOUT'}) +{ + $pose_timeout = "$ENV{'POSE_TIMEOUT'}"; +} +else +{ + $pose_timeout = 15; +} + +$cmdline_len = @ARGV; +if ($cmdline_len <= 0) +{ + print_usage(); + exit (0); +} + +&process_cmdline(@ARGV); +&print_env(); +&verify_env_options(); + +# Make the output directories with timestamps included in the +# directory names. +# +mkdir $pdb_orig, 0777 || die "can not create directory <$pdb_orig>."; +`chmod 777 $pdb_orig`; +mkdir $pdb_new, 0777 || die "can not create directory <$pdb_new>."; +`chmod 777 $pdb_new`; +mkdir $xml_new, 0777 || die "can not create directory <$xml_new>."; +`chmod 777 $xml_new`; + +&verify_prcs_exist("DBExporter.prc"); + +if ($test_list ne "") +{ + open (TESTLIST, $test_list) || die "Couldn't open testcase list file $test_list"; + + while (<TESTLIST>) + { + &process_testcase($_); + } +} +elsif ($infile ne "") +{ + if (!defined($child_pid = fork())) + { + # there was an error forking a process + print "ERROR: Unable to fork process\n"; + die "ERROR: Unable to fork process\n"; + } + elsif ($child_pid) + { + # this is the parent process + # run the actual test here +print "********\tPARENT (pid = $$): process_testcase...\n"; + &process_testcase($infile); +print "********\tPARENT (pid = $$): ...process_testcase finished normally\n"; + + # test finished normally, so kill the monitor + # that is running in the child process +print "********\tPARENT (pid = $$): kill child process ($child_pid)\n"; +print "********\tPARENT Before:\n"; +system( "/usr/bin/ptree" ); + kill( $child_pid ); + kill( 9, $child_pid ); +print "********\tPARENT After:\n"; +system( "/usr/bin/ptree" ); + } + else + { +print "********\tCHILD (pid = $$): sleep for $testcase_timeout seconds\n"; + # this is the child process + # wait on the test running in the parent, and + # kill it if it hasn't finished on time + sleep( $testcase_timeout ); + + # if the parent hasn't killed this process before it + # gets here, then it's probably hung, so we need to + # kill it. + print "********\tCHILD (pid = $$): TEST HUNG? still " + ."running after [$testcase_timeout] seconds - " + ."need to kill test process\n"; + $parent = getppid; + + if ( $parent != 1 ) { + print "********\nCHILD (pid = $$): Killing process ($parent)\n"; + kill( $parent ); + kill( 9, $parent ); + } else { + # If we cannot get the ppid, then the parent might + # have died abnormally, before it got a chance to + # kill this (child) process. + print "********\nCHILD (pid = $$): cannot determine ppid - " + ."terminating\n"; +system( "/usr/bin/ptree" ); + exit(2); + } + + exit(1); + } +} +else +{ + die ("You didn't supply any test cases to process"); +} + +print "Finished.\n"; +exit(0); + +#-------------------- End of main script ---------------------------------------- + +#-------------------------------------------------------------------------------- +# Various sub routines +#-------------------------------------------------------------------------------- + +# process_testcase +# infile - test case file name +# +# This is the main driver function +# Opens the infile, reads it in parses it, runs the appropriate conversion +# starts pose and load the file into the emulator. It launches the +# appropriate editor and then runs the commands specified in the test case. +# It then exports the file and saves it locally. Finally it is converted +# back to the original office format. +# +sub process_testcase +{ + my $infile = $_[0]; + my $convert_file = ""; + my $rc; + + # Process the inputfile + # + open (INFILE, $infile) || die "Failed to open test case <$infile>"; + + $running_testtype = ""; + + # Process the input file. + # + while ($c_inline = <INFILE>) + { + chomp $c_inline; + @entry = split('\|', $c_inline); + + # Process TEST + # + if ($c_inline =~ /^ *#/ || $c_inline =~ /^[ \t]*$/) + { + # skip comments and blank lines. + # + next; + } + elsif ("$entry[0]" eq "TEST") + { + # Close the test if one is running. + # + &close_program($convert_file); + $running_testtype = ""; + + $valid_test = 0; + + if ($#entry != 3) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + # Start the test. + # + print "\nStarting test: $entry[1]\n"; + $convert_file = $entry[3]; + + if ("$entry[2]" =~ /[Qq][Uu][Ii][Cc][Kk][Ww][Oo][Rr][Dd]/) + { + $xml_extension = "sxw"; + $convert_to = "application/x-aportisdoc"; + + # Convert XML file to pdb format. + # + $rc = &convert_to_pdb("$xml_orig", $convert_file, $xml_extension , + $convert_to,"$pdb_orig"); + if ($rc != 0) + { + print "\nERROR, problem converting file $convert_file\n\n"; + } + else + { + # Start pose + # + $rc = &start_pose("$pose_exe", + "$pose_prc/Quickword.PRC,$pose_prc/DBExporter.prc,$pdb_orig/$convert_file.pdb", + "Quickword", $pose_timeout); + + if ($rc == 0) + { + &start_quickword(); + $valid_test = 1; + $running_testtype = "QUICKWORD"; + print "\npose launched, begin automated test sequence for QuickWord\n"; + } + else + { + &kill_pose(); + $running_testtype = ""; + } + } + } + elsif ("$entry[2]" =~ /[Mm][Ii][Nn][Ii][Cc][Aa][Ll][Cc]/) + { + $xml_extension = "sxc"; + $convert_to = "application/x-minicalc"; + + # Convert XML file to pdb format. + # + $rc = &convert_to_pdb("$xml_orig", $convert_file, + $xml_extension, $convert_to,"$pdb_orig"); + if ($rc != 0) + { + print "\nERROR, problem converting file $convert_file\n\n"; + } + else + { + # Get minicalc PDB file names, since an SXC file can + # be converted to more than one. + # + $pdb_files=""; + $i = 1; + while (-f "$pdb_orig/$convert_file-Sheet$i.pdb") + { + if ($i > 1) + { + $pdb_files .= ","; + } + $pdb_files .= "$pdb_orig/$convert_file-Sheet$i.pdb"; + $i++; + } + $number = $i-1; + + # Start pose + # + $rc = &start_pose("$pose_exe", + "$pose_prc/MiniCalc.prc,$pose_prc/DBExporter.prc,$pdb_files", + "MiniCalc", $pose_timeout); + + if ($rc == 0) + { + &start_minicalc(); + $valid_test = 1; + $running_testtype = "MINICALC"; + print "pose launched, begin automated test sequence for MiniCalc\n"; + } + else + { + &kill_pose(); + $running_testtype = ""; + } + } + } + else + { + print "\nERROR, invalid extension <$entry[2]>\n\n"; + } + } + } + + # Process DB_EXPORT + # + elsif ("$entry[0]" eq "DB_EXPORT") + { + if ($#entry != 1) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + &db_export($entry[1]); + } + } + + # Process TAP_APPLICATIONS + # + elsif ("$entry[0]" eq "TAP_APPLICATIONS") + { + if ($#entry != 0) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + &tap_applications(0); + } + } + + # Process ENTER_STRING_AT_LOCATION + # + elsif ("$entry[0]" eq "ENTER_STRING_AT_LOCATION") + { + if ($#entry != 3) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &enter_string_at_location($entry[1], $entry[2], + $entry[3], $running_testtype); + } + } + + # Process TAP_PEN + # + elsif ("$entry[0]" eq "TAP_PEN") + { + if ($#entry != 2) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &pose_tap_pen($entry[1], $entry[2], 0); + } + } + + # Process TAP_BUTTON + # + elsif ("$entry[0]" eq "TAP_BUTTON") + { + if ($#entry != 1) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &pose_tap_button($entry[1], 0); + } + } + + # Process TAP_PEN_HARD + # + elsif ("$entry[0]" eq "TAP_PEN_HARD") + { + if ($#entry != 2) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &pose_tap_pen_hard($entry[1],$entry[2], 0); + } + } + + + # Process SLEEP + # + elsif ("$entry[0]" eq "SLEEP") + { + if ($#entry != 1) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + &pose_sleep($entry[1]); + } + } + + # Process MINICALC_ENTER_CELL + # + elsif ("$entry[0]" eq "MINICALC_ENTER_CELL") + { + if ($#entry != 3) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &minicalc_enter_cell($entry[1], $entry[2], $entry[3]); + } + } + + # Process QUICKWORD_FIND_REPLACE + # + elsif ("$entry[0]" eq "QUICKWORD_FIND_REPLACE") + { + if ($#entry != 2) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &quickword_find_replace($entry[1], $entry[2]); + } + } + else + { + print "\nERROR, invalid line <$c_inline>\n"; + } + } + + &close_program($convert_file); +} + +# close_program +# convert_file - file to export +# +# closes the program running in pose and kills pose +# +sub close_program +{ + my $convert_file = $_[0]; + + if ($running_testtype eq "QUICKWORD") + { + print "QuickWord test completed.\n"; + &close_program_quickword($convert_file); + } + elsif ($running_testtype eq "MINICALC") + { + print "MiniCalc test completed.\n"; + &close_program_minicalc($convert_file, $number); + } +} + +# close_program_quickword +# convert_file - file to export +# +# Closes quickword and kills pose +# +sub close_program_quickword +{ + my $convert_file = $_[0]; + my $error_file = "./error.txt"; + my $rc; + + &close_quickword(); + + &db_export($convert_file); + print "Moving /tmp/$convert_file.pdb to $pdb_new\n"; + `mv /tmp/$convert_file.pdb $pdb_new`; + `chmod 666 $pdb_new/$convert_file.pdb`; + + &close_connection(1); + &kill_pose(); + print "\nFinishing test...\n"; + + # The path of where to put the error file should be specified + # in the properties file. Not sure if it is really necessary + # to put this out to a separate file. STDOUT should be fine. + # + $rc = &convert_to_xml($xml_new, $xml_orig, + "$pdb_new/$convert_file.pdb", "application/x-aportisdoc" , + "sxw", $convert_file, $merge_opt); + if ($rc != 0) + { + print "\nERROR, problem converting file $pdb_new/$convert_file.pdb\n\n"; + } +} + +# close_program_minicalc +# convert_file - file to export +# +# Closes minicalc and kills pose +# +sub close_program_minicalc +{ + my $convert_file = $_[0]; + my $num_files = $_[1]; + my $list=""; + my $rc; + + &close_minicalc(); + + for ($a=1; $a <= $num_files; $a++) + { + &db_export("$convert_file-Sheet$a"); + print "Moving /tmp/$convert_file-Sheet$a.pdb to $pdb_new/\n"; + `mv /tmp/$convert_file-Sheet$a.pdb $pdb_new/`; + `chmod 666 $pdb_new/$convert_file-Sheet$a.pdb`; + } + + &close_connection(1); + &kill_pose(); + print "\nFinishing test...\n"; + + for ($a=1; $a <= $num_files; $a++) + { + $list .="$pdb_new/$convert_file-Sheet$a.pdb " + } + + $rc = &convert_to_xml($xml_new, $xml_orig, "$list", + "application/x-minicalc", "sxc", $convert_file, $merge_opt); + if ($rc != 0) + { + print "\nERROR, problem converting file(s) $list\n\n"; + } + + &pose_sleep(5); +} + +# print_usage +# +# prints the usage for this program. +# +sub print_usage +{ + print "Usage : test_driver.pl\n"; + print "\t-test=<file> \t\t: individual test case file to run\n"; + print "\t-list=<file> \t\t: list of test case files\n"; + print "\t-env=<file> \t\t: Properites like file defining env\n"; + print "\t-pose-exe=<fullpath> \t: path to pose executable\n"; + print "\t-pose-prc=<path> \t: path to directory holding prc files\n"; + print "\t-pdb-orig=<path> \t: directory to hold original pdb files\n"; + print "\t-pdb-new=<path> \t: directory to hold new pdb files\n"; + print "\t-xml-orig=<path> \t: directory to hold original office documents\n"; + print "\t-xml-new=<path> \t: directory to hold new office documents\n"; + print "\t-merge \t: Invokes the merge option when converting\n"; + print "\t \t from PDB back to XML.\n"; +} + +# print_env +# +# Prints the current environment. +# +sub print_env +{ + print "\nUsing the following environment:\n"; + print "\tPOSE_EXE = $pose_exe\n"; + print "\tPOSE_PRC = $pose_prc\n"; + print "\tPDB_ORIG = $pdb_orig\n"; + print "\tPDB_NEW = $pdb_new\n"; + print "\tXML_ORIG = $xml_orig\n"; + print "\tXML_NEW = $xml_new\n"; +} + +# process_cmdline +# +# command line options come in as key/value pairs. +# read them and set the appropriate global variable +# +# Sets these globals: pose_exe, pose_prc, xml_orig, xml_new_dir, +# xml_new, pdb_orig_dir, pdb_orig, pdb_new_dir, pdb_new. +# +sub process_cmdline +{ + foreach $i (@_) + { + my @arg= split('=', $i); + @arg[0] =~ tr/A-Z/a-z/; + + if (@arg[0] eq "-pose-exe") + { + $pose_exe=$arg[1]; + } + elsif (@arg[0] eq "-pose-prc") + { + $pose_prc=$arg[1]; + } + elsif (@arg[0] eq "-pdb-orig") + { + $pdb_orig_dir=$arg[1]; + $pdb_orig=$arg[1]; + } + elsif (@arg[0] eq "-pdb-new") + { + $pdb_new_dir=$arg[1]; + $pdb_new=$arg[1]; + } + elsif (@arg[0] eq "-xml-orig") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "-xml-new") + { + $xml_new_dir=$arg[1]; + $xml_new=$arg[1]; + } + elsif (@arg[0] eq "-env") + { + &set_env_from_props($arg[1]); + } + elsif (@arg[0] eq "-list") + { + $test_list = $arg[1]; + } + elsif (@arg[0] eq "-test") + { + $infile = $arg[1]; + } + elsif (@arg[0] eq "-merge") + { + $merge_opt = 1; + } + else + { + print_usage(); + die "Incorrect command line"; + } + } +} + +# set_env_from_props +# infile - property file +# +# Read the properties file, of the form key=value +# Valid key values are : +# POSE_EXE +# POSE_PRC +# PDB_ORIG +# PDB_NEW +# XML_ORIG +# XML_NEW +# If a value is found the appropriate global variable is set. +# +# Sets these globals: pose_exe, pose_prc, xml_orig, xml_new_dir, +# xml_new, pdb_orig_dir, pdb_orig, pdb_new_dir, pdb_new. +# +sub set_env_from_props +{ + my $infile = $_[0]; + + open(PROPSFILE, $infile) || die "Could not open properties file <$infile>"; + + while (<PROPSFILE>) + { + chomp $_; + my @arg = split('=', $_); + @arg[0] =~ tr/a-z/A-Z/; + my $len = @arg; + if ($len != 2) + { + die "Malformed property in $arg[0]"; + } + if (@arg[0] eq "POSE_EXE") + { + $pose_exe=$arg[1]; + } + elsif (@arg[0] eq "POSE_PRC") + { + $pose_prc=$arg[1]; + } + elsif (@arg[0] eq "PDB_ORIG") + { + $pdb_orig_dir=$arg[1]; + $pdb_orig=$arg[1]; + } + elsif (@arg[0] eq "PDB_NEW") + { + $pdb_new_dir=$arg[1]; + $pdb_new=$arg[1]; + } + elsif (@arg[0] eq "XML_ORIG") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "XML_NEW") + { + $xml_new_dir=$arg[1]; + $xml_new=$arg[1]; + } + + } + close PROPSFILE; +} + +# verify_env_options +# +# Verify that input options are correctly set. +# Assumes pose_exe, pose_prc, xml_orig, xml_new_dir, +# pdb_orig_dir, and pdb_new_dir are already set. +# +sub verify_env_options +{ + if (!-e "$pose_exe") + { + die "The pose executable cannot be found at $pose_exe."; + } + if (!-x $pose_exe) + { + die "$pose_exe exists but is not executable."; + } + + if (!-e "$pose_prc") + { + die "The PRC directory specified as $pose_prc does not exist."; + } + if (!-d "$pose_prc") + { + die "The PRC location specified as $pose_prc exists, but is not a directory."; + } + + if (!-e "$pdb_orig_dir") + { + die "The original PDB directory specified as $pdb_orig_dir does not exist."; + } + if (!-d "$pdb_orig_dir") + { + die "The original PDB directory specified as $pdb_orig_dir exists but is not a directory."; + } + + if (!-e "$pdb_new_dir") + { + die "The new PDB directory specified as $pdb_new_dir does not exist."; + } + if (!-d "$pdb_new_dir") + { + die "The new PDB directory specified as $pdb_new_dir exists but is not a directory."; + } + + if (!-e "$xml_orig") + { + die "The original Office document directory specified as $xml_orig does not exist."; + } + if (!-d "$xml_orig") + { + die "The original Office document location specified as $xml_orig exists but is not a directory."; + } + + if (!-e "$xml_new_dir") + { + die "The new Office document directory specified as $xml_new_dir does not exist."; + } + if (!-d "$xml_new_dir") + { + die "The new Office document location specified as $xml_new_dir exists but is not a directory."; + } +} + +# verify_prcs_exist +# prcfile - the PRC file to check +# +# Verifies that the specified PRC file exists. +# +sub verify_prcs_exist +{ + my $prcfile = $_[0]; + + if (!-e "$pose_prc/$prcfile") + { + die "The pose PRC directory ($pose_prc) is correct, but I can't find $prcfile there."; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/run-convtest b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/run-convtest new file mode 100755 index 000000000000..8b97b3ec71d3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/bin/run-convtest @@ -0,0 +1,540 @@ +#!/bin/ksh +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: run-convtest,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#set -x +umask 0 + +integer TOTAL_PASS=0 +integer TOTAL_FAIL=0 +integer TOTAL_RUN=0 +integer MAX_RETRIES=5 +typeset RUNNAME=`date +%Y%m%d%H%M%S` +typeset PRINTDATE=`date` +typeset PDB_INFILE_DIR +typeset PDB_OUTFILE_DIR +typeset XML_OUTFILE_DIR +typeset REPORT +typeset RESDIR +typeset LOGFILE +typeset COMPLOG +typeset TEST_COMMENTS +typeset BGCOLOR +typeset ODD_BGCOLOR='#BBBBBB' +typeset EVEN_BGCOLOR='#DCDCDC' +typeset PASS_COLOR='#00ff00' +typeset FAIL_COLOR='#ff4040' + +typeset ENVFILE="" +# The following variables should be set in the env file +typeset MASTERLIST="" +typeset TESTCASEDIR="" +typeset RESULTSBASE="" +typeset XMERGE_JAR="" +typeset APORTIS_JAR="" +typeset WORDSMITH_JAR="" +typeset MINICALC_JAR="" +typeset PERL5LIB="" +typeset POSE_EXE="" +typeset POSE_PRC="" +typeset TEST_DRIVER_PL="" +typeset COMPARATOR_PL="" +typeset COMPLIST="" +typeset XML_INFILE_DIR="" +typeset PDB_BASELINE_DIR="" +typeset XML_BASELINE_DIR="" +typeset EM_SCRIPT_HOME="" +typeset QAWRAPPER_SCRIPT_HOME="" +typeset EM_ROM_FILE="" +typeset EM_SESSION_FILE="" +typeset QA_LIB_HOME="" +typeset QA_COMPARATOR_HOME="" +typeset CLASSES_DIR="" + + + +################################################################################ +Usage() { + echo "Usage: run-convtest -env <ENVFILE> [-name RUNNAME]" + exit 1 +} + + +################################################################################ +StartReportFile() { + typeset line=`date` + + ReportLine "<HTML>" + ReportLine "<HEAD>" + ReportLine "<TITLE>XMerge Converters Test Results - ${RUNNAME}</TITLE>" + ReportLine "</HEAD>" + ReportLine "<BODY BGCOLOR=#ffffff>" + ReportLine "<H1 align=center>XMerge Converters Test Results - ${RUNNAME}</H1>" + ReportLine "<P>" + ReportLine "Test run on: ${PRINTDATE}" + ReportLine "<P>" + ReportLine "<CENTER>" + ReportLine "<TABLE WIDTH='100%' BORDER=1 CELLSPACING=0 CELLPADDING=2>" + ReportLine "<TR BGCOLOR='#9999CC'>" + ReportLine "<TH>Test Name</TH>" + ReportLine "<TH>Test File</TH>" + ReportLine "<TH>.ext</TH>" + ReportLine "<TH>Result</TH>" + ReportLine "<TH>Comments</TH>" + ReportLine "</TR>" +} + + +################################################################################ +EndReportFile() { + # remove full path from LOGFILE (link will be to current dir) + typeset loglink=${LOGFILE##*/} + + ReportLine "<P>" + ReportLine "<CENTER>" + ReportLine "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>" + ReportLine "<TR>" + ReportLine "<TH>Total Tests PASSED</TH>" + ReportLine "<TH>${TOTAL_PASS}</TH>" + ReportLine "</TR>" + ReportLine "<TR>" + ReportLine "<TH>Total Tests FAILED</TH>" + ReportLine "<TH>${TOTAL_FAIL}</TH>" + ReportLine "</TR>" + ReportLine "<TR>" + ReportLine "<TH>Total Tests Run</TH>" + ReportLine "<TH>${TOTAL_RUN}</TH>" + ReportLine "</TR>" + ReportLine "</TABLE>" + ReportLine "</CENTER>" + ReportLine "<P>" + ReportLine "<A HREF=${loglink}>Full logfile for test run</A>" + ReportLine "<P>" + ReportLine "<CENTER>" + ReportLine "</BODY>" + ReportLine "</HTML>" +} + +################################################################################ +ReportLine() { + echo $1 >> $REPORT +} + +################################################################################ +LogLine() { + echo $1 >> $LOGFILE +} + +################################################################################ +ReportTestComments() { + if [[ $TEST_COMMENTS == "" ]] ; then + TEST_COMMENTS=" " + fi + + ReportLine "<TD>${TEST_COMMENTS}</TD>" +} + +################################################################################ +GetParams() { + integer argc=$# + integer i=0 + + if [[ $argc -lt 1 ]] ; then + Usage + fi + + while (($i < $argc)) ; do + arg=$1 + shift + i=i+1 + + if [[ $arg == '-name' ]] ; then + if (( $i < $argc )) ; then + RUNNAME=$1 + echo "RUNNAME=[$RUNNAME]" + shift + i=i+1 + else + Usage + fi + elif [[ $arg == '-env' ]] ; then + if (( $i < $argc )) ; then + ENVFILE=$1 + shift + i=i+1 + else + Usage + fi + else + Usage + fi + done + + if [[ $ENVFILE == "" ]] ; then + Usage + fi +} + + +################################################################################ +ReadEnvFile() { + . $ENVFILE + + + echo "" + echo "The following values have been set from $ENVFILE:" + echo "MASTERLIST=$MASTERLIST" + echo "TESTCASEDIR=$TESTCASEDIR" + echo "XMERGE_JAR=$XMERGE_JAR" + echo "APORTIS_JAR=$APORTIS_JAR" + echo "WORDSMITH_JAR=$WORDSMITH_JAR" + echo "MINICALC_JAR=$MINICALC_JAR" + echo "RESULTSBASE=$RESULTSBASE" + echo "PERL5LIB=$PERL5LIB" + echo "POSE_EXE=$POSE_EXE" + echo "POSE_PRC=$POSE_PRC" + echo "TEST_DRIVER_PL=$TEST_DRIVER_PL" + echo "COMPARATOR_PL=$COMPARATOR_PL" + echo "XML_INFILE_DIR=$XML_INFILE_DIR" + echo "PDB_BASELINE_DIR=$PDB_BASELINE_DIR" + echo "XML_BASELINE_DIR=$XML_BASELINE_DIR" + echo "EM_SCRIPT_HOME=$EM_SCRIPT_HOME" + echo "QAWRAPPER_SCRIPT_HOME=$QAWRAPPER_SCRIPT_HOME" + echo "EM_ROM_FILE=$EM_ROM_FILE" + echo "EM_SESSION_FILE=$EM_SESSION_FILE" + echo "QA_LIB_HOME=$QA_LIB_HOME" + echo "QA_COMPARATOR_HOME=$QA_COMPARATOR_HOME" + echo "CLASSES_DIR=$CLASSES_DIR" + echo "COMPLIST=$COMPLIST" +} + +################################################################################ +POSESetup() { + export PERL5LIB + export EM_SCRIPT_HOME + export QAWRAPPER_SCRIPT_HOME + export EM_ROM_FILE + export EM_SESSION_FILE + export QA_LIB_HOME + export QA_COMPARATOR_HOME + export CLASSES_DIR + +} + +################################################################################ +TestSetup() { + + + POSESetup + + export ZENDEBUG=1 + + COMPLIST="${COMPLIST}/tempcomp.${RUNNAME}.list" + # create the directories for the results of this test run + RESDIR="${RESULTSBASE}/${RUNNAME}" + \rm -Rf $RESDIR + mkdir $RESDIR + + # Define the directories for the test input files, + # test output files, working directories and baseline files + PDB_INFILE_DIR="${RESDIR}/pdb-orig" + mkdir "${PDB_INFILE_DIR}" + PDB_OUTFILE_DIR="${RESDIR}/pdb-new" + mkdir "${PDB_OUTFILE_DIR}" + XML_OUTFILE_DIR="${RESDIR}/xml-new" + mkdir "${XML_OUTFILE_DIR}" + + LOGFILE="${RESDIR}/logfile" + COMPLOG="${RESDIR}/complog" + REPORT="${RESDIR}/report.html" + StartReportFile + + echo "Results in: $RESDIR" + echo "Report file: $REPORT" +} + +################################################################################ +TestCleanup() { + EndReportFile +} + +################################################################################ +TestCaseSetup() { + # where to pick up converter classes + export CLASSPATH="" + export CLASSPATH=$CLASSPATH:$XMERGE_JAR + export CLASSPATH=$CLASSPATH:$APORTIS_JAR + export CLASSPATH=$CLASSPATH:$WORDSMITH_JAR + export CLASSPATH=$CLASSPATH:$MINICALC_JAR +} + +################################################################################ +TestCaseCleanup() { + # empty function + a=42 +} + +################################################################################ +RunTestCase() { + testcase=$1 + + LogLine "" + LogLine "test_driver output:" + + # run test_driver in foreground + $TEST_DRIVER_PL\ + -pose-prc=${POSE_PRC}\ + -pose-exe=${POSE_EXE}\ + -xml-orig=${XML_INFILE_DIR}\ + -pdb-orig=${PDB_INFILE_DIR}\ + -pdb-new=${PDB_OUTFILE_DIR}\ + -xml-new=${XML_OUTFILE_DIR}\ + -test=$testcase -merge >> $LOGFILE 2>&1 + + # cleanup in case zombie POSE processes are hanging around + pkill pose + pkill -9 pose +} + + +################################################################################ +ComparisonSetup() { + typeset file=$1 + + + export CLASSPATH="$CLASSES_DIR/xerces.jar" + + # create temporary comparator list file for this test case + echo $file > $COMPLIST +} + +################################################################################ +ComparisonCleanup() { + # remove temporary comparator list file used for this test case + \rm -f $COMPLIST +} + +################################################################################ +RunComparison() { + typeset type=$1 + + LogLine "" + LogLine "Comparator output:" + $COMPARATOR_PL\ + -xml-orig=${XML_BASELINE_DIR}\ + -pdb-orig=${PDB_BASELINE_DIR}\ + -pdb-new=${PDB_INFILE_DIR}\ + -xml-new=${XML_OUTFILE_DIR}\ + -list=$COMPLIST -log=$COMPLOG -type=$type >> $LOGFILE 2>&1 +# -list=$COMPLIST -log=$COMPLOG -type=$type | tee -a $LOGFILE 2>&1 + + pass=`grep TRUE $COMPLOG | wc -l` + + LogLine "" + LogLine "COMPLIST file:" + cat $COMPLIST >> $LOGFILE + LogLine "" + LogLine "Comparator logfile:" + cat $COMPLOG >> $LOGFILE + + if [ $pass -eq 0 ] + then + TEST_COMMENTS="${TEST_COMMENTS}$type comparison ERROR<BR>" + echo "$type comparison ERROR" + return 0 + fi + + echo "$type comparison OK" + return 1 +} + +################################################################################ +CheckOutput() { + typeset xmlfile="${XML_OUTFILE_DIR}/$1" + typeset pdbfile="${PDB_INFILE_DIR}/$2" + + if [ ! -f $pdbfile ] ; then + TEST_COMMENTS="${TEST_COMMENTS}[$pdbfile] does not exist<BR>" + LogLine "ERROR: $pdbfile does not exist" + echo "ERROR: $pdbfile does not exist" + return 0 + fi + + if [ ! -f $xmlfile ] ; then + TEST_COMMENTS="${TEST_COMMENTS}[$xmlfile] does not exist<BR>" + LogLine "ERROR: $xmlfile does not exist" + echo "ERROR: $xmlfile does not exist" + return 0 + fi + + return 1 +} + +################################################################################ +RunTest() { + typeset testcasename + typeset testcase + typeset testfile + typeset pdbfile + typeset xmlfile + typeset ext + integer try + integer finished_with_test + integer test_pass + + TestSetup + + BGCOLOR=$ODD_BGCOLOR + + while read line ; do + # get chars up to 1st space + testcasename=${line%% *} + testcase="${TESTCASEDIR}/$testcasename" + + # get 2nd word + testfile=${line#* } + testfile=${testfile%% *} + + # get last word + ext=${line##* } + + LogLine "############################################" + LogLine "Starting the following testcase" + LogLine "testcase = $testcase" + LogLine "testfile = $testfile" + LogLine "ext = $ext" + + ReportLine "<TR BGCOLOR='${BGCOLOR}'>" + ReportLine "<TD valign=top>$testcasename</TD>" + ReportLine "<TD valign=top>$testfile</TD>" + ReportLine "<TD valign=top>$ext</TD>" + + echo "" + echo "testcase = $testcase" + echo "testfile = $testfile" + echo "ext = $ext" + + try=1 + finished_with_test=0 + TEST_COMMENTS="" + + while (($finished_with_test == 0)) ; do + + TestCaseSetup + RunTestCase $testcase + TestCaseCleanup + + xmlfile="${testfile}.${ext}" + + if [[ $ext == "sxc" ]] ; then + pdbfile="${testfile}-Sheet1.pdb" + else + pdbfile="${testfile}.pdb" + fi + + CheckOutput $xmlfile $pdbfile + res=$? + + if [[ $res -eq 1 ]] ; then + ComparisonSetup $pdbfile + RunComparison pdb + res=$? +# ignore result until pdb comparator is fixed... +res=1 + ComparisonCleanup + fi + + if [[ $res -eq 1 ]] ; then + ComparisonSetup $xmlfile + RunComparison xml + res=$? + ComparisonCleanup + fi + + if [[ $res -eq 1 ]] ; then + TOTAL_PASS=TOTAL_PASS+1 + ReportLine "<TD valign=top BGCOLOR='${PASS_COLOR}'>PASS</TD>" + ReportTestComments + ReportLine "</TR>" + LogLine "Test PASSED (on try $try)" + echo "Test PASSED (on try $try)" + finished_with_test=1 + else + TEST_COMMENTS="${TEST_COMMENTS}error on try ${try}<BR>" + LogLine "TEST FAILED (on try $try)" + echo "TEST FAILED (on try $try)" + + if [[ $try -eq $MAX_RETRIES ]] ; then + TOTAL_FAIL=TOTAL_FAIL+1 + ReportLine "<TD valign=top BGCOLOR='${FAIL_COLOR}'>FAIL</TD>" + ReportTestComments + ReportLine "</TR>" + finished_with_test=1 + fi + fi + + try=try+1 + done + + TOTAL_RUN=TOTAL_RUN+1 + + # toggle BGCOLOR for next report line + if [[ $BGCOLOR == $ODD_BGCOLOR ]] ; then + BGCOLOR=$EVEN_BGCOLOR + else + BGCOLOR=$ODD_BGCOLOR + fi + + done < $MASTERLIST + + ReportLine "</TABLE>" + ReportLine "</CENTER>" + + TestCleanup + + echo "Total Tests PASSED: "${TOTAL_PASS} + echo "Total Tests FAILED: "${TOTAL_FAIL} + echo "Total Tests RUN: "${TOTAL_RUN} + echo "Results in: $RESDIR" + echo "Report file: $REPORT" +} + +################################################################################ +################################################################################ +# main +################################################################################ +################################################################################ + +GetParams $@ +ReadEnvFile +RunTest + +exit 0 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/env/master.env b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/env/master.env new file mode 100755 index 000000000000..1571781bf475 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/env/master.env @@ -0,0 +1,85 @@ +#The Qa-Test environment is defined in this file. All of the fields are
+#necessary in order for the scripts to run effectlively
+
+###########################################################
+# MASTERLIST file defines which test to run. These list are usually located in
+# the qa-wrapper/lists dir
+
+MASTERLIST=<listdir/list file>
+
+###########################################################
+#The TESTCASE dir is where the testcases to be run are located
+
+TESTCASEDIR=<testcase dir>
+
+###########################################################
+# Results are stored in a new directory at ${RESULTSBASE}/results-${RUNNAME}
+
+RESULTSBASE=/export/home/test/qadir/qa-wrapper/results
+
+###########################################################
+# Where to find the Xmerge JAR files
+
+APORTIS_JAR=/export/home/test/qadir/qa-wrapper/classes/aportisdoc.jar
+WORDSMITH_JAR=/export/home/test/qadir/qa-wrapper/classes/wordsmith.jar
+MINICALC_JAR=/export/home/test/qadir/qa-wrapper/classes/minicalc.jar
+CLASSES_DIR=<qa-wrapperdir>/classes
+
+###########################################################
+# setup which version of POSE to use
+
+PERL5LIB=<Pose directory>/Scripting/Perl
+POSE_EXE=<Pose directory>/posedist/pose
+POSE_PRC=<location of prc files to use for testing>
+
+###########################################################
+
+# Location of files required to run Pose
+
+EM_ROM_FILE=<location and name of palm rom file>
+EM_SESSION_FILE=<location of palm session file>
+
+
+###########################################################
+
+
+# where to get the executables for the test_driver and the comparator
+
+TEST_DRIVER_PL=<qa-wrapperdir>/bin/qa_test_driver.pl
+COMPARATOR_PL=<qa-wrapperdir>/bin/qa_comparator.pl
+COMPLIST=<qa-wrapperdir>/lists
+
+###########################################################
+# where to get the original XML test files
+
+XML_INFILE_DIR=<qa-wrapperdir>/testcases/xml-orig
+
+###########################################################
+# where to find the baseline PDB files
+
+PDB_BASELINE_DIR=<qa-wrapperdir>/results/baseline/pdb-base
+
+###########################################################
+# where to find the baseline XML files
+
+XML_BASELINE_DIR=<qa-wrapperdir>/results/baseline/xml-base
+
+###########################################################
+#Location of script that runs the conversions
+EM_SCRIPT_HOME=<location of rd script>
+
+###########################################################
+#Location of run-convtest.pl
+QAWRAPPER_SCRIPT_HOME=<qa-wrapperdir>/bin
+
+###########################################################
+#Location of converterlib.pm
+QA_LIB_HOME=<qa dir>/lib
+
+###########################################################
+#Location of comparator.pl
+QA_COMPARATOR_HOME=<qa dir>/comparator/
+
+
+
+
diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/lists/master.list b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/lists/master.list new file mode 100755 index 000000000000..d6be4fb063bd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/lists/master.list @@ -0,0 +1,55 @@ +c_addition01-mod.infile c_addition sxc +c_alignment.infile c_alignment sxc +c_backwardrange-mod.infile c_backwardrange sxc +c_basic-mod.infile c_basic sxc +c_boolean-mod.infile c_boolean sxc +c_cellpercentvalue-mod.infile c_cellpercentvalue sxc +c_cellstringvalue-mod.infile c_cellstringvalue sxc +c_columnswidth-mod.infile c_columnswidth sxc +c_cyclic-mod.infile c_cyclic sxc +c_dividefloating-mod.infile c_dividefloating sxc +c_forwardrange-mod.infile c_forwardrange sxc +c_insertimage.infile c_insertimage sxc +c_invalidcellref-mod.infile c_invalidcellref sxc +c_largerange-mod.infile c_largerange sxc +c_listrange-mod.infile c_listrange sxc +c_mathematical-mod.infile c_mathematical sxc +c_protection-mod01.infile c_protection sxc +c_sheetreference-mod.infile c_sheetreference sxc +c_simple01-mod.infile c_simple01 sxc +c_simple02-mod.infile c_simple04 sxc +c_simple03-mod.infile c_simple02 sxc +c_simple04-mod.infile c_simple03 sxc +c_smallrange-mod.infile c_smallrange sxc +c_styles.infile c_styles sxc +c_textimage.infile c_textimage sxc +a_table.infile a_table sxw +a_animatedgif.infile a_animatedgif sxw +a_linebreaks.infile a_linebreaks sxw +a_bulletorderedlist.infile a_bulletorderedlist sxw +a_superscript.infile a_superscript sxw +a_subscript.infile a_subscript sxw +a_emptydoc.infile a_emptydoc sxw +a_fontsize.infile a_fontsize sxw +a_heading.infile a_heading sxw +a_heading1.infile a_heading1 sxw +a_heading2.infile a_heading2 sxw +a_hyperlink.infile a_hyperlink sxw +a_justified.infile a_justified sxw +a_linespacing.infile a_linespacing sxw +a_numberorderedlist.infile a_numberorderedlist sxw +a_pagebreak.infile a_pagebreak sxw +a_paragraph.infile a_paragraph sxw +a_standard.infile a_standard sxw +a_symbols.infile a_symbols sxw +a_wordwrap.infile a_wordwrap sxw +a_unorderedlist.infile a_unorderedlist sxw +a_textspan.infile a_textspan sxw +a_bolddoc.infile a_bolddoc sxw +a_tab.infile a_tab sxw +a_firstlineindent.infile a_firstlineindent sxw +a_bookmarks.infile a_bookmarks sxw + + + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_animatedgif.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_animatedgif.pdb Binary files differnew file mode 100755 index 000000000000..88dbf557cc4e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_animatedgif.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bolddoc.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bolddoc.pdb Binary files differnew file mode 100755 index 000000000000..0bfadf294bdf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bolddoc.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bookmarks.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bookmarks.pdb Binary files differnew file mode 100755 index 000000000000..8c134002c9de --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bookmarks.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bulletorderedlist.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bulletorderedlist.pdb Binary files differnew file mode 100755 index 000000000000..8f3d588dfb67 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_bulletorderedlist.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_emptydoc.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_emptydoc.pdb Binary files differnew file mode 100755 index 000000000000..99c045e6113c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_emptydoc.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_firstlineindent.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_firstlineindent.pdb Binary files differnew file mode 100755 index 000000000000..279d2287b65d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_firstlineindent.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_fontsize.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_fontsize.pdb Binary files differnew file mode 100755 index 000000000000..8b3cef8cdedb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_fontsize.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading.pdb Binary files differnew file mode 100755 index 000000000000..deb8f613fdf3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading1.pdb Binary files differnew file mode 100755 index 000000000000..f3c89a917c21 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading2.pdb Binary files differnew file mode 100755 index 000000000000..e954224020b7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_heading2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_hyperlink.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_hyperlink.pdb Binary files differnew file mode 100755 index 000000000000..88a3927fbd24 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_hyperlink.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_justified.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_justified.pdb Binary files differnew file mode 100755 index 000000000000..c93da36ec630 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_justified.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_linebreaks.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_linebreaks.pdb Binary files differnew file mode 100755 index 000000000000..8152cf5156d2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_linebreaks.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_linespacing.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_linespacing.pdb Binary files differnew file mode 100755 index 000000000000..8cbe09e5ff1e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_linespacing.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_numberorderedlist.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_numberorderedlist.pdb Binary files differnew file mode 100755 index 000000000000..f7c1835b8d0b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_numberorderedlist.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_pagebreak.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_pagebreak.pdb Binary files differnew file mode 100755 index 000000000000..7ad393f3fd84 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_pagebreak.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_paragraph.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_paragraph.pdb Binary files differnew file mode 100755 index 000000000000..5c2bfa52c77b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_paragraph.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple01.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple01.pdb Binary files differnew file mode 100755 index 000000000000..b1ea0024c1f1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple01.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple02.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple02.pdb Binary files differnew file mode 100755 index 000000000000..5eaf2292c34f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple02.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple03.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple03.pdb Binary files differnew file mode 100755 index 000000000000..8c9d2bb568df --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple03.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple04.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple04.pdb Binary files differnew file mode 100755 index 000000000000..7e88c9fe866a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple04.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple05.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple05.pdb Binary files differnew file mode 100755 index 000000000000..d0959c91bd2d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_simple05.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_standard.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_standard.pdb Binary files differnew file mode 100755 index 000000000000..694e33361df2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_standard.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_subscript.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_subscript.pdb Binary files differnew file mode 100755 index 000000000000..d6a9081a0150 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_subscript.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_superscript.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_superscript.pdb Binary files differnew file mode 100755 index 000000000000..e4349e79842f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_superscript.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_symbols.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_symbols.pdb Binary files differnew file mode 100755 index 000000000000..7ef7f9daacc7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_symbols.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_tab.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_tab.pdb Binary files differnew file mode 100755 index 000000000000..0befa7c85eb2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_tab.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_table.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_table.pdb Binary files differnew file mode 100755 index 000000000000..72a2f98f7485 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_table.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_textspan.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_textspan.pdb Binary files differnew file mode 100755 index 000000000000..bbb4487c986f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_textspan.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_unorderedlist.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_unorderedlist.pdb Binary files differnew file mode 100755 index 000000000000..214100ce6117 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_unorderedlist.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_wordwrap.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_wordwrap.pdb Binary files differnew file mode 100755 index 000000000000..4c2179aada8e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/a_wordwrap.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..c5a559ead4e7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..c633734b8f17 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..c7571e003964 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_addition-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..200026701dc6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..1531205547ce --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..089b36be0cdd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_alignment-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..a99167080c7e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..6df6cb9cd183 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..3f08a196172a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_backwardrange-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..287a25bd0b87 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..8efbe6d58e34 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..b7cbfb7f8f5c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_basic-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..458fcf18bfc5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..188dd9d5be96 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..6568390100da --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_boolean-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..984b1f14001c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..9b0e50b204c1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..c39410c5c656 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellcurrencyalue-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..84b0c2aabaaa --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..f8300622d553 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..5c841af6f953 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellpercentvalue-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..aeea92b92b38 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..3230b1574a69 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..8fcfd9940ead --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cellstringvalue-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..db4ee52a9c1b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..110ef180f613 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..33c6c9f0061f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_columnswidth-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..ee52655a0056 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..c6caaf40132d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..8b6a735edeb9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_cyclic-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..53d2acbac676 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..5a4a0460d258 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..eaa43bc683b1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_dividefloating-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..026634583a5b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..b11956ab7c4a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..56fef34f9c4e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_forwardrange-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..f7c2e2188bfc --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..cc2cc083533a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..51328fd9c1ef --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_insertimage-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..390fc9710723 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..9efa6bbc78a9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..62dc5629c67a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_invalidcellref-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..cf485e74d8c9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..ac000de5b8a0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..45d1faf2a293 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_largerange-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..1b617ff67e32 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..b2e34e5ec759 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..0bb0d1a6b3d6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_listrange-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..3f9fe58a186c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..dddc94e07f02 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..1f40204c7971 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_mathematical-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..06fc72d829fe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..03107c5d325d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..de40bfd56ec6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_protection-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..a9df85405e1a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..e8412d07e081 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..b6a2c0ef38d5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_sheetreference-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..72aa8c82ba4a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..cb04d4125fc9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..7a85aff6ba62 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple01-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..383fb4cccfb5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..a5e9b8beea3b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..6bce59077201 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple02-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..09d9020bc61f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..14e2723688c4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..705134770677 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple03-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..efba83c29b8d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..2811910ecd04 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..08028abc6fd1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_simple04-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..c7978fac0a6b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..c8234832053d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..78e2a4ea6b21 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_smallrange-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..f622cd7d1243 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..8c29018d9e8a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..4eebe759c1db --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_styles-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet1.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet1.pdb Binary files differnew file mode 100755 index 000000000000..169a2cc173b9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet1.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet2.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet2.pdb Binary files differnew file mode 100755 index 000000000000..4dee2cab0d2b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet2.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet3.pdb b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet3.pdb Binary files differnew file mode 100755 index 000000000000..999d53f16a0c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/pdb-base/c_textimage-Sheet3.pdb diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/Blocklist.dtd b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/Blocklist.dtd new file mode 100755 index 000000000000..c1d585a7b0a9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/Blocklist.dtd @@ -0,0 +1,38 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: Blocklist.dtd,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<!ELEMENT block-list:block-list (block-list:block*) > +<!ATTLIST block-list:block-list + block-list:list-name CDATA #REQUIRED> +<!ELEMENT block-list:block EMPTY> +<!ATTLIST block-list:block + block-list:abbreviated-name CDATA #REQUIRED + block-list:package-name CDATA #REQUIRED + block-list:name CDATA #REQUIRED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_animatedgif.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_animatedgif.sxw Binary files differnew file mode 100755 index 000000000000..a8f7d91ef03f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_animatedgif.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bolddoc.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bolddoc.sxw Binary files differnew file mode 100755 index 000000000000..9f0cb66d69ba --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bolddoc.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bookmarks.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bookmarks.sxw Binary files differnew file mode 100755 index 000000000000..d3ea3431875d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bookmarks.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bulletorderedlist.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bulletorderedlist.sxw Binary files differnew file mode 100755 index 000000000000..bd640d575fb2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_bulletorderedlist.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_emptydoc.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_emptydoc.sxw Binary files differnew file mode 100755 index 000000000000..d4a0621ad46d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_emptydoc.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_firstlineindent.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_firstlineindent.sxw Binary files differnew file mode 100755 index 000000000000..75a18d84a53f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_firstlineindent.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_fontsize.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_fontsize.sxw Binary files differnew file mode 100755 index 000000000000..b87aa37523d0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_fontsize.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading.sxw Binary files differnew file mode 100755 index 000000000000..a6d25bd5cf8e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading1.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading1.sxw Binary files differnew file mode 100755 index 000000000000..ed91418ab374 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading1.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading2.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading2.sxw Binary files differnew file mode 100755 index 000000000000..2f767e6f1675 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_heading2.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_hyperlink.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_hyperlink.sxw Binary files differnew file mode 100755 index 000000000000..6a04edd6a073 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_hyperlink.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_justified.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_justified.sxw Binary files differnew file mode 100755 index 000000000000..ae33ab576588 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_justified.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_linebreaks.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_linebreaks.sxw Binary files differnew file mode 100755 index 000000000000..27b1e73e0b50 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_linebreaks.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_linespacing.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_linespacing.sxw Binary files differnew file mode 100755 index 000000000000..74436d8076c7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_linespacing.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_numberorderedlist.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_numberorderedlist.sxw Binary files differnew file mode 100755 index 000000000000..3d8e19970fd8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_numberorderedlist.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_pagebreak.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_pagebreak.sxw Binary files differnew file mode 100755 index 000000000000..d929cfe5c13f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_pagebreak.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_paragraph.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_paragraph.sxw Binary files differnew file mode 100755 index 000000000000..5c74827d5663 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_paragraph.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple01.sxw Binary files differnew file mode 100755 index 000000000000..2d3384d5f9f0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple02.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple02.sxw Binary files differnew file mode 100755 index 000000000000..404cfd5ffd92 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple02.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple03.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple03.sxw Binary files differnew file mode 100755 index 000000000000..9b90d54cfc54 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple03.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple04.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple04.sxw Binary files differnew file mode 100755 index 000000000000..dddb02f91248 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple04.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple05.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple05.sxw Binary files differnew file mode 100755 index 000000000000..c811aabcf28d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_simple05.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_standard.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_standard.sxw Binary files differnew file mode 100755 index 000000000000..b9ac1e688e71 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_standard.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_subscript.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_subscript.sxw Binary files differnew file mode 100755 index 000000000000..78ed939f1f83 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_subscript.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_superscript.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_superscript.sxw Binary files differnew file mode 100755 index 000000000000..7d44042aaf5f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_superscript.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_symbols.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_symbols.sxw Binary files differnew file mode 100755 index 000000000000..a48137a8ded5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_symbols.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_tab.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_tab.sxw Binary files differnew file mode 100755 index 000000000000..5602764f3c9d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_tab.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_table.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_table.sxw Binary files differnew file mode 100755 index 000000000000..a101ba833aa9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_table.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_textspan.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_textspan.sxw Binary files differnew file mode 100755 index 000000000000..beae7b8c8a7a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_textspan.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_unorderedlist.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_unorderedlist.sxw Binary files differnew file mode 100755 index 000000000000..ca5ee406ccc5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_unorderedlist.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_wordwrap.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_wordwrap.sxw Binary files differnew file mode 100755 index 000000000000..ece3fefae183 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/a_wordwrap.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_addition.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_addition.sxc Binary files differnew file mode 100755 index 000000000000..6c4341f62ac2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_addition.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_alignment.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_alignment.sxc Binary files differnew file mode 100755 index 000000000000..b9df5dd3b00e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_alignment.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_backwardrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_backwardrange.sxc Binary files differnew file mode 100755 index 000000000000..c61f460e9fd8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_backwardrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_basic.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_basic.sxc Binary files differnew file mode 100755 index 000000000000..8a1ba23b78fc --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_basic.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_boolean.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_boolean.sxc Binary files differnew file mode 100755 index 000000000000..c34e7608c129 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_boolean.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellcurrencyalue.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellcurrencyalue.sxc Binary files differnew file mode 100755 index 000000000000..808d781162e6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellcurrencyalue.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellpercentvalue.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellpercentvalue.sxc Binary files differnew file mode 100755 index 000000000000..9b4b9f024a6a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellpercentvalue.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellstringvalue.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellstringvalue.sxc Binary files differnew file mode 100755 index 000000000000..b44496fdb57b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cellstringvalue.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_columnswidth.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_columnswidth.sxc Binary files differnew file mode 100755 index 000000000000..9aeec30fb699 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_columnswidth.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cyclic.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cyclic.sxc Binary files differnew file mode 100755 index 000000000000..196bd78962a9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_cyclic.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_dividefloating.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_dividefloating.sxc Binary files differnew file mode 100755 index 000000000000..1e2c55b448c8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_dividefloating.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_forwardrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_forwardrange.sxc Binary files differnew file mode 100755 index 000000000000..0e41c624511b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_forwardrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_insertimage.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_insertimage.sxc Binary files differnew file mode 100755 index 000000000000..bae72239f17e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_insertimage.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_invalidcellref.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_invalidcellref.sxc Binary files differnew file mode 100755 index 000000000000..881b4ffdb966 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_invalidcellref.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_largerange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_largerange.sxc Binary files differnew file mode 100755 index 000000000000..379b1cef6d62 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_largerange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_listrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_listrange.sxc Binary files differnew file mode 100755 index 000000000000..e0e05b128917 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_listrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_mathematical.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_mathematical.sxc Binary files differnew file mode 100755 index 000000000000..c9cf3e8bbc5e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_mathematical.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_protection.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_protection.sxc Binary files differnew file mode 100755 index 000000000000..64f89cc61ce7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_protection.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_sheetreference.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_sheetreference.sxc Binary files differnew file mode 100755 index 000000000000..4239ab2fa908 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_sheetreference.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple01.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple01.sxc Binary files differnew file mode 100755 index 000000000000..e508b749bb0d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple01.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple02.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple02.sxc Binary files differnew file mode 100755 index 000000000000..d490ed66fe3c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple02.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple03.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple03.sxc Binary files differnew file mode 100755 index 000000000000..1dee18c7ddd7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple03.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple04.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple04.sxc Binary files differnew file mode 100755 index 000000000000..5164313a79cf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_simple04.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_smallrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_smallrange.sxc Binary files differnew file mode 100755 index 000000000000..8283b04c54e3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_smallrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_styles.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_styles.sxc Binary files differnew file mode 100755 index 000000000000..21e0f1ab5ac0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_styles.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_textimage.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_textimage.sxc Binary files differnew file mode 100755 index 000000000000..9f42285d2881 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/c_textimage.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/chart.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/chart.mod new file mode 100755 index 000000000000..dec81f10aac6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/chart.mod @@ -0,0 +1,232 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: chart.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + +<!ENTITY % chart-class "(line|area|circle|ring|scatter|radar|bar|stock|add-in)"> +<!ENTITY % chart-solid-type "(cuboid|cylinder|cone|pyramid)"> + +<!-- Chart element --> +<!ELEMENT chart:chart ( chart:title?, chart:subtitle?, chart:legend?, + chart:plot-area, + table:table? )> +<!ATTLIST chart:chart + chart:class %chart-class; #REQUIRED + chart:add-in-name %string; #IMPLIED + chart:table-number-list %string; #IMPLIED + draw:name %string; #IMPLIED + %draw-position; + %draw-size; + %draw-style-name; + chart:style-name %styleName; #IMPLIED> + +<!ATTLIST chart:chart %presentation-class; > +<!ATTLIST chart:chart %zindex;> +<!ATTLIST chart:chart %draw-end-position; > +<!ATTLIST chart:chart draw:id %draw-shape-id; > +<!ATTLIST chart:chart draw:layer %layerName; #IMPLIED> + +<!ATTLIST style:properties + chart:scale-text %boolean; "true" + chart:stock-updown-bars %boolean; "false" + chart:stock-with-volume %boolean; "false" + chart:three-dimensional %boolean; "false" + chart:deep %boolean; "false" + chart:lines %boolean; "false" + chart:percentage %boolean; "false" + chart:solid-type %chart-solid-type; "cuboid" + chart:splines %nonNegativeInteger; "0" + chart:stacked %boolean; "false" + chart:symbol %integer; "-1" + chart:vertical %boolean; "false" + chart:lines-used %nonNegativeInteger; "0" + chart:connect-bars %boolean; "false"> + +<!-- Main/Sub Title --> +<!-- the cell-address attribute is currently not supported for titles --> +<!ELEMENT chart:title (text:p)?> +<!ATTLIST chart:title + table:cell-range %cell-address; #IMPLIED + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ELEMENT chart:subtitle (text:p)?> +<!ATTLIST chart:subtitle + table:cell-range %cell-address; #IMPLIED + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- you must specify either a legend-position or both, x and y coordinates --> +<!ELEMENT chart:legend EMPTY> +<!ATTLIST chart:legend + chart:legend-position (top|left|bottom|right) "right" + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- Plot-Area specification --> + +<!ELEMENT chart:plot-area (dr3d:light*, + chart:axis*, + chart:categories?, + chart:series*, + chart:wall?, + chart:floor?) > + +<!ATTLIST chart:plot-area + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + svg:width %length; #IMPLIED + svg:height %length; #IMPLIED + chart:style-name %styleName; #IMPLIED + table:cell-range-address %cell-range-address; #IMPLIED + chart:table-number-list %string; #IMPLIED + chart:data-source-has-labels (none|row|column|both) "none" > + +<!-- 3d scene attributes on plot-area --> +<!ATTLIST chart:plot-area + dr3d:vrp %vector3D; #IMPLIED + dr3d:vpn %vector3D; #IMPLIED + dr3d:vup %vector3D; #IMPLIED + dr3d:projection (parallel|perspective) #IMPLIED + dr3d:transform CDATA #IMPLIED + dr3d:distance %length; #IMPLIED + dr3d:focal-length %length; #IMPLIED + dr3d:shadow-slant %nonNegativeInteger; #IMPLIED + dr3d:shade-mode (flat|phong|gouraud|draft) #IMPLIED + dr3d:ambient-color %color; #IMPLIED + dr3d:lighting-mode %boolean; #IMPLIED > + +<!ATTLIST style:properties + chart:series-source (columns|rows) "columns" > + +<!ELEMENT chart:wall EMPTY> +<!ATTLIST chart:wall + svg:width %length; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ELEMENT chart:floor EMPTY> +<!ATTLIST chart:floor + svg:width %length; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- Axis --> + +<!ELEMENT chart:axis (chart:title?, chart:grid*)> +<!ATTLIST chart:axis + chart:class (category|value|series|domain) #REQUIRED + chart:name %string; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ATTLIST style:properties + chart:tick-marks-major-inner %boolean; "false" + chart:tick-marks-major-outer %boolean; "true" + chart:tick-marks-minor-inner %boolean; "false" + chart:tick-marks-minor-outer %boolean; "false" + chart:logarithmic %boolean; "false" + chart:maximum %float; #IMPLIED + chart:minimum %float; #IMPLIED + chart:origin %float; #IMPLIED + chart:interval-major %float; #IMPLIED + chart:interval-minor %float; #IMPLIED + chart:gap-width %integer; #IMPLIED + chart:overlap %integer; #IMPLIED + text:line-break %boolean; "true" + chart:display-label %boolean; "true" + chart:label-arrangement (side-by-side|stagger-even|stagger-odd) "side-by-side" + chart:visible %boolean; "true" + chart:link-data-style-to-source %boolean; "true" > + +<!ELEMENT chart:grid EMPTY> +<!ATTLIST chart:grid + chart:class (major|minor) "major" + chart:style-name %styleName; #IMPLIED > + + +<!ELEMENT chart:categories EMPTY> +<!ATTLIST chart:categories + table:cell-range-address %cell-range-address; #REQUIRED > + +<!-- + each series element must have an cell-range-address element that points + to the underlying table data. + Impl. Note: Internally all href elements are merged to one table range + that represents the data for the whole chart +--> +<!ELEMENT chart:series ( chart:domain*, + chart:data-point* )> +<!ATTLIST chart:series + chart:values-cell-range-address %cell-range-address; #IMPLIED + chart:label-cell-address %cell-address; #IMPLIED + chart:class %chart-class; #IMPLIED + chart:attached-axis %string; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ELEMENT chart:domain EMPTY> +<!ATTLIST chart:domain + table:cell-range-address %cell-range-address; #IMPLIED > + +<!ELEMENT chart:data-point EMPTY> +<!ATTLIST chart:data-point + chart:repeated %nonNegativeInteger; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- statistical properties --> + +<!ATTLIST style:properties + chart:mean-value %boolean; #IMPLIED + chart:error-category (none|variance|standard-deviation|percentage|error-margin|constant) "none" + chart:error-percentage %float; #IMPLIED + chart:error-margin %float; #IMPLIED + chart:error-lower-limit %float; #IMPLIED + chart:error-upper-limit %float; #IMPLIED + chart:error-upper-indicator %boolean; #IMPLIED + chart:error-lower-indicator %boolean; #IMPLIED + chart:regression-type (none|linear|logarithmic|exponential|power) "none" > + +<!-- data label properties --> + +<!ATTLIST style:properties + chart:data-label-number (none|value|percentage) "none" + chart:data-label-text %boolean; "false" + chart:data-label-symbol %boolean; "false" > + +<!-- general text properties --> + +<!ATTLIST style:properties text:rotation-angle %integer; "0" > + +<!-- symbol properties --> + +<!ATTLIST style:properties + chart:symbol-width %nonNegativeLength; #IMPLIED + chart:symbol-height %nonNegativeLength; #IMPLIED + chart:symbol-image-name %string; #IMPLIED > diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/datastyl.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/datastyl.mod new file mode 100755 index 000000000000..31bf7a464c77 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/datastyl.mod @@ -0,0 +1,172 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: datastyl.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!-- data styles --> +<!ENTITY % any-number "( number:number | number:scientific-number | number:fraction )"> +<!ENTITY % number-style-content "( (number:text,(%any-number;,number:text?)?) | (%any-number;,number:text?) )"> +<!ELEMENT number:number-style ( style:properties?, %number-style-content;, style:map* )> +<!ELEMENT number:number EMPTY> +<!ELEMENT number:scientific-number EMPTY> +<!ELEMENT number:fraction EMPTY> + +<!ENTITY % currency-symbol-and-text "number:currency-symbol,number:text?"> +<!ENTITY % number-and-text "number:number,number:text?"> +<!ENTITY % currency-symbol-and-number "((%number-and-text;),(%currency-symbol-and-text;)?) | ((%currency-symbol-and-text;),(%number-and-text;)?)"> +<!ENTITY % currency-style-content "number:text?, (%currency-symbol-and-number;)?"> + +<!ELEMENT number:currency-style ( style:properties?, (%currency-style-content;), style:map* )> +<!ELEMENT number:currency-symbol (#PCDATA)> +<!ATTLIST number:currency-symbol number:language CDATA #IMPLIED> +<!ATTLIST number:currency-symbol number:country CDATA #IMPLIED> + +<!ENTITY % percentage-style-content "( (number:text,(%number-and-text;)?) | (%number-and-text;) )"> +<!ELEMENT number:percentage-style ( style:properties?, %percentage-style-content;, style:map* )> + +<!ENTITY % any-date "( number:day | number:month | number:year | number:era | number:day-of-week | number:week-of-year | number:quarter| number:hours | number:am-pm | number:minutes | number:seconds )"> +<!ENTITY % date-style-content "( (number:text,(%any-date;,number:text?)+) | (%any-date;,number:text?)+ )"> +<!ELEMENT number:date-style ( style:properties?, %date-style-content;, style:map* )> +<!ELEMENT number:day EMPTY> +<!ATTLIST number:day number:style (short|long) "short"> +<!ATTLIST number:day number:calendar CDATA #IMPLIED> +<!ELEMENT number:month EMPTY> +<!ATTLIST number:month number:textual %boolean; "false"> +<!ATTLIST number:month number:style (short|long) "short"> +<!ATTLIST number:month number:calendar CDATA #IMPLIED> +<!ELEMENT number:year EMPTY> +<!ATTLIST number:year number:style (short|long) "short"> +<!ATTLIST number:year number:calendar CDATA #IMPLIED> +<!ELEMENT number:era EMPTY> +<!ATTLIST number:era number:style (short|long) "short"> +<!ATTLIST number:era number:calendar CDATA #IMPLIED> +<!ELEMENT number:day-of-week EMPTY> +<!ATTLIST number:day-of-week number:style (short|long) "short"> +<!ATTLIST number:day-of-week number:calendar CDATA #IMPLIED> +<!ELEMENT number:week-of-year EMPTY> +<!ATTLIST number:week-of-year number:calendar CDATA #IMPLIED> +<!ELEMENT number:quarter EMPTY> +<!ATTLIST number:quarter number:style (short|long) "short"> +<!ATTLIST number:quarter number:calendar CDATA #IMPLIED> + +<!ENTITY % any-time "( number:hours | number:am-pm | number:minutes | number:seconds )"> +<!ENTITY % time-style-content "( (number:text,(%any-time;,number:text?)+) | (%any-time;,number:text?)+)"> +<!ELEMENT number:time-style ( style:properties?, %time-style-content;, style:map* )> +<!ELEMENT number:hours EMPTY> +<!ATTLIST number:hours number:style (short|long) "short"> +<!ELEMENT number:minutes EMPTY> +<!ATTLIST number:minutes number:style (short|long) "short"> +<!ELEMENT number:seconds EMPTY> +<!ATTLIST number:seconds number:style (short|long) "short"> +<!ATTLIST number:seconds number:decimal-places %integer; "0"> +<!ELEMENT number:am-pm EMPTY> + +<!ENTITY % boolean-style-content "( (number:text,(number:boolean,number:text?)?) | (number:boolean,number:text?) )"> +<!ELEMENT number:boolean-style ( style:properties?,%boolean-style-content;, style:map* )> +<!ELEMENT number:boolean EMPTY> + +<!ENTITY % text-style-content "( (number:text,(number:text-content,number:text?)?) | (number:text-content,number:text?) )"> +<!ELEMENT number:text-style ( style:properties?,%text-style-content;, style:map* )> +<!ELEMENT number:text (#PCDATA)> +<!ELEMENT number:text-content EMPTY> + +<!ATTLIST number:number-style style:name %styleName; #REQUIRED> +<!ATTLIST number:currency-style style:name %styleName; #REQUIRED> +<!ATTLIST number:percentage-style style:name %styleName; #REQUIRED> +<!ATTLIST number:date-style style:name %styleName; #REQUIRED> +<!ATTLIST number:time-style style:name %styleName; #REQUIRED> +<!ATTLIST number:boolean-style style:name %styleName; #REQUIRED> +<!ATTLIST number:text-style style:name %styleName; #REQUIRED> + +<!ATTLIST number:number-style style:family CDATA #REQUIRED> +<!ATTLIST number:currency-style style:family CDATA #REQUIRED> +<!ATTLIST number:percentage-style style:family CDATA #REQUIRED> +<!ATTLIST number:date-style style:family CDATA #REQUIRED> +<!ATTLIST number:time-style style:family CDATA #REQUIRED> +<!ATTLIST number:boolean-style style:family CDATA #REQUIRED> +<!ATTLIST number:text-style style:family CDATA #REQUIRED> + +<!ATTLIST number:number-style number:language CDATA #IMPLIED> +<!ATTLIST number:currency-style number:language CDATA #IMPLIED> +<!ATTLIST number:percentage-style number:language CDATA #IMPLIED> +<!ATTLIST number:date-style number:language CDATA #IMPLIED> +<!ATTLIST number:time-style number:language CDATA #IMPLIED> +<!ATTLIST number:boolean-style number:language CDATA #IMPLIED> +<!ATTLIST number:text-style number:language CDATA #IMPLIED> + +<!ATTLIST number:number-style number:country CDATA #IMPLIED> +<!ATTLIST number:currency-style number:country CDATA #IMPLIED> +<!ATTLIST number:percentage-style number:country CDATA #IMPLIED> +<!ATTLIST number:date-style number:country CDATA #IMPLIED> +<!ATTLIST number:time-style number:country CDATA #IMPLIED> +<!ATTLIST number:boolean-style number:country CDATA #IMPLIED> +<!ATTLIST number:text-style number:country CDATA #IMPLIED> + +<!ATTLIST number:number-style number:title CDATA #IMPLIED> +<!ATTLIST number:currency-style number:title CDATA #IMPLIED> +<!ATTLIST number:percentage-style number:title CDATA #IMPLIED> +<!ATTLIST number:date-style number:title CDATA #IMPLIED> +<!ATTLIST number:time-style number:title CDATA #IMPLIED> +<!ATTLIST number:boolean-style number:title CDATA #IMPLIED> +<!ATTLIST number:text-style number:title CDATA #IMPLIED> + +<!ATTLIST number:number-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:currency-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:percentage-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:date-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:time-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:boolean-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:text-style style:volatile %boolean; #IMPLIED> + +<!ATTLIST number:currency-style number:automatic-order %boolean; "false"> +<!ATTLIST number:date-style number:automatic-order %boolean; "false"> + +<!ATTLIST number:date-style number:format-source (fixed|language) "fixed"> +<!ATTLIST number:time-style number:format-source (fixed|language) "fixed"> + +<!ATTLIST number:time-style number:truncate-on-overflow %boolean; "true"> + +<!ATTLIST number:number number:decimal-places %integer; #IMPLIED> +<!ATTLIST number:scientific-number number:decimal-places %integer; #IMPLIED> + +<!ATTLIST number:number number:min-integer-digits %integer; #IMPLIED> +<!ATTLIST number:scientific-number number:min-integer-digits %integer; #IMPLIED> +<!ATTLIST number:fraction number:min-integer-digits %integer; #IMPLIED> + +<!ATTLIST number:number number:grouping %boolean; "false"> +<!ATTLIST number:scientific-number number:grouping %boolean; "false"> +<!ATTLIST number:fraction number:grouping %boolean; "false"> + +<!ATTLIST number:number number:decimal-replacement CDATA #IMPLIED> + +<!ATTLIST number:scientific-number number:min-exponent-digits %integer; #IMPLIED> + +<!ATTLIST number:fraction number:min-numerator-digits %integer; #IMPLIED> + +<!ATTLIST number:fraction number:min-denominator-digits %integer; #IMPLIED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/drawing.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/drawing.mod new file mode 100755 index 000000000000..d200a39fe7f9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/drawing.mod @@ -0,0 +1,841 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: drawing.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % points "CDATA" > +<!ENTITY % pathData "CDATA" > +<!ENTITY % gradient-style "(linear|axial|radial|ellipsoid|square|rectangular)" > +<!ENTITY % draw-position "svg:x %coordinate; #IMPLIED svg:y %coordinate; #IMPLIED"> +<!ENTITY % draw-end-position "table:end-cell-address %cell-address; #IMPLIED table:end-x %coordinate; #IMPLIED table:end-y %coordinate; #IMPLIED"> +<!ENTITY % draw-size "svg:width %coordinate; #IMPLIED svg:height %coordinate; #IMPLIED"> +<!ENTITY % draw-transform "draw:transform CDATA #IMPLIED"> +<!ENTITY % draw-viewbox "svg:viewBox CDATA #REQUIRED"> +<!ENTITY % draw-style-name "draw:style-name %styleName; #IMPLIED presentation:style-name %styleName; #IMPLIED draw:text-style-name %styleName; #IMPLIED"> +<!ENTITY % draw-shape-id "CDATA #IMPLIED" > +<!ENTITY % draw-text "(text:p|text:unordered-list|text:ordered-list)*"> +<!ENTITY % zindex "draw:z-index %nonNegativeInteger; #IMPLIED"> +<!ENTITY % distance "CDATA"> +<!ENTITY % rectanglePoint "(top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right)"> +<!ENTITY % vector3D "CDATA"> +<!ENTITY % text-anchor "text:anchor-type %anchorType; #IMPLIED text:anchor-page-number %positiveInteger; #IMPLIED"> +<!ENTITY % layerName "CDATA"> +<!ENTITY % table-background "table:table-background (true | false) #IMPLIED"> + +<!-- commont presentation shape attributes --> +<!ENTITY % presentation-style-name "presentation:style-name %styleName; #IMPLIED"> +<!ENTITY % presentation-classes "(title|outline|subtitle|text|graphic|object|chart|table|orgchart|page|notes)" > +<!-- ENTITY % presentation-class "presentation:class %presentation-classes; #IMPLIED" --> +<!ENTITY % presentation-class "presentation:class %presentation-classes; #IMPLIED presentation:placeholder (true|false) #IMPLIED presentation:user-transformed (true|false) #IMPLIED"> +<!ENTITY % presentationEffects "(none|fade|move|stripes|open|close|dissolve|wavyline|random|lines|laser|appear|hide|move-short|checkerboard|rotate|stretch)" > +<!ENTITY % presentationEffectDirections "(none|from-left|from-top|from-right|from-bottom|from-center|from-upper-left|from-upper-right|from-lower-left|from-lower-right|to-left|to-top|to-right|to-bottom|to-upper-left|to-upper-right|to-lower-right|to-lower-left|path|spiral-inward-left|spiral-inward-right|spiral-outward-left|spiral-outward-right|vertical|horizontal|to-center|clockwise|counter-clockwise)" > +<!ENTITY % presentationSpeeds "(slow|medium|fast)" > + +<!-- Drawing shapes --> +<!ELEMENT draw:rect ( office:events?, %draw-text; )> +<!ATTLIST draw:rect %draw-position; > +<!ATTLIST draw:rect %draw-end-position; > +<!ATTLIST draw:rect %table-background; > +<!ATTLIST draw:rect %draw-size; > +<!ATTLIST draw:rect %draw-style-name; > +<!ATTLIST draw:rect %draw-transform; > +<!ATTLIST draw:rect draw:corner-radius %nonNegativeLength; #IMPLIED> +<!ATTLIST draw:rect %zindex;> +<!ATTLIST draw:rect draw:id %draw-shape-id;> +<!ATTLIST draw:rect %text-anchor;> +<!ATTLIST draw:rect draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:line ( office:events?, %draw-text; )> +<!ATTLIST draw:line svg:x1 %length; #REQUIRED> +<!ATTLIST draw:line svg:y1 %length; #REQUIRED> +<!ATTLIST draw:line svg:x2 %length; #REQUIRED> +<!ATTLIST draw:line svg:y2 %length; #REQUIRED> +<!ATTLIST draw:line %draw-style-name; > +<!ATTLIST draw:line %draw-transform; > +<!ATTLIST draw:line %zindex;> +<!ATTLIST draw:line %draw-end-position; > +<!ATTLIST draw:line %table-background; > +<!ATTLIST draw:line draw:id %draw-shape-id;> +<!ATTLIST draw:line %text-anchor;> +<!ATTLIST draw:line draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:polyline ( office:events?, %draw-text; )> +<!ATTLIST draw:polyline %draw-position; > +<!ATTLIST draw:polyline %draw-size; > +<!ATTLIST draw:polyline %draw-viewbox; > +<!ATTLIST draw:polyline draw:points %points; #REQUIRED> +<!ATTLIST draw:polyline %draw-style-name; > +<!ATTLIST draw:polyline %draw-transform; > +<!ATTLIST draw:polyline %zindex;> +<!ATTLIST draw:polyline %draw-end-position; > +<!ATTLIST draw:polyline %table-background; > +<!ATTLIST draw:polyline draw:id %draw-shape-id;> +<!ATTLIST draw:polyline %text-anchor;> +<!ATTLIST draw:polyline draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:polygon ( office:events?, %draw-text; )> +<!ATTLIST draw:polygon %draw-position; > +<!ATTLIST draw:polygon %draw-end-position; > +<!ATTLIST draw:polygon %table-background; > +<!ATTLIST draw:polygon %draw-size; > +<!ATTLIST draw:polygon %draw-viewbox; > +<!ATTLIST draw:polygon draw:points %points; #REQUIRED > +<!ATTLIST draw:polygon %draw-style-name; > +<!ATTLIST draw:polygon %draw-transform; > +<!ATTLIST draw:polygon %zindex;> +<!ATTLIST draw:polygon draw:id %draw-shape-id;> +<!ATTLIST draw:polygon %text-anchor;> +<!ATTLIST draw:polygon draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:path ( office:events?, %draw-text; )> +<!ATTLIST draw:path %draw-position;> +<!ATTLIST draw:path %draw-end-position; > +<!ATTLIST draw:path %table-background; > +<!ATTLIST draw:path %draw-size; > +<!ATTLIST draw:path %draw-viewbox; > +<!ATTLIST draw:path svg:d %pathData; #REQUIRED > +<!ATTLIST draw:path %draw-style-name; > +<!ATTLIST draw:path %draw-transform; > +<!ATTLIST draw:path %zindex;> +<!ATTLIST draw:path draw:id %draw-shape-id;> +<!ATTLIST draw:path %text-anchor;> +<!ATTLIST draw:path draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:circle ( office:events?, %draw-text; )> +<!ATTLIST draw:circle %draw-position; > +<!ATTLIST draw:circle %draw-size; > +<!ATTLIST draw:circle %draw-style-name; > +<!ATTLIST draw:circle %draw-transform; > +<!ATTLIST draw:circle %zindex;> +<!ATTLIST draw:circle %draw-end-position; > +<!ATTLIST draw:circle %table-background; > +<!ATTLIST draw:circle draw:id %draw-shape-id;> +<!ATTLIST draw:circle draw:kind (full|section|cut|arc) "full"> +<!ATTLIST draw:circle draw:start-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:circle draw:end-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:circle %text-anchor;> +<!ATTLIST draw:circle draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:ellipse ( office:events?, %draw-text; )> +<!ATTLIST draw:ellipse %draw-position; > +<!ATTLIST draw:ellipse %draw-size; > +<!ATTLIST draw:ellipse %draw-style-name; > +<!ATTLIST draw:ellipse %draw-transform; > +<!ATTLIST draw:ellipse %zindex;> +<!ATTLIST draw:ellipse %draw-end-position; > +<!ATTLIST draw:ellipse %table-background; > +<!ATTLIST draw:ellipse draw:id %draw-shape-id;> +<!ATTLIST draw:ellipse draw:kind (full|section|cut|arc) "full"> +<!ATTLIST draw:ellipse draw:start-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:ellipse draw:end-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:ellipse %text-anchor;> +<!ATTLIST draw:ellipse draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:connector ( office:events?, %draw-text;)> +<!ATTLIST draw:connector draw:type (standard|lines|line|curve) "standard"> +<!ATTLIST draw:connector draw:line-skew CDATA #IMPLIED> +<!ATTLIST draw:connector %draw-style-name;> +<!ATTLIST draw:connector svg:x1 %coordinate; #REQUIRED> +<!ATTLIST draw:connector svg:y1 %coordinate; #REQUIRED> +<!ATTLIST draw:connector svg:x2 %coordinate; #REQUIRED> +<!ATTLIST draw:connector svg:y2 %coordinate; #REQUIRED> +<!ATTLIST draw:connector draw:start-shape %draw-shape-id;> +<!ATTLIST draw:connector draw:start-glue-point %integer; #IMPLIED> +<!ATTLIST draw:connector draw:end-shape %draw-shape-id;> +<!ATTLIST draw:connector draw:end-glue-point %integer; #IMPLIED> +<!ATTLIST draw:connector %zindex;> +<!ATTLIST draw:connector %draw-end-position; > +<!ATTLIST draw:connector %table-background; > +<!ATTLIST draw:connector draw:id %draw-shape-id;> +<!ATTLIST draw:connector %text-anchor;> +<!ATTLIST draw:connector draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:control EMPTY> +<!ATTLIST draw:control %draw-style-name;> +<!ATTLIST draw:control %draw-position; > +<!ATTLIST draw:control %draw-size; > +<!ATTLIST draw:control %control-id; > +<!ATTLIST draw:control %zindex;> +<!ATTLIST draw:control %draw-end-position; > +<!ATTLIST draw:control %table-background; > +<!ATTLIST draw:control draw:id %draw-shape-id;> +<!ATTLIST draw:control %text-anchor;> +<!ATTLIST draw:control draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:g ( office:events?, (%shapes;)* ) > +<!ATTLIST draw:g %draw-transform; > +<!ATTLIST draw:g %draw-style-name; > +<!ATTLIST draw:g %zindex;> +<!ATTLIST draw:g %draw-end-position; > +<!ATTLIST draw:g %table-background; > +<!ATTLIST draw:g draw:id %draw-shape-id;> +<!ATTLIST draw:g %text-anchor;> +<!ATTLIST draw:g draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:page-thumbnail EMPTY> +<!ATTLIST draw:page-thumbnail draw:page-number %positiveInteger; #IMPLIED> +<!ATTLIST draw:page-thumbnail %draw-position; > +<!ATTLIST draw:page-thumbnail %draw-size; > +<!ATTLIST draw:page-thumbnail %draw-style-name; > +<!ATTLIST draw:page-thumbnail %presentation-class; > +<!ATTLIST draw:page-thumbnail %zindex;> +<!ATTLIST draw:page-thumbnail %draw-end-position; > +<!ATTLIST draw:page-thumbnail %table-background; > +<!ATTLIST draw:page-thumbnail draw:id %draw-shape-id;> +<!ATTLIST draw:page-thumbnail %text-anchor;> +<!ATTLIST draw:page-thumbnail draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:caption ( office:events?, %draw-text;)> +<!ATTLIST draw:caption %draw-position; > +<!ATTLIST draw:caption %draw-end-position; > +<!ATTLIST draw:caption %table-background; > +<!ATTLIST draw:caption %draw-size; > +<!ATTLIST draw:caption %draw-style-name; > +<!ATTLIST draw:caption %draw-transform; > +<!ATTLIST draw:caption draw:caption-point-x %coordinate; #IMPLIED> +<!ATTLIST draw:caption draw:caption-point-y %coordinate; #IMPLIED> +<!ATTLIST draw:caption %zindex;> +<!ATTLIST draw:caption draw:id %draw-shape-id;> +<!ATTLIST draw:caption %text-anchor;> +<!ATTLIST draw:caption draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:caption draw:corner-radius %nonNegativeLength; #IMPLIED> + +<!ELEMENT draw:measure ( office:events?, %draw-text;)> +<!ATTLIST draw:measure svg:x1 %coordinate; #REQUIRED> +<!ATTLIST draw:measure svg:y1 %coordinate; #REQUIRED> +<!ATTLIST draw:measure svg:x2 %coordinate; #REQUIRED> +<!ATTLIST draw:measure svg:y2 %coordinate; #REQUIRED> +<!ATTLIST draw:measure %draw-end-position; > +<!ATTLIST draw:measure %table-background; > +<!ATTLIST draw:measure %draw-style-name; > +<!ATTLIST draw:measure %draw-transform; > +<!ATTLIST draw:measure %zindex;> +<!ATTLIST draw:measure draw:id %draw-shape-id;> +<!ATTLIST draw:measure %text-anchor;> +<!ATTLIST draw:measure draw:layer %layerName; #IMPLIED> + +<!-- graphic style elements --> +<!ELEMENT draw:gradient EMPTY > +<!ATTLIST draw:gradient draw:name %styleName; #REQUIRED> +<!ATTLIST draw:gradient draw:style %gradient-style; #REQUIRED> +<!ATTLIST draw:gradient draw:cx %coordinate; #IMPLIED> +<!ATTLIST draw:gradient draw:cy %coordinate; #IMPLIED> +<!ATTLIST draw:gradient draw:start-color %color; #IMPLIED> +<!ATTLIST draw:gradient draw:end-color %color; #IMPLIED> +<!ATTLIST draw:gradient draw:start-intensity %percentage; #IMPLIED> +<!ATTLIST draw:gradient draw:end-intensity %percentage; #IMPLIED> +<!ATTLIST draw:gradient draw:angle %integer; #IMPLIED> +<!ATTLIST draw:gradient draw:border %percentage; #IMPLIED> + +<!ELEMENT draw:hatch EMPTY > +<!ATTLIST draw:hatch draw:name %styleName; #REQUIRED> +<!ATTLIST draw:hatch draw:style (single|double|triple) #REQUIRED > +<!ATTLIST draw:hatch draw:color %color; #IMPLIED> +<!ATTLIST draw:hatch draw:distance %length; #IMPLIED> +<!ATTLIST draw:hatch draw:rotation %integer; #IMPLIED> + + +<!ELEMENT draw:fill-image EMPTY > +<!ATTLIST draw:fill-image draw:name %styleName; #REQUIRED> +<!ATTLIST draw:fill-image xlink:href %uriReference; #REQUIRED> +<!ATTLIST draw:fill-image xlink:type (simple) #IMPLIED> +<!ATTLIST draw:fill-image xlink:show (embed) #IMPLIED> +<!ATTLIST draw:fill-image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:fill-image svg:width %length; #IMPLIED> +<!ATTLIST draw:fill-image svg:height %length; #IMPLIED> + +<!ELEMENT draw:transparency EMPTY> +<!ATTLIST draw:transparency draw:name %styleName; #REQUIRED> +<!ATTLIST draw:transparency draw:style %gradient-style; #REQUIRED> +<!ATTLIST draw:transparency draw:cx %coordinate; #IMPLIED> +<!ATTLIST draw:transparency draw:cy %coordinate; #IMPLIED> +<!ATTLIST draw:transparency draw:start %percentage; #IMPLIED> +<!ATTLIST draw:transparency draw:end %percentage; #IMPLIED> +<!ATTLIST draw:transparency draw:angle %integer; #IMPLIED> +<!ATTLIST draw:transparency draw:border %percentage; #IMPLIED> + +<!ELEMENT draw:marker EMPTY> +<!ATTLIST draw:marker draw:name %styleName; #REQUIRED> +<!ATTLIST draw:marker %draw-viewbox; > +<!ATTLIST draw:marker svg:d %pathData; #REQUIRED> + +<!ELEMENT draw:stroke-dash EMPTY> +<!ATTLIST draw:stroke-dash draw:name %styleName; #REQUIRED> +<!ATTLIST draw:stroke-dash draw:style (rect|round) #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots1 %integer; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots1-length %length; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots2 %integer; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots2-length %length; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:distance %length; #IMPLIED> + +<!-- stroke attributes --> +<!ATTLIST style:properties draw:stroke (none|dash|solid) #IMPLIED> +<!ATTLIST style:properties draw:stroke-dash CDATA #IMPLIED> +<!ATTLIST style:properties svg:stroke-width %length; #IMPLIED> +<!ATTLIST style:properties svg:stroke-color %color; #IMPLIED> +<!ATTLIST style:properties draw:marker-start %styleName; #IMPLIED> +<!ATTLIST style:properties draw:marker-end %styleName; #IMPLIED> +<!ATTLIST style:properties draw:marker-start-width %length; #IMPLIED> +<!ATTLIST style:properties draw:marker-end-width %length; #IMPLIED> +<!ATTLIST style:properties draw:marker-start-center %boolean; #IMPLIED> +<!ATTLIST style:properties draw:marker-end-center %boolean; #IMPLIED> +<!ATTLIST style:properties svg:stroke-opacity %floatOrPercentage; #IMPLIED> +<!ATTLIST style:properties svg:stroke-linejoin (miter|round|bevel|middle|none|inherit) #IMPLIED> + +<!-- text attributes --> +<!ATTLIST style:properties draw:auto-grow-width %boolean; #IMPLIED> +<!ATTLIST style:properties draw:auto-grow-height %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fit-to-size %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fit-to-contour %boolean; #IMPLIED> +<!ATTLIST style:properties draw:textarea-horizontal-align ( left | center | right | justify ) #IMPLIED> +<!ATTLIST style:properties draw:textarea-vertical-align ( top | middle | bottom ) #IMPLIED> + +<!-- fill attributes --> +<!ATTLIST style:properties draw:fill (none|solid|bitmap|gradient|hatch) #IMPLIED> +<!ATTLIST style:properties draw:fill-color %color; #IMPLIED> +<!ATTLIST style:properties draw:fill-gradient-name %styleName; #IMPLIED> +<!ATTLIST style:properties draw:gradient-step-count CDATA #IMPLIED> +<!ATTLIST style:properties draw:fill-hatch-name %styleName; #IMPLIED> +<!ATTLIST style:properties draw:fill-hatch-solid %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-name %styleName; #IMPLIED> +<!ATTLIST style:properties style:repeat (no-repeat|repeat|stretch) #IMPLIED> +<!ATTLIST style:properties draw:fill-image-width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-ref-point-x %percentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-ref-point-y %percentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-ref-point %rectanglePoint; #IMPLIED> +<!ATTLIST style:properties draw:tile-repeat-offset CDATA #IMPLIED> +<!ATTLIST style:properties draw:transparency %percentage; #IMPLIED> +<!ATTLIST style:properties draw:transparency-name %styleName; #IMPLIED> + +<!-- graphic attributes --> +<!ATTLIST style:properties draw:color-mode (greyscale|mono|watermark|standard) #IMPLIED> +<!ATTLIST style:properties draw:luminance %percentage; #IMPLIED> +<!ATTLIST style:properties draw:contrast %percentage; #IMPLIED> +<!ATTLIST style:properties draw:gamma %percentage; #IMPLIED> +<!ATTLIST style:properties draw:red %percentage; #IMPLIED> +<!ATTLIST style:properties draw:green %percentage; #IMPLIED> +<!ATTLIST style:properties draw:blue %percentage; #IMPLIED> +<!ATTLIST style:properties draw:color-inversion %boolean; #IMPLIED> + +<!-- shadow attributes --> +<!ATTLIST style:properties draw:shadow (visible|hidden) #IMPLIED> +<!ATTLIST style:properties draw:shadow-offset-x %length; #IMPLIED> +<!ATTLIST style:properties draw:shadow-offset-y %length; #IMPLIED> +<!ATTLIST style:properties draw:shadow-color %color; #IMPLIED> +<!ATTLIST style:properties draw:shadow-transparency CDATA #IMPLIED> + +<!-- connector attributes --> +<!ATTLIST style:properties draw:start-line-spacing-horizontal %distance; #IMPLIED> +<!ATTLIST style:properties draw:start-line-spacing-vertical %distance; #IMPLIED> +<!ATTLIST style:properties draw:end-line-spacing-horizontal %distance; #IMPLIED> +<!ATTLIST style:properties draw:end-line-spacing-vertical %distance; #IMPLIED> + +<!-- measure attributes --> +<!ATTLIST style:properties draw:line-distance %distance; #IMPLIED> +<!ATTLIST style:properties draw:guide-overhang %distance; #IMPLIED> +<!ATTLIST style:properties draw:guide-distance %distance; #IMPLIED> +<!ATTLIST style:properties draw:start-guide %distance; #IMPLIED> +<!ATTLIST style:properties draw:end-guide %distance; #IMPLIED> +<!ATTLIST style:properties draw:measure-align (automatic|left-outside|inside|right-outside) #IMPLIED> +<!ATTLIST style:properties draw:measure-vertical-align (automatic|above|below|center) #IMPLIED> +<!ATTLIST style:properties draw:unit (automatic|mm|cm|m|km|pt|pc|inch|ft|mi) #IMPLIED> +<!ATTLIST style:properties draw:show-unit %boolean; #IMPLIED> +<!ATTLIST style:properties draw:placing (below|above) #IMPLIED> +<!ATTLIST style:properties draw:parallel %boolean; #IMPLIED> + +<!-- frame attributes --> +<!ATTLIST style:properties draw:frame-display-scrollbar %boolean; #IMPLIED> +<!ATTLIST style:properties draw:frame-display-border %boolean; #IMPLIED> +<!ATTLIST style:properties draw:frame-margin-horizontal %nonNegativePixelLength; #IMPLIED> +<!ATTLIST style:properties draw:frame-margin-vertical %nonNegativePixelLength; #IMPLIED> +<!ATTLIST style:properties draw:size-protect %boolean; #IMPLIED> +<!ATTLIST style:properties draw:move-protect %boolean; #IMPLIED> + +<!-- ole object attributes --> +<!ATTLIST style:properties draw:visible-area-left %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties draw:visible-area-top %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties draw:visible-area-width %positiveLength; #IMPLIED> +<!ATTLIST style:properties draw:visible-area-height %positiveLength; #IMPLIED> + +<!-- fontwork attributes --> +<!ATTLIST style:properties draw:fontwork-style (rotate|upright|slant-x|slant-y|none) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-adjust (left|right|autosize|center) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-distance %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-start %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-mirror %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-outline %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow (normal|slant|none) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-color %color; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-offset-x %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-offset-y %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-form (none|top-circle|bottom-circle|left-circle|right-circle|top-arc|bottom-arc|left-arc|right-arc|button1|button2|button3|button4) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-hide-form %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-transparence %percentage; #IMPLIED> + +<!-- caption attributes --> +<!ATTLIST style:properties draw:caption-type (straight-line|angled-line|angled-connector-line) #IMPLIED> +<!ATTLIST style:properties draw:caption-angle-type (fixed|free) #IMPLIED> +<!ATTLIST style:properties draw:caption-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties draw:caption-gap %distance; #IMPLIED> +<!ATTLIST style:properties draw:caption-escape-direction (horizontal|vertical|auto) #IMPLIED> +<!ATTLIST style:properties draw:caption-escape %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties draw:caption-line-length %distance; #IMPLIED> +<!ATTLIST style:properties draw:caption-fit-line-length %boolean; #IMPLIED> + +<!-- Animations --> +<!ELEMENT presentation:sound EMPTY> +<!ATTLIST presentation:sound xlink:href %uriReference; #REQUIRED> +<!ATTLIST presentation:sound xlink:type (simple) #FIXED "simple"> +<!ATTLIST presentation:sound xlink:show (new|replace) #IMPLIED> +<!ATTLIST presentation:sound xlink:actuate (onRequest) "onRequest"> +<!ATTLIST presentation:sound presentation:play-full %boolean; #IMPLIED> + +<!ELEMENT presentation:show-shape (presentation:sound)?> +<!ATTLIST presentation:show-shape draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:show-shape presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:show-shape presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:show-shape presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:show-shape presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:show-shape presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:show-text (presentation:sound)?> +<!ATTLIST presentation:show-text draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:show-text presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:show-text presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:show-text presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:show-text presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:show-text presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:hide-shape (presentation:sound)?> +<!ATTLIST presentation:hide-shape draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:hide-shape presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:hide-shape presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:hide-shape presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:hide-shape presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:hide-shape presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:hide-text (presentation:sound)?> +<!ATTLIST presentation:hide-text draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:hide-text presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:hide-text presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:hide-text presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:hide-text presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:hide-text presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:dim (presentation:sound)?> +<!ATTLIST presentation:dim draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:dim draw:color %color; #REQUIRED> + +<!ELEMENT presentation:play EMPTY> +<!ATTLIST presentation:play draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:play presentation:speed %presentationSpeeds; "medium"> + +<!ELEMENT presentation:animations (presentation:show-shape|presentation:show-text|presentation:hide-shape|presentation:hide-text|presentation:dim|presentation:play)*> + +<!ELEMENT presentation:show EMPTY> +<!ATTLIST presentation:show presentation:name %styleName; #REQUIRED> +<!ATTLIST presentation:show presentation:pages CDATA #REQUIRED> + +<!ELEMENT presentation:settings (presentation:show)*> +<!ATTLIST presentation:settings presentation:start-page %styleName; #IMPLIED> +<!ATTLIST presentation:settings presentation:show %styleName; #IMPLIED> +<!ATTLIST presentation:settings presentation:full-screen %boolean; "true"> +<!ATTLIST presentation:settings presentation:endless %boolean; "false"> +<!ATTLIST presentation:settings presentation:pause %timeDuration; #IMPLIED> +<!ATTLIST presentation:settings presentation:show-logo %boolean; "false"> +<!ATTLIST presentation:settings presentation:force-manual %boolean; "false"> +<!ATTLIST presentation:settings presentation:mouse-visible %boolean; "true"> +<!ATTLIST presentation:settings presentation:mouse-as-pen %boolean; "false"> +<!ATTLIST presentation:settings presentation:start-with-navigator %boolean; "false"> +<!ATTLIST presentation:settings presentation:animations (enabled|disabled) "enabled"> +<!ATTLIST presentation:settings presentation:stay-on-top %boolean; "false"> +<!ATTLIST presentation:settings presentation:transition-on-click (enabled|disabled) "enabled"> + +<!-- Drawing page --> +<!ELEMENT draw:page (office:forms?,(%shapes;)*,presentation:animations?,presentation:notes?)> +<!ATTLIST draw:page draw:name %string; #IMPLIED> +<!ATTLIST draw:page draw:style-name %styleName; #IMPLIED> +<!ATTLIST draw:page draw:master-page-name %styleName; #REQUIRED> +<!ATTLIST draw:page presentation:presentation-page-layout-name %styleName; #IMPLIED> +<!ATTLIST draw:page draw:id %nonNegativeInteger; #IMPLIED> + +<!-- Presentation notes --> +<!ELEMENT presentation:notes (%shapes;)*> + + +<!-- presentation page layouts --> +<!ELEMENT style:presentation-page-layout (presentation:placeholder)* > +<!ATTLIST style:presentation-page-layout style:name %styleName; #REQUIRED> +<!ELEMENT presentation:placeholder EMPTY > +<!ATTLIST presentation:placeholder presentation:object (title|outline|subtitle|text|graphic|object|chart|orgchart|page|notes|handout) #REQUIRED> +<!ATTLIST presentation:placeholder svg:x %coordinateOrPercentage; #REQUIRED> +<!ATTLIST presentation:placeholder svg:y %coordinateOrPercentage; #REQUIRED> +<!ATTLIST presentation:placeholder svg:width %lengthOrPercentage; #REQUIRED> +<!ATTLIST presentation:placeholder svg:height %lengthOrPercentage; #REQUIRED> + +<!-- presentation page attributes --> +<!ATTLIST style:properties presentation:transition-type (manual|automatic|semi-automatic) #IMPLIED > +<!ATTLIST style:properties presentation:transition-style (none|fade-from-left|fade-from-top|fade-from-right|fade-from-bottom|fade-to-center|fade-from-center|move-from-left|move-from-top|move-from-right|move-from-bottom|roll-from-top|roll-from-left|roll-from-right|roll-from-bottom|vertical-stripes|horizontal-stripes|clockwise|counterclockwise|fade-from-upperleft|fade-from-upperright|fade-from-lowerleft|fade-from-lowerright|close-vertical|close-horizontal|open-vertical|open-horizontal|spiralin-left|spiralin-right|spiralout-left|spiralout-right|dissolve|wavyline-from-left|wavyline-from-top|wavyline-from-right|wavyline-from-bottom|random|stretch-from-left|stretch-from-top|stretch-from-right|stretch-from-bottom|vertical-lines|horizontal-lines) #IMPLIED > +<!ATTLIST style:properties presentation:transition-speed %presentationSpeeds; #IMPLIED > +<!ATTLIST style:properties presentation:duration %timeDuration; #IMPLIED> +<!ATTLIST style:properties presentation:visibility (visible|hidden) #IMPLIED> +<!ATTLIST style:properties draw:background-size (full|border) #IMPLIED> +<!ATTLIST style:properties presentation:background-objects-visible %boolean; #IMPLIED> +<!ATTLIST style:properties presentation:background-visible %boolean; #IMPLIED> + + +<!-- text boxes --> +<!ELEMENT draw:text-box (office:events?,draw:image-map?, + (text:h|text:p|text:ordered-list| + text:unordered-list|table:table|chart:chart| + draw:a|draw:text-box|draw:image)*)> +<!ATTLIST draw:text-box %draw-style-name;> +<!ATTLIST draw:text-box %draw-transform; > +<!ATTLIST draw:text-box draw:name %string; #IMPLIED> +<!ATTLIST draw:text-box draw:chain-next-name %string; #IMPLIED> + +<!ATTLIST draw:text-box %text-anchor;> +<!ATTLIST draw:text-box %draw-position;> +<!ATTLIST draw:text-box %draw-end-position; > +<!ATTLIST draw:text-box %table-background; > +<!ATTLIST draw:text-box svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:text-box svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:text-box fo:min-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:text-box %zindex;> +<!ATTLIST draw:text-box %presentation-class; > +<!ATTLIST draw:text-box %draw-transform; > +<!ATTLIST draw:text-box draw:id %draw-shape-id;> +<!ATTLIST draw:text-box draw:layer %layerName; #IMPLIED> + +<!-- image --> +<!ELEMENT draw:image (office:binary-data?,office:events?,draw:image-map?,svg:desc?,(draw:contour-polygon|draw:contour-path)?)> +<!ATTLIST draw:image %draw-style-name;> +<!ATTLIST draw:image draw:name %string; #IMPLIED> +<!ATTLIST draw:image xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:image xlink:type (simple) #IMPLIED> +<!ATTLIST draw:image xlink:show (embed) #IMPLIED> +<!ATTLIST draw:image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:image draw:filter-name %string; #IMPLIED> +<!ATTLIST draw:image %text-anchor;> +<!ATTLIST draw:image %draw-position;> +<!ATTLIST draw:image %draw-end-position; > +<!ATTLIST draw:image %table-background; > +<!ATTLIST draw:image svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:image svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:image %presentation-class; > +<!ATTLIST draw:image %zindex;> +<!ATTLIST draw:image draw:id %draw-shape-id;> +<!ATTLIST draw:image draw:layer %layerName; #IMPLIED> + +<!-- objects --> +<!ELEMENT draw:thumbnail EMPTY> +<!ATTLIST draw:thumbnail xlink:href %uriReference; #REQUIRED> +<!ATTLIST draw:thumbnail xlink:type (simple) #IMPLIED> +<!ATTLIST draw:thumbnail xlink:show (embed) #IMPLIED> +<!ATTLIST draw:thumbnail xlink:actuate (onLoad) #IMPLIED> + +<!ELEMENT math:math ANY> <!-- dummy (we have no MathML DTD currently)--> +<!ELEMENT draw:object (draw:thumbnail?,(office:document|math:math)?,office:events?, draw:image-map?, svg:desc?,(draw:contour-polygon|draw:contour-path)?)> +<!ATTLIST draw:object %draw-style-name;> +<!ATTLIST draw:object draw:name %string; #IMPLIED> +<!ATTLIST draw:object xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:object xlink:type (simple) #IMPLIED> +<!ATTLIST draw:object xlink:show (embed) #IMPLIED> +<!ATTLIST draw:object xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:object %text-anchor;> +<!ATTLIST draw:object %draw-position;> +<!ATTLIST draw:object %draw-end-position; > +<!ATTLIST draw:object %table-background; > +<!ATTLIST draw:object svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object %presentation-class; > +<!ATTLIST draw:object %zindex;> +<!ATTLIST draw:object draw:id %draw-shape-id;> +<!ATTLIST draw:object draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:object draw:notify-on-update-of-ranges %string; #IMPLIED> + +<!ELEMENT draw:object-ole (office:binary-data?|office:events?|draw:image-map?|svg:desc?|draw:contour-polygon?|draw:contour-path?|draw:thumbnail?)> +<!ATTLIST draw:object-ole draw:class-id CDATA #IMPLIED> +<!ATTLIST draw:object-ole %draw-style-name;> +<!ATTLIST draw:object-ole draw:name %string; #IMPLIED> +<!ATTLIST draw:object-ole xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:object-ole xlink:type (simple) #IMPLIED> +<!ATTLIST draw:object-ole xlink:show (embed) #IMPLIED> +<!ATTLIST draw:object-ole xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:object-ole %text-anchor;> +<!ATTLIST draw:object-ole %draw-position;> +<!ATTLIST draw:object-ole %draw-end-position; > +<!ATTLIST draw:object-ole %table-background; > +<!ATTLIST draw:object-ole svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object-ole svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object-ole %presentation-class; > +<!ATTLIST draw:object-ole %zindex;> +<!ATTLIST draw:object-ole draw:id %draw-shape-id;> +<!ATTLIST draw:object-ole draw:layer %layerName; #IMPLIED> + +<!ELEMENT svg:desc (#PCDATA)> + +<!ELEMENT draw:contour-polygon EMPTY> +<!ATTLIST draw:contour-polygon svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:contour-polygon svg:height %coordinate; #REQUIRED> +<!ATTLIST draw:contour-polygon %draw-viewbox;> +<!ATTLIST draw:contour-polygon svg:points %points; #REQUIRED> + +<!ELEMENT draw:contour-path EMPTY> +<!ATTLIST draw:contour-path svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:contour-path svg:height %coordinate; #REQUIRED> +<!ATTLIST draw:contour-path %draw-viewbox;> +<!ATTLIST draw:contour-path svg:d %pathData; #REQUIRED> + +<!-- hyperlink --> +<!ELEMENT draw:a (draw:image|draw:text-box)> +<!ATTLIST draw:a xlink:href %uriReference; #REQUIRED> +<!ATTLIST draw:a xlink:type (simple) #FIXED "simple"> +<!ATTLIST draw:a xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:a xlink:actuate (onRequest) "onRequest"> +<!ATTLIST draw:a office:name %string; #IMPLIED> +<!ATTLIST draw:a office:target-frame-name %string; #IMPLIED> +<!ATTLIST draw:a office:server-map %boolean; "false"> + +<!-- 3d properties --> +<!ATTLIST style:properties dr3d:horizontal-segments %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties dr3d:vertical-segments %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties dr3d:edge-rounding %percentage; #IMPLIED> +<!ATTLIST style:properties dr3d:edge-rounding-mode (correct|attractive) #IMPLIED> +<!ATTLIST style:properties dr3d:back-scale %percentage; #IMPLIED> +<!ATTLIST style:properties dr3d:end-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties dr3d:depth %length; #IMPLIED> +<!ATTLIST style:properties dr3d:backface-culling (enabled|disabled) #IMPLIED> +<!ATTLIST style:properties dr3d:lighting-mode (standard|double-sided) #IMPLIED> +<!ATTLIST style:properties dr3d:normals-kind (object|flat|sphere) #IMPLIED> +<!ATTLIST style:properties dr3d:normals-direction (normal|inverse) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-generation-mode-x (object|parallel|sphere) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-generation-mode-y (object|parallel|sphere) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-kind (luminance|intesity|color) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-filter (enabled|disabled) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-mode (replace|modulate|blend) #IMPLIED> +<!ATTLIST style:properties dr3d:ambient-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:emissive-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:specular-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:diffuse-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:shininess %percentage; #IMPLIED> +<!ATTLIST style:properties dr3d:shadow (visible|hidden) #IMPLIED> + +<!ELEMENT dr3d:light EMPTY> +<!ATTLIST dr3d:light dr3d:diffuse-color %color; #IMPLIED> +<!ATTLIST dr3d:light dr3d:direction %vector3D; #REQUIRED> +<!ATTLIST dr3d:light dr3d:enabled %boolean; #IMPLIED> +<!ATTLIST dr3d:light dr3d:specular %boolean; #IMPLIED> + +<!ENTITY % shapes3d "(dr3d:scene|dr3d:extrude|dr3d:sphere|dr3d:rotate|dr3d:cube)"> + +<!ELEMENT dr3d:cube EMPTY> +<!ATTLIST dr3d:cube dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:cube dr3d:min-edge %vector3D; #IMPLIED> +<!ATTLIST dr3d:cube dr3d:max-edge %vector3D; #IMPLIED> +<!ATTLIST dr3d:cube %zindex;> +<!ATTLIST dr3d:cube draw:id %draw-shape-id;> +<!ATTLIST dr3d:cube %draw-end-position; > +<!ATTLIST dr3d:cube %table-background; > +<!ATTLIST dr3d:cube %draw-style-name; > +<!ATTLIST dr3d:cube draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:sphere EMPTY> +<!ATTLIST dr3d:sphere dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:sphere dr3d:center %vector3D; #IMPLIED> +<!ATTLIST dr3d:sphere dr3d:size %vector3D; #IMPLIED> +<!ATTLIST dr3d:sphere %zindex;> +<!ATTLIST dr3d:sphere draw:id %draw-shape-id;> +<!ATTLIST dr3d:sphere %draw-end-position; > +<!ATTLIST dr3d:sphere %table-background; > +<!ATTLIST dr3d:sphere %draw-style-name; > +<!ATTLIST dr3d:sphere draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:extrude EMPTY> +<!ATTLIST dr3d:extrude dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:extrude %draw-viewbox;> +<!ATTLIST dr3d:extrude svg:d %pathData; #REQUIRED > +<!ATTLIST dr3d:extrude %zindex;> +<!ATTLIST dr3d:extrude draw:id %draw-shape-id;> +<!ATTLIST dr3d:extrude %draw-end-position; > +<!ATTLIST dr3d:extrude %table-background; > +<!ATTLIST dr3d:extrude %draw-style-name; > +<!ATTLIST dr3d:extrude draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:rotate EMPTY> +<!ATTLIST dr3d:rotate dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:rotate %draw-viewbox;> +<!ATTLIST dr3d:rotate svg:d %pathData; #REQUIRED > +<!ATTLIST dr3d:rotate %zindex;> +<!ATTLIST dr3d:rotate draw:id %draw-shape-id;> +<!ATTLIST dr3d:rotate %draw-end-position; > +<!ATTLIST dr3d:rotate %table-background; > +<!ATTLIST dr3d:rotate %draw-style-name; > +<!ATTLIST dr3d:rotate draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:scene (dr3d:light*,(%shapes3d;)*)> +<!ATTLIST dr3d:scene %draw-style-name; > +<!ATTLIST dr3d:scene svg:x %coordinate; #IMPLIED> +<!ATTLIST dr3d:scene svg:y %coordinate; #IMPLIED> +<!ATTLIST dr3d:scene svg:width %length; #IMPLIED> +<!ATTLIST dr3d:scene svg:height %length; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:vrp %vector3D; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:vpn %vector3D; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:vup %vector3D; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:projection (parallel|perspective) #IMPLIED> +<!ATTLIST dr3d:scene dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:scene dr3d:distance %length; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:focal-length %length; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:shadow-slant %nonNegativeInteger; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:shade-mode (flat|phong|gouraud|draft) #IMPLIED> +<!ATTLIST dr3d:scene dr3d:ambient-color %color; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:lighting-mode %boolean; #IMPLIED> +<!ATTLIST dr3d:scene %zindex;> +<!ATTLIST dr3d:scene draw:id %draw-shape-id;> +<!ATTLIST dr3d:scene %draw-end-position; > +<!ATTLIST dr3d:scene %table-background; > + +<!-- layer --> + +<!ELEMENT draw:layer-set (draw:layer*)> + +<!ELEMENT draw:layer EMPTY> +<!ATTLIST draw:layer draw:name %layerName; #REQUIRED> + +<!-- events --> +<!ELEMENT presentation:event (presentation:sound)?> +<!ATTLIST presentation:event %event-name;> +<!ATTLIST presentation:event presentation:action (none|previous-page|next-page|first-page|last-page|hide|stop|execute|show|verb|fade-out|sound) #REQUIRED> +<!ATTLIST presentation:event presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:event presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:event presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:event presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:event xlink:href %uriReference; #IMPLIED> +<!ATTLIST presentation:event xlink:type (simple) #IMPLIED> +<!ATTLIST presentation:event xlink:show (embed) #IMPLIED> +<!ATTLIST presentation:event xlink:actuate (onRequest) #IMPLIED> +<!ATTLIST presentation:event presentation:verb %nonNegativeInteger; #IMPLIED> + +<!-- applets --> +<!ELEMENT draw:applet (draw:thumbnail?, draw:param*, svg:desc?)> +<!ATTLIST draw:applet xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:applet xlink:type (simple) #IMPLIED> +<!ATTLIST draw:applet xlink:show (embed) #IMPLIED> +<!ATTLIST draw:applet xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:applet draw:code CDATA #REQUIRED> +<!ATTLIST draw:applet draw:object CDATA #IMPLIED> +<!ATTLIST draw:applet draw:archive CDATA #IMPLIED> +<!ATTLIST draw:applet draw:may-script %boolean; "false"> +<!ATTLIST draw:applet draw:name CDATA #IMPLIED> +<!ATTLIST draw:applet %draw-style-name;> +<!ATTLIST draw:applet svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:applet svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:applet %zindex;> +<!ATTLIST draw:applet draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:applet %draw-position;> +<!ATTLIST draw:applet %draw-end-position; > + +<!-- plugins --> +<!ELEMENT draw:plugin (draw:thumbnail?, draw:param*, svg:desc?)> +<!ATTLIST draw:plugin xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:plugin xlink:type (simple) #IMPLIED> +<!ATTLIST draw:plugin xlink:show (embed) #IMPLIED> +<!ATTLIST draw:plugin xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:plugin draw:mime-type CDATA #IMPLIED> +<!ATTLIST draw:plugin draw:name CDATA #IMPLIED> +<!ATTLIST draw:plugin %draw-style-name;> +<!ATTLIST draw:plugin svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:plugin svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:plugin %zindex;> +<!ATTLIST draw:plugin draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:plugin %draw-position;> +<!ATTLIST draw:plugin %draw-end-position; > + +<!-- Paramaters --> +<!ELEMENT draw:param EMPTY> +<!ATTLIST draw:param draw:name CDATA #IMPLIED> +<!ATTLIST draw:param draw:value CDATA #IMPLIED> + +<!-- Floating Frames --> +<!ELEMENT draw:floating-frame (draw:thumbnail?, svg:desc?)> +<!ATTLIST draw:floating-frame xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:floating-frame xlink:type (simple) #IMPLIED> +<!ATTLIST draw:floating-frame xlink:show (embed) #IMPLIED> +<!ATTLIST draw:floating-frame xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:floating-frame draw:name CDATA #IMPLIED> +<!ATTLIST draw:floating-frame draw:frame-name CDATA #IMPLIED> +<!ATTLIST draw:floating-frame %draw-style-name;> +<!ATTLIST draw:floating-frame svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:floating-frame svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:floating-frame %zindex;> +<!ATTLIST draw:floating-frame draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:floating-frame %draw-position;> +<!ATTLIST draw:floating-frame %draw-end-position; > + +<!-- Image Maps --> +<!ELEMENT draw:image-map + (draw:area-rectangle|draw:area-circle|draw:area-polygon)*> + +<!ELEMENT draw:area-rectangle (svg:desc?,office:events?)> +<!ATTLIST draw:area-rectangle xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:area-rectangle xlink:type (simple) #IMPLIED> +<!ATTLIST draw:area-rectangle office:target-frame-name CDATA #IMPLIED> +<!ATTLIST draw:area-rectangle xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:area-rectangle office:name CDATA #IMPLIED> +<!ATTLIST draw:area-rectangle draw:nohref (nohref) #IMPLIED> +<!ATTLIST draw:area-rectangle svg:x %coordinate; #REQUIRED> +<!ATTLIST draw:area-rectangle svg:y %coordinate; #REQUIRED> +<!ATTLIST draw:area-rectangle svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:area-rectangle svg:height %coordinate; #REQUIRED> + +<!ELEMENT draw:area-circle (svg:desc?,office:events?)> +<!ATTLIST draw:area-circle xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:area-circle xlink:type (simple) #IMPLIED> +<!ATTLIST draw:area-circle office:target-frame-name CDATA #IMPLIED> +<!ATTLIST draw:area-circle xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:area-circle office:name CDATA #IMPLIED> +<!ATTLIST draw:area-circle draw:nohref (nohref) #IMPLIED> +<!ATTLIST draw:area-circle svg:cx %coordinate; #REQUIRED> +<!ATTLIST draw:area-circle svg:cy %coordinate; #REQUIRED> +<!ATTLIST draw:area-circle svg:r %coordinate; #REQUIRED> + +<!ELEMENT draw:area-polygon (svg:desc?,office:events?)> +<!ATTLIST draw:area-polygon xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:area-polygon xlink:type (simple) #IMPLIED> +<!ATTLIST draw:area-polygon office:target-frame-name CDATA #IMPLIED> +<!ATTLIST draw:area-polygon xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:area-polygon office:name CDATA #IMPLIED> +<!ATTLIST draw:area-polygon draw:nohref (nohref) #IMPLIED> +<!ATTLIST draw:area-polygon svg:x %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:y %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:height %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:points %points; #REQUIRED> +<!ATTLIST draw:area-polygon svg:viewBox CDATA #REQUIRED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/dtypes.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/dtypes.mod new file mode 100755 index 000000000000..1cdd7bf50785 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/dtypes.mod @@ -0,0 +1,147 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: dtypes.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!-- datatypes corresponding to XML Schema Part 2 W3C Working draft of --> +<!-- 07 April 2000 --> + +<!-- string --> +<!ENTITY % string "CDATA"> +<!ENTITY % cString "#PCDATA"> + +<!-- boolean (values are "true" and "false" --> +<!ENTITY % boolean "CDATA"> + +<!-- integer ( ..., -2, -1, 0, 1, 2, ...) --> +<!ENTITY % integer "CDATA"> + +<!-- non negative integer ( 0, 1, 2, ...) --> +<!ENTITY % nonNegativeInteger "CDATA"> + +<!-- positive integer ( 1, 2, ...) --> +<!ENTITY % positiveInteger "CDATA"> +<!ENTITY % cPositiveInteger "#PCDATA"> + +<!ENTITY % positiveNumberOrDefault "CDATA"> + +<!-- time duration as specified by ISO8601, section 5.5.3.2 --> +<!ENTITY % timeDuration "CDATA"> +<!ENTITY % cTimeDuration "#PCDATA"> + +<!-- time instance as specified by ISO8601, section 5.4 --> +<!ENTITY % timeInstance "CDATA"> +<!ENTITY % cTimeInstance "#PCDATA"> + +<!-- date instance as specified by ISO8601, section 5.2.1.1, extended format--> +<!ENTITY % date "CDATA"> +<!ENTITY % cDate "#PCDATA"> + +<!-- date duration, like timDuration but truncated to full dates --> +<!ENTITY % dateDuration "CDATA"> +<!ENTITY % cDateDuration "#PCDATA"> + +<!-- URI reference --> +<!ENTITY % uriReference "CDATA"> + +<!-- language code as specified by RFC1766 --> +<!ENTITY % language "CDATA"> +<!ENTITY % cLanguage "#PCDATA"> + +<!-- float --> +<!ENTITY % float "CDATA"> + +<!-- Some other common used data types --> + +<!-- a single UNICODE character --> +<!ENTITY % character "CDATA"> + +<!-- a style name --> +<!ENTITY % styleName "CDATA"> + +<!-- a target frame mame --> +<!ENTITY % targetFrameName "CDATA"> + +<!-- a language without a country as specified by ISO639 --> +<!ENTITY % languageOnly "CDATA"> + +<!-- a country as specified by ISO3166 --> +<!ENTITY % country "CDATA"> + +<!-- a color value having the format #rrggbb --> +<!ENTITY % color "CDATA"> +<!-- a color value having the format #rrggbb or "transparent" --> +<!ENTITY % transparentOrColor "CDATA"> + +<!-- a percentage --> +<!ENTITY % percentage "CDATA"> + +<!-- a length (i.e. 1cm or .6inch) --> +<!ENTITY % length "CDATA"> +<!ENTITY % positiveLength "CDATA"> +<!ENTITY % nonNegativeLength "CDATA"> +<!ENTITY % lengthOrNoLimit "CDATA"> + +<!-- a length or a percentage --> +<!ENTITY % lengthOrPercentage "CDATA"> +<!ENTITY % positiveLengthOrPercentage "CDATA"> + +<!-- a pixel length (i.e. 2px) --> +<!ENTITY % nonNegativePixelLength "CDATA"> + +<!-- a float or a percentage --> +<!ENTITY % floatOrPercentage "CDATA"> + +<!-- a text encoding --> +<!ENTITY % textEncoding "CDATA"> + +<!-- cell address and cell range address --> +<!ENTITY % cell-address "CDATA"> +<!ENTITY % cell-range-address "CDATA"> +<!ENTITY % cell-range-address-list "CDATA"> + +<!-- value types --> +<!ENTITY % valueType "(float|time|date|percentage|currency|boolean|string)"> + +<!-- an svg coordinate in different distance formats --> +<!ENTITY % coordinate "CDATA"> + +<!ENTITY % coordinateOrPercentage "CDATA"> + +<!ENTITY % shape "draw:rect|draw:line|draw:polyline|draw:polygon|draw:path| + draw:circle|draw:ellipse|draw:g|draw:page-thumbnail| + draw:text-box|draw:image|draw:object|draw:object-ole| + draw:applet|draw:floating-frame|draw:plugin| + draw:measure|draw:caption|draw:connector|chart:chart| + dr3d:scene|draw:control" > +<!ENTITY % shapes "(%shape;)" > + +<!ENTITY % anchorType "(page|frame|paragraph|char|as-char)"> + +<!ENTITY % control-id "form:id CDATA #REQUIRED"> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/form.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/form.mod new file mode 100755 index 000000000000..7c39fe5fd43b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/form.mod @@ -0,0 +1,312 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: form.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % controls "form:text|form:textarea|form:fixed-text|form:file| + form:password|form:formatted-text|form:button|form:image| + form:checkbox|form:radio|form:listbox|form:combobox|form:frame| + form:hidden|form:image-frame|form:grid|form:generic-control"> + +<!ENTITY % name "form:name CDATA #IMPLIED"> +<!ENTITY % service-name "form:service-name CDATA #IMPLIED"> + +<!ENTITY % navigation "(none|current|parent)"> +<!ENTITY % cycles "(records|current|page)"> +<!ENTITY % url "CDATA"> + + +<!ENTITY % types "(submit|reset|push|url)"> +<!ENTITY % button-type "form:button-type %types; 'push'"> +<!ENTITY % current-selected "form:current-selected %boolean; 'false'"> +<!ENTITY % current-value "form:current-value CDATA #IMPLIED"> +<!ENTITY % value "form:value CDATA #IMPLIED"> +<!ENTITY % disabled "form:disabled %boolean; 'false'"> +<!ENTITY % dropdown "form:dropdown %boolean; 'false'"> +<!ENTITY % for "form:for CDATA #IMPLIED"> +<!ENTITY % image-data "form:image-data %url; #IMPLIED"> +<!ENTITY % label "form:label CDATA #IMPLIED"> +<!ENTITY % max-length "form:max-length CDATA #IMPLIED"> +<!ENTITY % printable "form:printable %boolean; 'true'"> +<!ENTITY % readonly "form:readonly %boolean; 'false'"> +<!ENTITY % size "form:size CDATA #IMPLIED"> +<!ENTITY % selected "form:selected %boolean; 'false'"> +<!ENTITY % size "form:size CDATA #IMPLIED"> +<!ENTITY % tab-index "form:tab-index CDATA #IMPLIED"> +<!ENTITY % target-frame "office:target-frame CDATA '_blank'"> +<!ENTITY % target-location "xlink:href %url; #IMPLIED"> +<!ENTITY % tab-stop "form:tab-stop %boolean; 'true'"> +<!ENTITY % title "form:title CDATA #IMPLIED"> +<!ENTITY % default-value "form:default-value CDATA #IMPLIED"> +<!ENTITY % bound-column "form:bound-column CDATA #IMPLIED"> +<!ENTITY % convert-empty "form:convert-empty-to-null %boolean; 'false'"> +<!ENTITY % data-field "form:data-field CDATA #IMPLIED"> +<!ENTITY % list-source "form:list-source CDATA #IMPLIED"> +<!ENTITY % list-source-types "(table|query|sql|sql-pass-through|value-list|table-fields)"> +<!ENTITY % list-source-type "form:list-source-type %list-source-types; #IMPLIED"> + +<!ELEMENT form:control (%controls;)+> +<!ATTLIST form:control %name; + %service-name; + %control-id;> + +<!ELEMENT form:form (form:properties?, office:events?, (form:control|form:form)*)> +<!ATTLIST form:form %name; %service-name;> +<!ATTLIST form:form xlink:href %url; #IMPLIED> +<!ATTLIST form:form form:enctype CDATA "application/x-www-form-urlencoded"> +<!ATTLIST form:form form:method CDATA "get"> +<!ATTLIST form:form office:target-frame CDATA "_blank"> +<!ATTLIST form:form form:allow-deletes %boolean; "true"> +<!ATTLIST form:form form:allow-inserts %boolean; "true"> +<!ATTLIST form:form form:allow-updates %boolean; "true"> +<!ATTLIST form:form form:apply-filter %boolean; "false"> +<!ATTLIST form:form form:command CDATA #IMPLIED> +<!ATTLIST form:form form:command-type (table|query|command) "command"> +<!ATTLIST form:form form:datasource CDATA #IMPLIED> +<!ATTLIST form:form form:detail-fields CDATA #IMPLIED> +<!ATTLIST form:form form:escape-processing %boolean; "true"> +<!ATTLIST form:form form:filter CDATA #IMPLIED> +<!ATTLIST form:form form:ignore-result %boolean; "false"> +<!ATTLIST form:form form:master-fields CDATA #IMPLIED> +<!ATTLIST form:form form:navigation-mode %navigation; #IMPLIED> +<!ATTLIST form:form form:order CDATA #IMPLIED> +<!ATTLIST form:form form:tab-cycle %cycles; #IMPLIED> + +<!ELEMENT office:forms (form:form*)> +<!ATTLIST office:forms form:automatic-focus %boolean; "false"> +<!ATTLIST office:forms form:apply-design-mode %boolean; "true"> + +<!ELEMENT form:text (form:properties?, office:events?)> +<!ATTLIST form:text %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field;> + +<!ELEMENT form:textarea (form:properties?, office:events?)> +<!ATTLIST form:textarea %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field;> + +<!ELEMENT form:password (form:properties?, office:events?)> +<!ATTLIST form:password %disabled; + %max-length; + %printable; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty;> + +<!ATTLIST form:password form:echo-char CDATA "*"> + +<!ELEMENT form:file (form:properties?, office:events?)> +<!ATTLIST form:file %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value;> + +<!ELEMENT form:formatted-text (form:properties?, office:events?)> +<!ATTLIST form:formatted-text %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field;> +<!ATTLIST form:formatted-text form:max-value CDATA #IMPLIED> +<!ATTLIST form:formatted-text form:min-value CDATA #IMPLIED> +<!ATTLIST form:formatted-text form:validation %boolean; "false"> + +<!ELEMENT form:fixed-text (form:properties?, office:events?)> +<!ATTLIST form:fixed-text %for; + %disabled; + %label; + %printable; + %title;> +<!ATTLIST form:fixed-text form:multi-line %boolean; "false"> + +<!ELEMENT form:combobox (form:properties?, office:events?, form:item*)> +<!ATTLIST form:combobox %current-value; + %disabled; + %dropdown; + %max-length; + %printable; + %readonly; + %size; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field; + %list-source; + %list-source-type;> +<!ATTLIST form:combobox form:auto-complete %boolean; #IMPLIED> + +<!ELEMENT form:item (#PCDATA)> +<!ATTLIST form:item %label;> + +<!ELEMENT form:listbox (form:properties?, office:events?, form:option*)> +<!ATTLIST form:listbox %disabled; + %dropdown; + %printable; + %size; + %tab-index; + %tab-stop; + %title; + %bound-column; + %data-field; + %list-source; + %list-source-type;> +<!ATTLIST form:listbox form:multiple %boolean; "false"> + +<!ELEMENT form:option (#PCDATA)> +<!ATTLIST form:option %current-selected; + %selected; + %label; + %value;> + +<!ELEMENT form:button (form:properties?, office:events?)> +<!ATTLIST form:button %button-type; + %disabled; + %label; + %image-data; + %printable; + %tab-index; + %tab-stop; + %target-frame; + %target-location; + %title; + %value;> +<!ATTLIST form:button form:default-button %boolean; "false"> + +<!ELEMENT form:image (form:properties?, office:events?)> +<!ATTLIST form:image %button-type; + %disabled; + %image-data; + %printable; + %tab-index; + %tab-stop; + %target-frame; + %target-location; + %title; + %value;> + +<!ELEMENT form:checkbox (form:properties?, office:events?)> +<!ATTLIST form:checkbox %disabled; + %label; + %printable; + %tab-index; + %tab-stop; + %title; + %value; + %data-field;> +<!ENTITY % states "(unchecked|checked|unknown)"> +<!ATTLIST form:checkbox form:current-state %states; #IMPLIED> +<!ATTLIST form:checkbox form:is-tristate %boolean; "false"> +<!ATTLIST form:checkbox form:state %states; "unchecked"> + +<!ELEMENT form:radio (form:properties?, office:events?)> +<!ATTLIST form:radio %current-selected; + %disabled; + %label; + %printable; + %selected; + %tab-index; + %tab-stop; + %title; + %value; + %data-field;> + +<!ELEMENT form:frame (form:properties?, office:events?)> +<!ATTLIST form:frame %disabled; + %for; + %label; + %printable; + %title;> + +<!ELEMENT form:image-frame (form:properties?, office:events?)> +<!ATTLIST form:image-frame %disabled; + %image-data; + %printable; + %readonly; + %title; + %data-field;> + +<!ELEMENT form:hidden (form:properties?, office:events?)> +<!ATTLIST form:hidden %name; + %service-name; + %value;> + +<!ELEMENT form:grid (form:properties?, office:events?, form:column*)> +<!ATTLIST form:grid %disabled; + %printable; + %tab-index; + %tab-stop; + %title;> +<!ENTITY % column-type "form:text| form:textarea| form:formatted-text|form:checkbox| form:listbox| form:combobox"> +<!ELEMENT form:column (%column-type;)+> +<!ATTLIST form:column %name; + %service-name; + %label;> + +<!ELEMENT form:generic-control (form:properties?, office:events?)> + + +<!ELEMENT form:properties (form:property+)> +<!ELEMENT form:property (form:property-value*)> +<!ATTLIST form:property form:property-is-list %boolean; #IMPLIED> +<!ATTLIST form:property form:property-name CDATA #REQUIRED> +<!ATTLIST form:property form:property-type (boolean|short|int|long|double|string) #REQUIRED> +<!ELEMENT form:property-value (#PCDATA)> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/meta.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/meta.mod new file mode 100755 index 000000000000..0bef2535bcbf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/meta.mod @@ -0,0 +1,94 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: meta.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + +<!ELEMENT meta:generator (%cString;)> + +<!ELEMENT dc:title (%cString;)> + +<!ELEMENT dc:description (%cString;)> + +<!ELEMENT dc:subject (%cString;)> + +<!ELEMENT meta:keywords (meta:keyword)*> +<!ELEMENT meta:keyword (%cString;)> + +<!ELEMENT meta:initial-creator (%cString;)> + +<!ELEMENT dc:creator (%cString;)> + +<!ELEMENT meta:printed-by (%cString;)> + +<!ELEMENT meta:creation-date (%cTimeInstance;)> + +<!ELEMENT dc:date (%cTimeInstance;)> + +<!ELEMENT meta:print-date (%cTimeInstance;)> + +<!ELEMENT meta:template EMPTY> +<!ATTLIST meta:template xlink:type (simple) #FIXED "simple"> +<!ATTLIST meta:template xlink:actuate (onRequest) "onRequest"> +<!ATTLIST meta:template xlink:href %uriReference; #REQUIRED> +<!ATTLIST meta:template xlink:title %string; #IMPLIED> +<!ATTLIST meta:template meta:date %timeInstance; #IMPLIED> + +<!ELEMENT meta:auto-reload EMPTY> +<!ATTLIST meta:auto-reload xlink:type (simple) #IMPLIED> +<!ATTLIST meta:auto-reload xlink:show (replace) #IMPLIED> +<!ATTLIST meta:auto-reload xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST meta:auto-reload xlink:href %uriReference; #IMPLIED> +<!ATTLIST meta:auto-reload meta:delay %timeDuration; "P0S"> + +<!ELEMENT meta:hyperlink-behaviour EMPTY> +<!ATTLIST meta:hyperlink-behaviour office:target-frame-name %targetFrameName; #IMPLIED> +<!ATTLIST meta:hyperlink-behaviour xlink:show (new|replace) #IMPLIED> + +<!ELEMENT dc:language (%cLanguage;)> + +<!ELEMENT meta:editing-cycles (%cPositiveInteger;)> + +<!ELEMENT meta:editing-duration (%cTimeDuration;)> + +<!ELEMENT meta:user-defined (%cString;)> +<!ATTLIST meta:user-defined meta:name %string; #REQUIRED> + +<!ELEMENT meta:document-statistic EMPTY> +<!ATTLIST meta:document-statistic meta:page-count %positiveInteger; #IMPLIED + meta:table-count %nonNegativeInteger; #IMPLIED + meta:draw-count %nonNegativeInteger; #IMPLIED + meta:image-count %nonNegativeInteger; #IMPLIED + meta:ole-object-count %nonNegativeInteger; #IMPLIED + meta:paragraph-count %nonNegativeInteger; #IMPLIED + meta:word-count %nonNegativeInteger; #IMPLIED + meta:character-count %nonNegativeInteger; #IMPLIED + meta:row-count %nonNegativeInteger; #IMPLIED + meta:cell-count %nonNegativeInteger; #IMPLIED + meta:object-count %positiveInteger; #IMPLIED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/nmspace.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/nmspace.mod new file mode 100755 index 000000000000..3dd3c4177c82 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/nmspace.mod @@ -0,0 +1,54 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: nmspace.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY nFO "http://www.w3.org/1999/XSL/Format"> +<!ENTITY nXLink "http://www.w3.org/1999/xlink"> +<!ENTITY nSVG "http://www.w3.org/2000/svg"> + +<!-- StarOffice namespace names and prefixes --> + +<!ENTITY nOpenOffice "http://openoffice.org/2000"> +<!ENTITY nOpenOffice2001 "http://openoffice.org/2001"> + +<!ENTITY nOffice "&nOpenOffice;/office"> +<!ENTITY nStyle "&nOpenOffice;/style"> +<!ENTITY nText "&nOpenOffice;/text"> +<!ENTITY nTable "&nOpenOffice;/table"> +<!ENTITY nMeta "&nOpenOffice;/meta"> +<!ENTITY nScript "&nOpenOffice;/script"> +<!ENTITY nDraw "&nOpenOffice;/drawing"> +<!ENTITY nChart "&nOpenOffice;/chart"> +<!ENTITY nNumber "&nOpenOffice;/datastyle"> +<!ENTITY nConfig "&nOpenOffice2001;/config"> + + +<!-- dublin core namespace name and prefic --> +<!ENTITY nDC "http://purl.org/dc/elements/1.1/"> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/office.dtd b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/office.dtd new file mode 100755 index 000000000000..ef73319720b1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/office.dtd @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: office.dtd,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % dtypes-mod SYSTEM "dtypes.mod"> +%dtypes-mod; +<!ENTITY % nmspace-mod SYSTEM "nmspace.mod"> +%nmspace-mod; +<!ENTITY % style-mod SYSTEM "style.mod"> +%style-mod; +<!ENTITY % office-mod SYSTEM "office.mod"> +%office-mod; +<!ENTITY % meta-mod SYSTEM "meta.mod"> +%meta-mod; +<!ENTITY % script-mod SYSTEM "script.mod"> +%script-mod; +<!ENTITY % drawing-mod SYSTEM "drawing.mod"> +%drawing-mod; +<!ENTITY % text-mod SYSTEM "text.mod"> +%text-mod; +<!ENTITY % table-mod SYSTEM "table.mod"> +%table-mod; +<!ENTITY % chart-mod SYSTEM "chart.mod"> +%chart-mod; +<!ENTITY % datastyl-mod SYSTEM "datastyl.mod"> +%datastyl-mod; +<!ENTITY % form-mod SYSTEM "form.mod"> +%form-mod; +<!ENTITY % settings-mod SYSTEM "settings.mod"> +%settings-mod; diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/office.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/office.mod new file mode 100755 index 000000000000..ed543b22a520 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/office.mod @@ -0,0 +1,238 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: office.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT office:document ( office:meta?, + office:settings?, + office:script?, + office:font-decls?, + office:styles?, + office:automatic-styles?, + office:master-styles?, + office:body ) > + +<!ATTLIST office:document xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document office:class + (text|text-global| + drawing|presentation| + spreadsheet|chart) #REQUIRED> + +<!ATTLIST office:document office:version %string; #IMPLIED> + +<!-- document-styles --> +<!ELEMENT office:document-styles ( + office:font-decls?, + office:styles?, + office:automatic-styles?, + office:master-styles? ) > + +<!ATTLIST office:document-styles xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-styles xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document-styles xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document-styles xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document-styles xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document-styles xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document-styles xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document-styles xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document-styles xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document-styles xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document-styles xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-styles xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document-styles xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document-styles office:version %string; #IMPLIED> + +<!-- document-content --> + +<!ELEMENT office:document-content ( + office:script?, + office:font-decls?, + office:automatic-styles?, + office:body ) > + +<!ATTLIST office:document-content xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-content xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document-content xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document-content xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document-content xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document-content xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document-content xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document-content xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document-content xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document-content xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document-content xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-content xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document-content xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document-content office:class + (text|text-global| + drawing|presentation| + spreadsheet|chart) #REQUIRED> + +<!ATTLIST office:document-content office:version %string; #IMPLIED> + +<!-- document-content --> + +<!ELEMENT office:document-meta ( office:meta? ) > + +<!ATTLIST office:document-meta xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-meta xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document-meta xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document-meta xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document-meta xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document-meta xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document-meta xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document-meta xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document-meta xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document-meta xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document-meta xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-meta xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document-meta xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document-meta office:version %string; #IMPLIED> + +<!ELEMENT office:document-settings (office:settings) > +<!ATTLIST office:document-settings xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-settings xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-settings xmlns:config CDATA #FIXED "&nConfig;"> + +<!ATTLIST office:document-settings office:version %string; #IMPLIED> + +<!ENTITY % meta "(meta:generator?, + dc:title?, + dc:description?, + dc:subject?, + meta:initial-creator?, + meta:creation-date?, + dc:creator?, + dc:date?, + meta:printed-by?, + meta:print-date?, + meta:keywords?, + dc:language?, + meta:editing-cycles?, + meta:editing-duration?, + meta:hyperlink-behaviour?, + meta:auto-reload?, + meta:template?, + meta:user-defined*, + meta:document-statistic?)"> +<!ELEMENT office:meta %meta;> + +<!ENTITY % script "(script:library-embedded | + script:library-linked)*"> +<!ELEMENT office:script %script;> + +<!ELEMENT office:font-decls (style:font-decl)*> + +<!ENTITY % styles "(style:default-style|style:style|text:list-style| + number:number-style|number:currency-style|number:percentage-style| + number:date-style|number:time-style|number:boolean-style| + number:text-style| + draw:gradient|draw:hatch|draw:fill-image|draw:marker|draw:stroke-dash| + style:presentation-page-layout|draw:transparency)"> + +<!-- Validity constraint: The elements + text:outline-style, + text:footnotes-configuration, + text:endnotes-configuration, + text:bibliography-configuration and + text:linenumbering-configuration + may appear only once! + Unfortunatetly, this constraint cannot be easily specified in the DTD. +--> +<!ELEMENT office:styles (%styles;|text:outline-style| + text:footnotes-configuration|text:endnotes-configuration| + text:bibliography-configuration|text:linenumbering-configuration)*> + +<!ELEMENT office:automatic-styles (%styles;|style:page-master)*> + +<!ELEMENT office:master-styles (draw:layer-set?,style:handout-master?,style:master-page*) > + +<!ENTITY % text-decls "text:variable-decls?, text:sequence-decls?, + text:user-field-decls?, text:dde-connection-decls?, + text:alphabetical-index-auto-mark-file?" > + +<!ENTITY % change-marks "text:change | text:change-start | text:change-end"> + +<!ENTITY % body "(office:forms?,(text:tracked-changes|table:tracked-changes)?,%text-decls;,table:calculation-settings?,table:content-validations?,table:label-ranges?, + (text:h|text:p|text:ordered-list| + text:unordered-list|table:table|draw:page| + draw:a|%shape;|text:section|text:table-of-content| + text:illustration-index|text:table-index|text:object-index| + text:user-index|text:alphabetical-index|text:bibliography| + %change-marks;)*, + table:named-expressions?, + table:database-ranges?,table:data-pilot-tables?, + table:consolidation?, + table:dde-links?, + presentation:settings?)"> +<!ELEMENT office:body %body;> +<!ATTLIST office:body table:structure-protected %boolean; "false" + table:protection-key CDATA #IMPLIED> + +<!ELEMENT office:events (script:event|presentation:event)*> + +<!-- DDE source: for text sections and tables --> +<!ELEMENT office:dde-source EMPTY> +<!ATTLIST office:dde-source office:dde-application CDATA #IMPLIED> +<!ATTLIST office:dde-source office:dde-topic CDATA #IMPLIED> +<!ATTLIST office:dde-source office:dde-item CDATA #IMPLIED> +<!ATTLIST office:dde-source office:automatic-update %boolean; "false"> +<!ATTLIST office:dde-source office:name CDATA #IMPLIED> +<!ATTLIST office:dde-source table:conversion-mode (into-default-style-data-style|into-english-number|let-text) "into-default-style-data-style" > + +<!-- annotations --> +<!-- limitation: in the current implementation, only plain text inside of + paragraphs is supported --> +<!ELEMENT office:annotation (text:p)*> +<!ATTLIST office:annotation office:author %string; #IMPLIED> +<!ATTLIST office:annotation office:create-date %date; #IMPLIED> +<!ATTLIST office:annotation office:create-date-string %string; #IMPLIED> +<!ATTLIST office:annotation office:display %boolean; "false"> + +<!ELEMENT office:change-info (text:p)*> +<!ATTLIST office:change-info office:chg-author %string; #REQUIRED> +<!ATTLIST office:change-info office:chg-date-time %timeInstance; #REQUIRED> + +<!ELEMENT office:binary-data (#PCDATA)> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/script.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/script.mod new file mode 100755 index 000000000000..81220e346f20 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/script.mod @@ -0,0 +1,55 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: script.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT script:library-embedded (script:module*)> +<!ATTLIST script:library-embedded script:name %string; #REQUIRED> +<!ATTLIST script:library-embedded script:password %string; #IMPLIED> + +<!ELEMENT script:library-linked EMPTY> +<!ATTLIST script:library-linked script:name %string; #REQUIRED> +<!ATTLIST script:library-linked xlink:href %string; #REQUIRED> +<!ATTLIST script:library-linked xlink:type (simple) #FIXED "simple"> + +<!ELEMENT script:module (#PCDATA)> +<!ATTLIST script:module script:name %string; #REQUIRED> +<!ATTLIST script:module script:language %string; #IMPLIED> + + +<!ENTITY % script-language "script:language %string; #REQUIRED"> +<!ENTITY % event-name "script:event-name %string; #REQUIRED"> +<!ENTITY % location "script:location (document|application) #REQUIRED"> +<!ENTITY % macro-name "script:macro-name %string; #REQUIRED"> + +<!ELEMENT script:event (#PCDATA)> +<!ATTLIST script:event %script-language; + %event-name; + %location; + %macro-name;> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/settings.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/settings.mod new file mode 100755 index 000000000000..5ba8f38f3ba6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/settings.mod @@ -0,0 +1,53 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: settings.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT office:settings (config:config-item-set+)> + +<!ENTITY % items "(config:config-item | + config:config-item-set | + config:config-item-map-named | + config:config-item-map-indexed)+"> + +<!ELEMENT config:config-item-set %items;> +<!ATTLIST config:config-item-set config:name CDATA #REQUIRED> + +<!ELEMENT config:config-item (#PCDATA)> +<!ATTLIST config:config-item config:name CDATA #REQUIRED + config:type (boolean | short | int | long | double | string | datetime | base64Binary) #REQUIRED> + +<!ELEMENT config:config-item-map-named (config:config-item-map-entry)+> +<!ATTLIST config:config-item-map-named config:name CDATA #REQUIRED> + +<!ELEMENT config:config-item-map-indexed (config:config-item-map-entry)+> +<!ATTLIST config:config-item-map-indexed config:name CDATA #REQUIRED> + +<!ELEMENT config:config-item-map-entry %items;> +<!ATTLIST config:config-item-map-entry config:name CDATA #IMPLIED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/style.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/style.mod new file mode 100755 index 000000000000..5c5b3dca3c4b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/style.mod @@ -0,0 +1,395 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: style.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT style:font-decl EMPTY> +<!ATTLIST style:font-decl style:name %string; #REQUIRED> +<!ATTLIST style:font-decl fo:font-family %string; #REQUIRED> +<!ATTLIST style:font-decl style:font-style-name %string; #IMPLIED> +<!ENTITY % fontFamilyGeneric "(roman|swiss|modern|decorative|script|system)"> +<!ATTLIST style:font-decl style:font-family-generic %fontFamilyGeneric; + #IMPLIED> +<!ENTITY % fontPitch "(fixed|variable)"> +<!ATTLIST style:font-decl style:font-pitch %fontPitch; #IMPLIED> +<!ATTLIST style:font-decl style:font-charset %textEncoding; #IMPLIED> + +<!ELEMENT style:style ( style:properties?,office:events?,style:map*)> + +<!ATTLIST style:style style:name %styleName; #REQUIRED> + +<!ENTITY % styleFamily "(paragraph|text|section| + table|table-column|table-row|table-cell|table-page|chart|graphics|default|drawing-page|presentation|control)"> +<!ATTLIST style:style style:family %styleFamily; #REQUIRED> + +<!ATTLIST style:style style:parent-style-name %styleName; #IMPLIED> +<!ATTLIST style:style style:master-page-name %styleName; #IMPLIED> +<!ATTLIST style:style style:next-style-name %styleName; #IMPLIED> +<!ATTLIST style:style style:list-style-name %styleName; #IMPLIED> +<!ATTLIST style:style style:data-style-name %styleName; #IMPLIED> + +<!ATTLIST style:style style:auto-update %boolean; "false"> + +<!ATTLIST style:style style:class %string; #IMPLIED> + +<!ELEMENT style:default-style (style:properties?)> +<!ATTLIST style:default-style style:family %styleFamily; #REQUIRED> + +<!ELEMENT style:map EMPTY> + +<!ATTLIST style:map style:condition %string; #REQUIRED> +<!ATTLIST style:map style:apply-style-name %styleName; #REQUIRED> +<!ATTLIST style:map style:base-cell-address %cell-address; #IMPLIED> + +<!ELEMENT style:properties ANY> + +<!-- number format properties --> +<!ATTLIST style:properties style:num-prefix %string; #IMPLIED> +<!ATTLIST style:properties style:num-suffix %string; #IMPLIED> +<!ATTLIST style:properties style:num-format %string; #IMPLIED> +<!ATTLIST style:properties style:num-letter-sync %boolean; #IMPLIED> + +<!-- frame properties --> +<!ATTLIST style:properties fo:width %positiveLength; #IMPLIED> +<!ATTLIST style:properties fo:height %positiveLength; #IMPLIED> +<!ATTLIST style:properties style:vertical-pos (top|middle|bottom|from-top) #IMPLIED> +<!ATTLIST style:properties style:vertical-rel (page|page-content| + frame|frame-content| + paragraph|paragraph-content|char| + line|baseline|text) #IMPLIED> +<!ATTLIST style:properties style:horizontal-pos (left|center|right|from-left|inside|outside|from-inside) #IMPLIED> +<!ATTLIST style:properties style:horizontal-rel (page|page-content| + frame|frame-content| + paragraph|paragraph-content| + char) #IMPLIED> +<!ATTLIST style:properties svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:min-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:min-width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:max-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:max-width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties text:anchor-type %anchorType; #IMPLIED> +<!ATTLIST style:properties text:anchor-page-number %positiveInteger; #IMPLIED> +<!ATTLIST style:properties svg:x %coordinate; #IMPLIED> +<!ATTLIST style:properties svg:y %coordinate; #IMPLIED> +<!ATTLIST style:properties style:print-content %boolean; #IMPLIED> +<!ATTLIST style:properties style:protect %boolean; #IMPLIED> +<!ATTLIST style:properties style:wrap (none|left|right|parallel|dynamic|run-through) #IMPLIED> +<!ENTITY % noLimitOrPositiveInteger "CDATA"> +<!ATTLIST style:properties style:number-wrapped-paragraphs %noLimitOrPositiveInteger; #IMPLIED> +<!ATTLIST style:properties style:wrap-contour %boolean; #IMPLIED> +<!ATTLIST style:properties style:wrap-contour-mode (full|outside) #IMPLIED> +<!ATTLIST style:properties style:run-through (foreground|background) #IMPLIED> +<!ATTLIST style:properties style:editable %boolean; #IMPLIED> +<!ATTLIST style:properties style:mirror CDATA #IMPLIED> +<!ATTLIST style:properties fo:clip CDATA #IMPLIED> +<!ATTLIST style:properties text:animation (none|scroll|alternate|slide) #IMPLIED> +<!ATTLIST style:properties text:animation-direction (left|right|up|down) #IMPLIED> +<!ATTLIST style:properties text:animation-start-inside %boolean; #IMPLIED> +<!ATTLIST style:properties text:animation-stop-inside %boolean; #IMPLIED> +<!ATTLIST style:properties text:animation-repeat %integer; #IMPLIED> +<!ATTLIST style:properties text:animation-delay %timeDuration; #IMPLIED> +<!ATTLIST style:properties text:animation-steps %length; #IMPLIED> + +<!-- text properties --> +<!ATTLIST style:properties fo:font-variant (normal|small-caps) #IMPLIED> +<!ATTLIST style:properties fo:text-transform (none|lowercase| + uppercase|capitalize) #IMPLIED> +<!ATTLIST style:properties fo:color %color; #IMPLIED> +<!ATTLIST style:properties style:use-window-font-color %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-outline %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-crossing-out + (none|single-line|double-line|thick-line|slash|X) + #IMPLIED> +<!ATTLIST style:properties style:text-position CDATA #IMPLIED> +<!ATTLIST style:properties style:text-align (left|right|start|center|end|justify|justified) #IMPLIED> + +<!ATTLIST style:properties style:font-name %string; #IMPLIED> +<!ATTLIST style:properties fo:font-family %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-generic %fontFamilyGeneric; + #IMPLIED> +<!ATTLIST style:properties style:font-style-name %string; #IMPLIED> +<!ATTLIST style:properties style:font-pitch %fontPitch; #IMPLIED> +<!ATTLIST style:properties style:font-charset %textEncoding; #IMPLIED> +<!ATTLIST style:properties style:font-name-asian %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-asian %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-generic-asian %fontFamilyGeneric; + #IMPLIED> +<!ATTLIST style:properties style:font-style-name-asian %string; #IMPLIED> +<!ATTLIST style:properties style:font-pitch-asian %fontPitch; #IMPLIED> +<!ATTLIST style:properties style:font-charset-asian %textEncoding; #IMPLIED> +<!ATTLIST style:properties style:font-name-complex %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-complex %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-generic-complex %fontFamilyGeneric; + #IMPLIED> +<!ATTLIST style:properties style:font-style-name-complex %string; #IMPLIED> +<!ATTLIST style:properties style:font-pitch-complex %fontPitch; #IMPLIED> +<!ATTLIST style:properties style:font-charset-complex %textEncoding; #IMPLIED> + +<!ATTLIST style:properties fo:font-size %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:font-size-rel %length; #IMPLIED> +<!ATTLIST style:properties style:font-size-asian %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:font-size-rel-asian %length; #IMPLIED> +<!ATTLIST style:properties style:font-size-complex %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:font-size-rel-complex %length; #IMPLIED> +<!ENTITY % normalOrLength "CDATA"> +<!ATTLIST style:properties fo:letter-spacing %normalOrLength; #IMPLIED> +<!ATTLIST style:properties fo:language %languageOnly; #IMPLIED> +<!ATTLIST style:properties style:language-asian %languageOnly; #IMPLIED> +<!ATTLIST style:properties style:language-complex %languageOnly; #IMPLIED> +<!ATTLIST style:properties fo:country %country; #IMPLIED> +<!ATTLIST style:properties style:country-asian %country; #IMPLIED> +<!ATTLIST style:properties style:country-complex %country; #IMPLIED> +<!ENTITY % fontStyle "(normal|italic|oblique)"> +<!ATTLIST style:properties fo:font-style %fontStyle; #IMPLIED> +<!ATTLIST style:properties style:font-style-asian %fontStyle; #IMPLIED> +<!ATTLIST style:properties style:font-style-complex %fontStyle; #IMPLIED> +<!ENTITY % fontRelief "(none|embossed|engraved)"> +<!ATTLIST style:properties style:font-relief %fontRelief; #IMPLIED> +<!ATTLIST style:properties fo:text-shadow CDATA #IMPLIED> +<!ATTLIST style:properties style:text-underline + (none|single|double|dotted|dash|long-dash|dot-dash| + dot-dot-dash|wave|bold|bold-dotted|bold-dash| + bold-long-dash|bold-dot-dash|bold-dot-dot-dash| + bold-wave|double-wave|small-wave) #IMPLIED> +<!ATTLIST style:properties style:text-autospace (none | ideograph-alpha) #IMPLIED> +<!ATTLIST style:properties style:punctuation-wrap (simple | hanging) #IMPLIED> +<!ATTLIST style:properties style:line-break (normal | strict) #IMPLIED> +<!ENTITY % fontColorOrColor "CDATA"> +<!ATTLIST style:properties style:text-underline-color %fontColorOrColor; + #IMPLIED> +<!ATTLIST style:properties fo:font-weight CDATA #IMPLIED> +<!ATTLIST style:properties style:font-weight-asian CDATA #IMPLIED> +<!ATTLIST style:properties style:font-weight-complex CDATA #IMPLIED> +<!ATTLIST style:properties fo:score-spaces %boolean; #IMPLIED> +<!ATTLIST style:properties style:letter-kerning %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-blinking %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-background-color %transparentOrColor; + #IMPLIED> + +<!ATTLIST style:properties style:text-combine (none|letters|lines) #IMPLIED> +<!ATTLIST style:properties style:text-combine-start-char %character; #IMPLIED> +<!ATTLIST style:properties style:text-combine-end-char %character; #IMPLIED> +<!ATTLIST style:properties style:text-emphasize CDATA #IMPLIED> +<!ATTLIST style:properties style:text-scale %percentage; #IMPLIED> +<!ATTLIST style:properties style:text-rotation-angle %integer; #IMPLIED> +<!ATTLIST style:properties style:text-rotation-scale (fixed|line-height) #IMPLIED> + +<!-- paragraph properties --> +<!ENTITY % nonNegativeLengthOrPercentageOrNormal "CDATA"> +<!ATTLIST style:properties fo:line-height + %nonNegativeLengthOrPercentageOrNormal; #IMPLIED> +<!ATTLIST style:properties style:line-height-at-least %nonNegativeLength; + #IMPLIED> +<!ATTLIST style:properties style:line-spacing %length; #IMPLIED> +<!ATTLIST style:properties fo:text-align (start|end|center|justify) #IMPLIED> +<!ATTLIST style:properties fo:text-align-last (start|center|justify) #IMPLIED> +<!ATTLIST style:properties style:text-align-source (fix|value-type) #IMPLIED> +<!ATTLIST style:properties style:justify-single-word %boolean; #IMPLIED> +<!ATTLIST style:properties style:break-inside (auto|avoid) #IMPLIED> +<!ATTLIST style:properties fo:widows %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties fo:orphans %nonNegativeInteger; #IMPLIED> + +<!ATTLIST style:properties fo:hyphenate %boolean; #IMPLIED> +<!ATTLIST style:properties fo:hyphenate-keep (none|page) #IMPLIED> +<!ATTLIST style:properties fo:hyphenation-remain-char-count %positiveInteger; + #IMPLIED> +<!ATTLIST style:properties fo:hyphenation-push-char-count %positiveInteger; + #IMPLIED> +<!ATTLIST style:properties fo:hyphenation-ladder-count + %noLimitOrPositiveInteger; #IMPLIED> +<!ATTLIST style:properties style:page-number %positiveInteger; #IMPLIED> + +<!ELEMENT style:tab-stops (style:tab-stop)*> +<!ELEMENT style:tab-stop EMPTY> +<!ATTLIST style:tab-stop style:position %nonNegativeLength; #REQUIRED> +<!ATTLIST style:tab-stop style:type (left|center|right|char|default) "left"> +<!ATTLIST style:tab-stop style:char %character; #IMPLIED> +<!ATTLIST style:tab-stop style:leader-char %character; " "> + +<!ELEMENT style:drop-cap EMPTY> +<!ENTITY % wordOrPositiveInteger "CDATA"> +<!ATTLIST style:drop-cap style:length %wordOrPositiveInteger; "1"> +<!ATTLIST style:drop-cap style:lines %positiveInteger; "1"> +<!ATTLIST style:drop-cap style:distance %length; "0cm"> +<!ATTLIST style:drop-cap style:style-name %styleName; #IMPLIED> + +<!ATTLIST style:properties style:register-true %boolean; #IMPLIED> +<!ATTLIST style:properties style:register-truth-ref-style-name %styleName; #IMPLIED> +<!ATTLIST style:properties fo:margin-left %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:margin-right %positiveLengthOrPercentage; + #IMPLIED> +<!ATTLIST style:properties fo:text-indent %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:auto-text-indent %boolean; #IMPLIED> +<!ATTLIST style:properties fo:margin-top %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:margin-bottom %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:break-before (auto|column|page) #IMPLIED> +<!ATTLIST style:properties fo:break-after (auto|column|page) #IMPLIED> +<!ATTLIST style:properties fo:background-color %transparentOrColor; #IMPLIED> + +<!ELEMENT style:background-image (office:binary-data?)> +<!ATTLIST style:background-image xlink:type (simple) #IMPLIED> +<!ATTLIST style:background-image xlink:href %uriReference; #IMPLIED> +<!ATTLIST style:background-image xlink:show (embed) #IMPLIED> +<!ATTLIST style:background-image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST style:background-image style:repeat (no-repeat|repeat|stretch) + "repeat"> +<!ATTLIST style:background-image style:position CDATA "center"> +<!ATTLIST style:background-image style:filter-name %string; #IMPLIED> + +<!ELEMENT style:symbol-image (office:binary-data?)> +<!ATTLIST style:symbol-image xlink:type (simple) #IMPLIED> +<!ATTLIST style:symbol-image xlink:href %uriReference; #IMPLIED> +<!ATTLIST style:symbol-image xlink:show (embed) #IMPLIED> +<!ATTLIST style:symbol-image xlink:actuate (onLoad) #IMPLIED> + +<!ATTLIST style:properties fo:border CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-top CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-bottom CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-left CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-right CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-top CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-bottom CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-left CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-right CDATA #IMPLIED> +<!ATTLIST style:properties fo:padding %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-top %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-bottom %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-left %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-right %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties style:shadow CDATA #IMPLIED> +<!ATTLIST style:properties fo:keep-with-next %boolean; #IMPLIED> + +<!ATTLIST style:properties text:number-lines %boolean; "false"> +<!ATTLIST style:properties text:line-number %nonNegativeInteger; #IMPLIED> + +<!ATTLIST style:properties style:decimal-places %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties style:tab-stop-distance %nonNegativeLength; #IMPLIED> + +<!-- table properties --> +<!ATTLIST style:properties style:width %positiveLength; #IMPLIED> +<!ATTLIST style:properties style:rel-width %percentage; #IMPLIED> +<!ATTLIST style:properties style:may-break-between-rows %boolean; #IMPLIED> +<!ATTLIST style:properties table:page-style-name %styleName; #IMPLIED> +<!ATTLIST style:properties table:display %boolean; #IMPLIED> + +<!-- table column properties --> +<!ATTLIST style:properties style:column-width %positiveLength; #IMPLIED> +<!ENTITY % relWidth "CDATA"> +<!ATTLIST style:properties style:rel-column-width %relWidth; #IMPLIED> +<!ATTLIST style:properties style:use-optimal-column-width %boolean; #IMPLIED> + +<!-- table row properties --> +<!ATTLIST style:properties style:row-height %positiveLength; #IMPLIED> +<!ATTLIST style:properties style:min-row-height %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties style:use-optimal-row-height %boolean; #IMPLIED> + +<!-- table cell properties --> +<!ATTLIST style:properties + table:align (left | center | right | margins) #IMPLIED + table:border-model (collapsing | separating) #IMPLIED + fo:vertical-align (top | middle | bottom | automatic) #IMPLIED + fo:direction (ltr | ttb) #IMPLIED + style:rotation-angle %nonNegativeInteger; #IMPLIED + style:rotation-align (none | bottom | top | center) #IMPLIED + style:cell-protect CDATA #IMPLIED + fo:wrap-option (no-wrap | wrap) #IMPLIED +> +<!ELEMENT style:columns (style:column-sep?,style:column*)> +<!ATTLIST style:columns fo:column-count %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:columns fo:column-gap %positiveLength; #IMPLIED> + +<!ELEMENT style:column EMPTY> +<!ATTLIST style:column style:rel-width CDATA #IMPLIED> +<!ATTLIST style:column fo:margin-left %positiveLength; #IMPLIED> +<!ATTLIST style:column fo:margin-right %positiveLength; #IMPLIED> + +<!ELEMENT style:column-sep EMPTY> +<!ATTLIST style:column-sep style:style (none|solid|dotted|dashed|dot-dashed) + "solid"> +<!ATTLIST style:column-sep style:width %length; #REQUIRED> +<!ATTLIST style:column-sep style:height %percentage; "100%"> +<!ATTLIST style:column-sep style:vertical-align (top|middle|bottom) "top"> +<!ATTLIST style:column-sep style:color %color; "#000000"> + +<!-- page master properties --> +<!ELEMENT style:page-master (style:properties?, style:header-style?, style:footer-style?)> +<!ATTLIST style:page-master style:name %styleName; #REQUIRED> +<!ATTLIST style:page-master style:page-usage (all|left|right|mirrored) "all"> + +<!ELEMENT style:header-style (style:properties?)> +<!ELEMENT style:footer-style (style:properties?)> + +<!ATTLIST style:properties fo:page-width %length; #IMPLIED> +<!ATTLIST style:properties fo:page-height %length; #IMPLIED> +<!ATTLIST style:properties style:paper-tray-number %positiveNumberOrDefault; #IMPLIED> +<!ATTLIST style:properties style:print-orientation (portrait|landscape) #IMPLIED> +<!ATTLIST style:properties style:print CDATA #IMPLIED> +<!ATTLIST style:properties style:print-page-order (ttb|ltr) #IMPLIED> +<!ATTLIST style:properties style:first-page-number %positiveInteger; #IMPLIED> +<!ATTLIST style:properties style:scale-to %percentage; #IMPLIED> +<!ATTLIST style:properties style:scale-to-pages %positiveInteger; #IMPLIED> +<!ATTLIST style:properties style:table-centering (horizontal | vertical | both | none) #IMPLIED> + +<!ATTLIST style:properties style:footnote-max-height %lengthOrNoLimit; #IMPLIED> +<!ATTLIST style:properties style:vertical-align (top|bottom|middle|basline|auto) #IMPLIED> + +<!ELEMENT style:footnote-sep EMPTY> +<!ATTLIST style:footnote-sep style:width %length; #IMPLIED> +<!ATTLIST style:footnote-sep style:rel-width %percentage; #IMPLIED> +<!ATTLIST style:footnote-sep style:color %color; #IMPLIED> +<!ATTLIST style:footnote-sep style:adjustment (left|center|right) "left"> +<!ATTLIST style:footnote-sep style:distance-before-sep %length; #IMPLIED> +<!ATTLIST style:footnote-sep style:distance-after-sep %length; #IMPLIED> + +<!-- master page --> +<!ELEMENT style:master-page ( (style:header, style:header-left?)?, (style:footer, style:footer-left?)?, + office:forms?,style:style*, (%shapes;)*, presentation:notes? )> +<!ATTLIST style:master-page style:name %styleName; #REQUIRED> +<!ATTLIST style:master-page style:page-master-name %styleName; #REQUIRED> +<!ATTLIST style:master-page style:next-style-name %styleName; #IMPLIED> +<!ATTLIST style:master-page draw:style-name %styleName; #IMPLIED> + +<!-- handout master --> +<!ELEMENT style:handout-master (%shapes;)*> +<!ATTLIST style:handout-master presentation:presentation-page-layout-name %styleName; #IMPLIED> + +<!ENTITY % hd-ft-content "( text:p | (style:region-left?, style:region-center?, style:region-right?) )"> +<!ELEMENT style:header %hd-ft-content;> +<!ELEMENT style:footer %hd-ft-content;> +<!ELEMENT style:header-left %hd-ft-content;> +<!ATTLIST style:header-left style:display %boolean; "true"> +<!ELEMENT style:footer-left %hd-ft-content;> +<!ATTLIST style:footer-left style:display %boolean; "true"> + +<!ENTITY % region-content "(text:p*)"> +<!ELEMENT style:region-left %region-content;> +<!ELEMENT style:region-center %region-content;> +<!ELEMENT style:region-right %region-content;> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/table.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/table.mod new file mode 100755 index 000000000000..f0371a6023ae --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/table.mod @@ -0,0 +1,497 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: table.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT table:calculation-settings (table:null-date?, table:iteration?)> +<!ATTLIST table:calculation-settings + table:case-sensitive %boolean; "true" + table:precision-as-shown %boolean; "false" + table:search-criteria-must-apply-to-whole-cell %boolean; "true" + table:automatic-find-labels %boolean; "true" + table:use-regular-expressions %boolean; "true" + table:null-year %positiveInteger; "1930" +> +<!ELEMENT table:null-date EMPTY> +<!ATTLIST table:null-date + table:value-type %valueType; #FIXED "date" + table:date-value %date; "1899-12-30" +> +<!ELEMENT table:iteration EMPTY> +<!ATTLIST table:iteration + table:status (enable | disable) "disable" + table:steps %positiveInteger; "100" + table:maximum-difference %float; "0.001" +> + +<!ELEMENT table:tracked-changes (table:cell-content-change | table:insertion | table:deletion | table:movement | table:rejection)*> +<!ATTLIST table:tracked-changes table:track-changes %boolean; "true" + table:protected %boolean; "false" + table:protection-key CDATA #IMPLIED +> + +<!ELEMENT table:dependences (table:dependence)+> +<!ELEMENT table:dependence EMPTY> +<!ATTLIST table:dependence + table:id CDATA #REQUIRED +> +<!ELEMENT table:deletions (table:cell-content-deletion | table:change-deletion)+> +<!ELEMENT table:cell-content-deletion (table:cell-address?, table:change-track-table-cell?)> +<!ATTLIST table:cell-content-deletion + table:id CDATA #IMPLIED +> +<!ELEMENT table:change-deletion EMPTY> +<!ATTLIST table:change-deletion + table:id CDATA #IMPLIED +> +<!ELEMENT table:insertion (office:change-info, table:dependences?, table:deletions?)> +<!ATTLIST table:insertion + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED + table:type (row | column | table) #REQUIRED + table:position %integer; #REQUIRED + table:count %positiveInteger; "1" + table:table %integer; #IMPLIED +> +<!ELEMENT table:deletion (office:change-info, table:dependences?, table:deletions?, table:cut-offs?)> +<!ATTLIST table:deletion + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED + table:type (row | column | table) #REQUIRED + table:position %integer; #REQUIRED + table:count %positiveInteger; "1" + table:table %integer; #IMPLIED + table:multi-deletion-spanned %integer; #IMPLIED +> +<!ELEMENT table:cut-offs (table:movement-cut-off+ | (table:insertion-cut-off, table:movement-cut-off*))> +<!ELEMENT table:insertion-cut-off EMPTY> +<!ATTLIST table:insertion-cut-off + table:id CDATA #REQUIRED + table:position %integer; #REQUIRED +> +<!ELEMENT table:movement-cut-off EMPTY> +<!ATTLIST table:movement-cut-off + table:id CDATA #REQUIRED + table:start-position %integer; #IMPLIED + table:end-position %integer; #IMPLIED + table:position %integer; #IMPLIED +> +<!ELEMENT table:movement (table:source-range-address, table:target-range-address, office:change-info, table:dependences?, table:deletions?)> +<!ATTLIST table:movement + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED +> +<!ELEMENT table:target-range-address EMPTY> +<!ATTLIST table:target-range-address + table:column %integer; #IMPLIED + table:row %integer; #IMPLIED + table:table %integer; #IMPLIED + table:start-column %integer; #IMPLIED + table:start-row %integer; #IMPLIED + table:start-table %integer; #IMPLIED + table:end-column %integer; #IMPLIED + table:end-row %integer; #IMPLIED + table:end-table %integer; #IMPLIED +> +<!ELEMENT table:source-range-address EMPTY> +<!ATTLIST table:source-range-address + table:column %integer; #IMPLIED + table:row %integer; #IMPLIED + table:table %integer; #IMPLIED + table:start-column %integer; #IMPLIED + table:start-row %integer; #IMPLIED + table:start-table %integer; #IMPLIED + table:end-column %integer; #IMPLIED + table:end-row %integer; #IMPLIED + table:end-table %integer; #IMPLIED +> +<!ELEMENT table:change-track-table-cell (text:p*)> +<!ATTLIST table:change-track-table-cell + table:cell-address %cell-address; #IMPLIED + table:matrix-covered (true | false) "false" + table:formula %string; #IMPLIED + table:number-matrix-rows-spanned %positiveInteger; #IMPLIED + table:number-matrix-columns-spanned %positiveInteger; #IMPLIED + table:value-type %valueType; "string" + table:value %float; #IMPLIED + table:date-value %date; #IMPLIED + table:time-value %timeInstance; #IMPLIED + table:string-value %string; #IMPLIED +> +<!ELEMENT table:cell-content-change (table:cell-address, office:change-info, table:dependences?, table:deletions?, table:previous)> +<!ATTLIST table:cell-content-change + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED +> +<!ELEMENT table:cell-address EMPTY> +<!ATTLIST table:cell-address + table:column %integer; #IMPLIED + table:row %integer; #IMPLIED + table:table %integer; #IMPLIED +> +<!ELEMENT table:previous (table:change-track-table-cell)> +<!ATTLIST table:previous + table:id CDATA #IMPLIED +> +<!ELEMENT table:rejection (office:change-info, table:dependences?, table:deletions?)> +<!ATTLIST table:rejection + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED +> + +<!ENTITY % table-columns "table:table-columns | ( table:table-column | table:table-column-group )+"> +<!ENTITY % table-header-columns "table:table-header-columns"> +<!ENTITY % table-rows "table:table-rows | ( table:table-row | table:table-row-group )+"> +<!ENTITY % table-header-rows "table:table-header-rows"> +<!ENTITY % table-column-groups "((%table-columns;),(%table-header-columns;,(%table-columns;)?)?) | (%table-header-columns;,(%table-columns;)?)"> +<!ENTITY % table-row-groups "((%table-rows;),(%table-header-rows;,(%table-rows;)?)?) | (%table-header-rows;,(%table-rows;)?)"> +<!ELEMENT table:table (table:table-source?, table:scenario?, office:forms?, table:shapes?, (%table-column-groups;), (%table-row-groups;))> +<!ATTLIST table:table + table:name %string; #IMPLIED + table:style-name %styleName; #IMPLIED + table:protected %boolean; "false" + table:protection-key CDATA #IMPLIED + table:print-ranges %cell-range-address-list; #IMPLIED +> +<!ELEMENT table:table-source EMPTY> +<!ATTLIST table:table-source + table:mode (copy-all | copy-results-only) "copy-all" + xlink:type (simple) #FIXED "simple" + xlink:actuate (onRequest) "onRequest" + xlink:href %uriReference; #REQUIRED + table:filter-name CDATA #IMPLIED + table:table-name CDATA #IMPLIED + table:filter-options CDATA #IMPLIED + table:refresh-delay %timeDuration; #IMPLIED +> +<!ELEMENT table:scenario EMPTY> +<!ATTLIST table:scenario + table:display-border %boolean; "true" + table:border-color %color; #IMPLIED + table:copy-back %boolean; "true" + table:copy-styles %boolean; "true" + table:copy-formulas %boolean; "true" + table:is-active %boolean; #REQUIRED + table:scenario-ranges %cell-range-address-list; #REQUIRED + table:comment CDATA #IMPLIED +> +<!ELEMENT table:shapes %shapes;> +<!ELEMENT table:table-column-group (table:table-header-columns | table:table-column | table:table-column-group)+> +<!ATTLIST table:table-column-group + table:display %boolean; "true" +> +<!ELEMENT table:table-header-columns (table:table-column | table:table-column-group)+> +<!ELEMENT table:table-columns (table:table-column | table:table-column-group)+> +<!ELEMENT table:table-column EMPTY> +<!ATTLIST table:table-column + table:number-columns-repeated %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:visibility (visible | collapse | filter) "visible" + table:default-cell-style-name %styleName; #IMPLIED +> +<!ELEMENT table:table-row-group (table:table-header-rows | table:table-row | table:table-row-group)+> +<!ATTLIST table:table-row-group + table:display %boolean; "true" +> +<!ELEMENT table:table-header-rows (table:table-row | table:table-row-group)+> +<!ELEMENT table:table-rows (table:table-row | table:table-row-group)+> +<!ENTITY % table-cells "(table:table-cell|table:covered-table-cell)+"> +<!ELEMENT table:table-row %table-cells;> +<!ATTLIST table:table-row + table:number-rows-repeated %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:visibility (visible | collapse | filter) "visible" + table:default-cell-style-name %styleName; #IMPLIED +> + +<!ENTITY % text-wo-table "(text:h|text:p|text:ordered-list|text:unordered-list|%shapes;)*"> +<!ENTITY % cell-content "(table:cell-range-source?,office:annotation?,table:detective?,(table:sub-table|%text-wo-table;))"> +<!ELEMENT table:table-cell %cell-content;> +<!ELEMENT table:covered-table-cell %cell-content;> +<!ATTLIST table:table-cell + table:number-columns-repeated %positiveInteger; "1" + table:number-rows-spanned %positiveInteger; "1" + table:number-columns-spanned %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:validation-name CDATA #IMPLIED + table:formula %string; #IMPLIED + table:number-matrix-rows-spanned %positiveInteger; #IMPLIED + table:number-matrix-columns-spanned %positiveInteger; #IMPLIED + table:value-type %valueType; "string" + table:value %float; #IMPLIED + table:date-value %date; #IMPLIED + table:time-value %timeInstance; #IMPLIED + table:boolean-value %boolean; #IMPLIED + table:string-value %string; #IMPLIED + table:currency %string; #IMPLIED +> +<!ATTLIST table:covered-table-cell + table:number-columns-repeated %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:validation-name CDATA #IMPLIED + table:formula %string; #IMPLIED + table:number-matrix-rows-spanned %positiveInteger; #IMPLIED + table:number-matrix-columns-spanned %positiveInteger; #IMPLIED + table:value-type %valueType; "string" + table:value %float; #IMPLIED + table:date-value %date; #IMPLIED + table:time-value %timeInstance; #IMPLIED + table:boolean-value %boolean; #IMPLIED + table:string-value %string; #IMPLIED + table:currency %string; #IMPLIED +> +<!-- cell protection in writer: cell attribute; calc uses format --> +<!ATTLIST table:table-cell table:protected %boolean; "false"> + +<!ELEMENT table:cell-range-source EMPTY> +<!ATTLIST table:cell-range-source + table:name %string; #REQUIRED + xlink:type (simple) #FIXED "simple" + xlink:actuate (onRequest) #FIXED "onRequest" + xlink:href %uriReference; #REQUIRED + table:filter-name %string; #REQUIRED + table:filter-options %string; #IMPLIED + table:last-column-spanned %positiveInteger; #REQUIRED + table:last-row-spanned %positiveInteger; #REQUIRED + table:refresh-delay %timeDuration; #IMPLIED +> + +<!ELEMENT table:detective (table:highlighted-range*, table:operation*)> +<!ELEMENT table:highlighted-range EMPTY> +<!ATTLIST table:highlighted-range + table:cell-range-address %cell-range-address; #IMPLIED + table:direction (from-another-table | to-another-table | from-same-table | to-same-table) #REQUIRED + table:contains-error %boolean; "false" +> +<!ELEMENT table:operation EMPTY> +<!ATTLIST table:operation + table:name (trace-dependents | remove-dependents | trace-precedents | remove-precedents | trace-errors) #REQUIRED + table:index %nonNegativeInteger; #REQUIRED +> + +<!ELEMENT table:content-validations (table:content-validation)+> +<!ELEMENT table:content-validation (table:help-message?, (table:error-message | (table:error-macro, office:events?))?)> +<!ATTLIST table:content-validation + table:name CDATA #REQUIRED + table:condition CDATA #IMPLIED + table:base-cell-address %cell-address; #IMPLIED + table:allow-empty-cell %boolean; #IMPLIED +> +<!ELEMENT table:help-message (text:p*)> +<!ATTLIST table:help-message + table:title CDATA #IMPLIED + table:display %boolean; #IMPLIED +> +<!ELEMENT table:error-message (text:p*)> +<!ATTLIST table:error-message + table:title CDATA #IMPLIED + table:message-type (stop | warning | information) #IMPLIED + table:display %boolean; #IMPLIED +> +<!ELEMENT table:error-macro EMPTY> +<!ATTLIST table:error-macro + table:name CDATA #IMPLIED + table:execute %boolean; #IMPLIED +> + +<!ELEMENT table:sub-table ((%table-column-groups;) , (%table-row-groups;))> + +<!ELEMENT table:label-ranges (table:label-range)*> +<!ELEMENT table:label-range EMPTY> +<!ATTLIST table:label-range + table:label-cell-range-address %cell-range-address; #REQUIRED + table:data-cell-range-address %cell-range-address; #REQUIRED + table:orientation (column | row) #REQUIRED +> + +<!ELEMENT table:named-expressions (table:named-range | table:named-expression)*> +<!ELEMENT table:named-range EMPTY> +<!ATTLIST table:named-range + table:name CDATA #REQUIRED + table:cell-range-address %cell-range-address; #REQUIRED + table:base-cell-address %cell-address; #IMPLIED + table:range-usable-as CDATA "none" +> +<!ELEMENT table:named-expression EMPTY> +<!ATTLIST table:named-expression + table:name CDATA #REQUIRED + table:expression CDATA #REQUIRED + table:base-cell-address %cell-address; #IMPLIED +> + +<!ELEMENT table:filter (table:filter-condition | table:filter-and | table:filter-or)> +<!ATTLIST table:filter + table:target-range-address %cell-range-address; #IMPLIED + table:condition-source-range-address %cell-range-address; #IMPLIED + table:condition-source (self | cell-range) "self" + table:display-duplicates %boolean; "true" +> +<!ELEMENT table:filter-and (table:filter-or | table:filter-condition)+> +<!ELEMENT table:filter-or (table:filter-and | table:filter-condition)+> +<!ELEMENT table:filter-condition EMPTY> +<!ATTLIST table:filter-condition + table:field-number %nonNegativeInteger; #REQUIRED + table:case-sensitive %boolean; "false" + table:data-type (text | number) "text" + table:value CDATA #REQUIRED + table:operator CDATA #REQUIRED +> + +<!ELEMENT table:database-ranges (table:database-range)*> +<!ELEMENT table:database-range ((table:database-source-sql | table:database-source-table | table:database-source-query)?, table:filter?, table:sort?, table:subtotal-rules?)> +<!ATTLIST table:database-range + table:name CDATA #IMPLIED + table:is-selection %boolean; "false" + table:on-update-keep-styles %boolean; "false" + table:on-update-keep-size %boolean; "true" + table:has-persistant-data %boolean; "true" + table:orientation (row | column) "row" + table:contains-header %boolean; "true" + table:display-filter-buttons %boolean; "false" + table:target-range-address %cell-range-address; #REQUIRED + table:refresh-delay %timeDuration; #IMPLIED +> +<!ELEMENT table:database-source-sql EMPTY> +<!ATTLIST table:database-source-sql + table:database-name CDATA #REQUIRED + table:sql-statement CDATA #REQUIRED + table:parse-sql-statements %boolean; "false" +> +<!ELEMENT table:database-source-table EMPTY> +<!ATTLIST table:database-source-table + table:database-name CDATA #REQUIRED + table:table-name CDATA #REQUIRED +> +<!ELEMENT table:database-source-query EMPTY> +<!ATTLIST table:database-source-query + table:database-name CDATA #REQUIRED + table:query-name CDATA #REQUIRED +> + +<!ELEMENT table:sort (table:sort-by)+> +<!ATTLIST table:sort + table:bind-styles-to-content %boolean; "true" + table:target-range-address %cell-range-address; #IMPLIED + table:case-sensitive %boolean; "false" + table:language CDATA #IMPLIED + table:country CDATA #IMPLIED + table:algorithm CDATA #IMPLIED +> +<!ELEMENT table:sort-by EMPTY> +<!ATTLIST table:sort-by + table:field-number %nonNegativeInteger; #REQUIRED + table:data-type (text | number | automatic | qname-but-not-ncname) "automatic" + table:order (ascending | descending) "ascending" +> + +<!ELEMENT table:subtotal-rules (table:sort-groups? | table:subtotal-rule*)?> +<!ATTLIST table:subtotal-rules + table:bind-styles-to-content %boolean; "true" + table:case-sensitive %boolean; "false" + table:page-breaks-on-group-change %boolean; "false" +> +<!ELEMENT table:sort-groups EMPTY> +<!ATTLIST table:sort-groups + table:data-type (text | number | automatic | qname-but-not-ncname) "automatic" + table:order (ascending | descending) "ascending" +> +<!ELEMENT table:subtotal-rule (table:subtotal-field)*> +<!ATTLIST table:subtotal-rule + table:group-by-field-number %nonNegativeInteger; #REQUIRED +> +<!ELEMENT table:subtotal-field EMPTY> +<!ATTLIST table:subtotal-field + table:field-number %nonNegativeInteger; #REQUIRED + table:function CDATA #REQUIRED +> + +<!ELEMENT table:data-pilot-tables (table:data-pilot-table)*> +<!ELEMENT table:data-pilot-table ((table:database-source-sql | table:database-source-table | table:database-source-query | table:source-service | table:source-cell-range)?, table:data-pilot-field+)> +<!ATTLIST table:data-pilot-table + table:name CDATA #REQUIRED + table:application-data CDATA #IMPLIED + table:grand-total (none | row | column | both) "both" + table:ignore-empty-rows %boolean; "false" + table:identify-categories %boolean; "false" + table:target-range-address %cell-range-address; #REQUIRED + table:buttons %cell-range-address-list; #REQUIRED +> +<!ELEMENT table:source-service EMPTY> +<!ATTLIST table:source-service + table:name CDATA #REQUIRED + table:source-name CDATA #REQUIRED + table:object-name CDATA #REQUIRED + table:username CDATA #IMPLIED + table:password CDATA #IMPLIED +> +<!ELEMENT table:source-cell-range (table:filter)?> +<!ATTLIST table:source-cell-range + table:cell-range-address %cell-range-address; #REQUIRED +> +<!ELEMENT table:data-pilot-field (table:data-pilot-level)?> +<!ATTLIST table:data-pilot-field + table:source-field-name CDATA #REQUIRED + table:is-data-layout-field %boolean; "false" + table:function CDATA #REQUIRED + table:orientation (row | column | data | page | hidden) #REQUIRED + table:used-hierarchy %positiveInteger; "1" +> +<!ELEMENT table:data-pilot-level (table:data-pilot-subtotals?, table:data-pilot-members?)> +<!ATTLIST table:data-pilot-level + table:display-empty %boolean; #IMPLIED +> +<!ELEMENT table:data-pilot-subtotals (table:data-pilot-subtotal)*> +<!ELEMENT table:data-pilot-subtotal EMPTY> +<!ATTLIST table:data-pilot-subtotal + table:function CDATA #REQUIRED +> +<!ELEMENT table:data-pilot-members (table:data-pilot-member)*> +<!ELEMENT table:data-pilot-member EMPTY> +<!ATTLIST table:data-pilot-member + table:name CDATA #REQUIRED + table:display %boolean; #IMPLIED + table:display-details %boolean; #IMPLIED +> + +<!ELEMENT table:consolidation EMPTY> +<!ATTLIST table:consolidation + table:function CDATA #REQUIRED + table:source-cell-range-addresses %cell-range-address-list; #REQUIRED + table:target-cell-address %cell-address; #REQUIRED + table:use-label (none | column | row | both) "none" + table:link-to-source-data %boolean; "false" +> + +<!ELEMENT table:dde-links (table:dde-link)+> +<!ELEMENT table:dde-link (office:dde-source, table:table)> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/text.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/text.mod new file mode 100755 index 000000000000..fd90aff575cd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/results/baseline/xml-base/text.mod @@ -0,0 +1,1103 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: text.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % fields "text:date | + text:time | + text:page-number | + text:page-continuation | + text:sender-firstname | + text:sender-lastname | + text:sender-initials | + text:sender-title | + text:sender-position | + text:sender-email | + text:sender-phone-private | + text:sender-fax | + text:sender-company | + text:sender-phone-work | + text:sender-street | + text:sender-city | + text:sender-postal-code | + text:sender-country | + text:sender-state-or-province | + text:author-name | + text:author-initials | + text:placeholder | + text:variable-set | + text:variable-get | + text:variable-input | + text:user-field-get | + text:user-field-input | + text:sequence | + text:expression | + text:text-input | + text:database-display | + text:database-next | + text:database-row-select | + text:database-row-number | + text:database-name | + text:initial-creator | + text:creation-date | + text:creation-time | + text:description | + text:user-defined | + text:print-time | + text:print-date | + text:printed-by | + text:title | + text:subject | + text:keywords | + text:editing-cycles | + text:editing-duration | + text:modification-time | + text:modification-date | + text:creator | + text:conditional-text | + text:hidden-text | + text:hidden-paragraph | + text:chapter | + text:file-name | + text:template-name | + text:set-page-variable | + text:get-page-variable | + text:execute-macro | + text:dde-connection | + text:reference-ref | + text:sequence-ref | + text:bookmark-ref | + text:footnote-ref | + text:endnote-ref | + text:sheet-name | + text:bibliography-mark | + text:page-count | + text:paragraph-count | + text:word-count | + text:character-count | + text:table-count | + text:image-count | + text:object-count | + office:annotation | + text:script | + text:measure" > + +<!ENTITY % inline-text "(#PCDATA| + text:span|text:tab-stop|text:s|text:line-break| + text:footnote|text:endnote|text:a| + text:bookmark|text:bookmark-start|text:bookmark-end| + text:reference-mark|text:reference-mark-start| + text:reference-mark-end|%fields;|%shape;| + text:toc-mark-start | text:toc-mark-end | + text:toc-mark | text:user-index-mark-start | + text:user-index-mark-end | text:user-index-mark | + text:alphabetical-index-mark-start | + text:alphabetical-index-mark-end | + text:alphabetical-index-mark | + %change-marks; | draw:a | text:ruby)*"> + +<!ELEMENT text:p %inline-text;> +<!ELEMENT text:h %inline-text;> + +<!ATTLIST text:p text:style-name %styleName; #IMPLIED> +<!ATTLIST text:p text:cond-style-name %styleName; #IMPLIED> + +<!ATTLIST text:h text:style-name %styleName; #IMPLIED> +<!ATTLIST text:h text:cond-style-name %styleName; #IMPLIED> +<!ATTLIST text:h text:level %positiveInteger; "1"> + +<!ELEMENT text:span %inline-text;> +<!ATTLIST text:span text:style-name %styleName; #REQUIRED> + +<!ELEMENT text:a %inline-text;> +<!ATTLIST text:a xlink:href %uriReference; #REQUIRED> +<!ATTLIST text:a xlink:type (simple) #FIXED "simple"> +<!ATTLIST text:a xlink:actuate (onRequest) "onRequest"> +<!ATTLIST text:a xlink:show (new|replace) "replace"> +<!ATTLIST text:a office:name %string; #IMPLIED> +<!ATTLIST text:a office:target-frame-name %string; #IMPLIED> +<!ATTLIST text:a text:style-name %styleName; #IMPLIED> +<!ATTLIST text:a text:visited-style-name %styleName; #IMPLIED> + + +<!ELEMENT text:s EMPTY> +<!ATTLIST text:s text:c %positiveInteger; "1"> + +<!ELEMENT text:tab-stop EMPTY> + +<!ELEMENT text:line-break EMPTY> + + +<!ENTITY % list-items "((text:list-header,text:list-item*)|text:list-item+)"> +<!ELEMENT text:ordered-list %list-items;> +<!ELEMENT text:unordered-list %list-items;> + + +<!ATTLIST text:ordered-list text:style-name %styleName; #IMPLIED> +<!ATTLIST text:unordered-list text:style-name %styleName; #IMPLIED> + +<!ATTLIST text:ordered-list text:continue-numbering %boolean; "false"> + +<!ELEMENT text:list-header (text:p)+> +<!ELEMENT text:list-item (text:p|text:ordered-list|text:unordered-list)+> + +<!ATTLIST text:list-item text:restart-numbering %boolean; "false"> +<!ATTLIST text:list-item text:start-value %positiveInteger; #IMPLIED> + +<!ELEMENT text:list-style (text:list-level-style-number| + text:list-level-style-bullet| + text:list-level-style-image)+> + +<!ATTLIST text:list-style style:name %styleName; #IMPLIED> + +<!ATTLIST text:list-style text:consecutive-numbering %boolean; "false"> + + +<!ELEMENT text:list-level-style-number (style:properties?)> + +<!ATTLIST text:list-level-style-number text:level %positiveInteger; + #REQUIRED> +<!ATTLIST text:list-level-style-number text:style-name %styleName; #IMPLIED> + +<!ATTLIST text:list-level-style-number style:num-format %string; #REQUIRED> +<!ATTLIST text:list-level-style-number style:num-prefix %string; #IMPLIED> +<!ATTLIST text:list-level-style-number style:num-suffix %string; #IMPLIED> +<!ATTLIST text:list-level-style-number style:num-letter-sync %boolean; + "false"> +<!ATTLIST text:list-level-style-number text:display-levels %positiveInteger; + "1"> +<!ATTLIST text:list-level-style-number text:start-value %positiveInteger; + "1"> +<!ELEMENT text:list-level-style-bullet (style:properties?)> + +<!ATTLIST text:list-level-style-bullet text:level %positiveInteger; #REQUIRED> +<!ATTLIST text:list-level-style-bullet text:style-name %styleName; #IMPLIED> +<!ATTLIST text:list-level-style-bullet text:bullet-char %character; #REQUIRED> +<!ATTLIST text:list-level-style-bullet style:num-prefix %string; #IMPLIED> +<!ATTLIST text:list-level-style-bullet style:num-suffix %string; #IMPLIED> + +<!ELEMENT text:list-level-style-image (style:properties?,office:binary-data?)> + +<!ATTLIST text:list-level-style-image text:level %positiveInteger; #REQUIRED> +<!ATTLIST text:list-level-style-image xlink:type (simple) #IMPLIED> +<!ATTLIST text:list-level-style-image xlink:href %uriReference; #IMPLIED> +<!ATTLIST text:list-level-style-image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST text:list-level-style-image xlink:show (embed) #IMPLIED> + + +<!-- list properties --> +<!ATTLIST style:properties text:space-before %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties text:min-label-width %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties text:min-label-distance %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties text:enable-numbering %boolean; #IMPLIED> +<!ATTLIST style:properties style:list-style-name %styleName; #IMPLIED> + +<!ELEMENT text:outline-style (text:outline-level-style)+> + +<!ELEMENT text:outline-level-style (style:properties?)> + +<!ATTLIST text:outline-level-style text:level %positiveInteger; + #REQUIRED> +<!ATTLIST text:outline-level-style text:style-name %styleName; #IMPLIED> + +<!ATTLIST text:outline-level-style style:num-format %string; #REQUIRED> +<!ATTLIST text:outline-level-style style:num-prefix %string; #IMPLIED> +<!ATTLIST text:outline-level-style style:num-suffix %string; #IMPLIED> +<!ATTLIST text:outline-level-style style:num-letter-sync %boolean; + "false"> +<!ATTLIST text:outline-level-style text:display-levels %positiveInteger; + "1"> +<!ATTLIST text:outline-level-style text:start-value %positiveInteger; + "1"> + +<!ENTITY % field-declarations "text:variable-decls?, + text:user-field-decls?, + text:sequence-decls?"> + +<!ENTITY % variableName "CDATA"> + +<!ENTITY % formula "CDATA"> + +<!ENTITY % valueAttr "text:value-type %valueType; #REQUIRED"> + +<!ENTITY % valueAndTypeAttr "%valueAttr; + text:value %float; #IMPLIED + text:date-value %date; #IMPLIED + text:time-value %timeInstance; #IMPLIED + text:boolean-value %boolean; #IMPLIED + text:string-value %string; #IMPLIED + text:currency CDATA #IMPLIED" > + +<!ENTITY % numFormat 'style:num-format CDATA #IMPLIED + style:num-letter-sync %boolean; "false"'> + + +<!ELEMENT text:date (#PCDATA)> +<!ATTLIST text:date text:date-value %date; #IMPLIED> +<!ATTLIST text:date text:date-adjust %dateDuration; #IMPLIED> +<!ATTLIST text:date text:fixed %boolean; "false"> +<!ATTLIST text:date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:time (#PCDATA)> +<!ATTLIST text:time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:time text:time-adjust %timeDuration; #IMPLIED> +<!ATTLIST text:time text:fixed %boolean; "false"> +<!ATTLIST text:time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:page-number (#PCDATA)> +<!ATTLIST text:page-number text:page-adjust %positiveInteger; #IMPLIED> +<!ATTLIST text:page-number text:select-page (previous|current|next) "current"> +<!ATTLIST text:page-number %numFormat;> + +<!ELEMENT text:page-continuation (#PCDATA)> +<!ATTLIST text:page-continuation text:select-page (previous|next) #REQUIRED> +<!ATTLIST text:page-continuation text:string-value %string; #IMPLIED> + +<!ELEMENT text:sender-firstname (#PCDATA)> +<!ATTLIST text:sender-firstname text:fixed %boolean; "true"> + +<!ELEMENT text:sender-lastname (#PCDATA)> +<!ATTLIST text:sender-lastname text:fixed %boolean; "true"> + +<!ELEMENT text:sender-initials (#PCDATA)> +<!ATTLIST text:sender-initials text:fixed %boolean; "true"> + +<!ELEMENT text:sender-title (#PCDATA)> +<!ATTLIST text:sender-title text:fixed %boolean; "true"> + +<!ELEMENT text:sender-position (#PCDATA)> +<!ATTLIST text:sender-position text:fixed %boolean; "true"> + +<!ELEMENT text:sender-email (#PCDATA)> +<!ATTLIST text:sender-email text:fixed %boolean; "true"> + +<!ELEMENT text:sender-phone-private (#PCDATA)> +<!ATTLIST text:sender-phone-private text:fixed %boolean; "true"> + +<!ELEMENT text:sender-fax (#PCDATA)> +<!ATTLIST text:sender-fax text:fixed %boolean; "true"> + +<!ELEMENT text:sender-company (#PCDATA)> +<!ATTLIST text:sender-company text:fixed %boolean; "true"> + +<!ELEMENT text:sender-phone-work (#PCDATA)> +<!ATTLIST text:sender-phone-work text:fixed %boolean; "true"> + +<!ELEMENT text:sender-street (#PCDATA)> +<!ATTLIST text:sender-street text:fixed %boolean; "true"> + +<!ELEMENT text:sender-city (#PCDATA)> +<!ATTLIST text:sender-city text:fixed %boolean; "true"> + +<!ELEMENT text:sender-postal-code (#PCDATA)> +<!ATTLIST text:sender-postal-code text:fixed %boolean; "true"> + +<!ELEMENT text:sender-country (#PCDATA)> +<!ATTLIST text:sender-country text:fixed %boolean; "true"> + +<!ELEMENT text:sender-state-or-province (#PCDATA)> +<!ATTLIST text:sender-state-or-province text:fixed %boolean; "true"> + +<!ELEMENT text:author-name (#PCDATA)> +<!ATTLIST text:author-name text:fixed %boolean; "true"> + +<!ELEMENT text:author-initials (#PCDATA)> +<!ATTLIST text:author-initials text:fixed %boolean; "true"> + +<!ELEMENT text:placeholder (#PCDATA)> +<!ATTLIST text:placeholder text:placeholder-type (text|table|text-box|image|object) #REQUIRED> +<!ATTLIST text:placeholder text:description %string; #IMPLIED> + +<!ELEMENT text:variable-decls (text:variable-decl)*> + +<!ELEMENT text:variable-decl EMPTY> +<!ATTLIST text:variable-decl text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-decl %valueAndTypeAttr;> + +<!ELEMENT text:variable-set (#PCDATA)> +<!ATTLIST text:variable-set text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-set text:formula %formula; #IMPLIED> +<!ATTLIST text:variable-set %valueAndTypeAttr;> +<!ATTLIST text:variable-set text:display (value|none) "value"> +<!ATTLIST text:variable-set style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:variable-get (#PCDATA)> +<!ATTLIST text:variable-get text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-get text:display (value|formula) "value"> +<!ATTLIST text:variable-get style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:variable-input (#PCDATA)> +<!ATTLIST text:variable-input text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-input text:description %string; #IMPLIED> +<!ATTLIST text:variable-input %valueAndTypeAttr;> +<!ATTLIST text:variable-input text:display (value|none) "value"> +<!ATTLIST text:variable-input style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:user-field-decls (text:user-field-decl)*> + +<!ELEMENT text:user-field-decl EMPTY> +<!ATTLIST text:user-field-decl text:name %variableName; #REQUIRED> +<!ATTLIST text:user-field-decl text:formula %formula; #IMPLIED> +<!ATTLIST text:user-field-decl %valueAndTypeAttr;> + +<!ELEMENT text:user-field-get (#PCDATA)> +<!ATTLIST text:user-field-get text:name %variableName; #REQUIRED> +<!ATTLIST text:user-field-get text:display (value|formula|none) "value"> +<!ATTLIST text:user-field-get style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:user-field-input (#PCDATA)> +<!ATTLIST text:user-field-input text:name %variableName; #REQUIRED> +<!ATTLIST text:user-field-input text:description %string; #IMPLIED> +<!ATTLIST text:user-field-input style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:sequence-decls (text:sequence-decl)*> + +<!ELEMENT text:sequence-decl EMPTY> +<!ATTLIST text:sequence-decl text:name %variableName; #REQUIRED> +<!ATTLIST text:sequence-decl text:display-outline-level %positiveInteger; "0"> +<!ATTLIST text:sequence-decl text:separation-character %character; "."> + +<!ELEMENT text:sequence (#PCDATA)> +<!ATTLIST text:sequence text:name %variableName; #REQUIRED> +<!ATTLIST text:sequence text:formula %formula; #IMPLIED> +<!ATTLIST text:sequence %numFormat;> +<!ATTLIST text:sequence text:ref-name ID #IMPLIED> + +<!ELEMENT text:expression (#PCDATA)> +<!ATTLIST text:expression text:formula %formula; #IMPLIED> +<!ATTLIST text:expression text:display (value|formula ) "value"> +<!ATTLIST text:expression %valueAndTypeAttr;> +<!ATTLIST text:expression style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:text-input (#PCDATA)> +<!ATTLIST text:text-input text:description %string; #IMPLIED> + +<!ENTITY % database-table "text:database-name CDATA #REQUIRED + text:table-name CDATA #REQUIRED"> + +<!ELEMENT text:database-display (#PCDATA)> +<!ATTLIST text:database-display %database-table;> +<!ATTLIST text:database-display text:column-name %string; #REQUIRED> +<!ATTLIST text:database-display style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:database-next (#PCDATA)> +<!ATTLIST text:database-next %database-table;> +<!ATTLIST text:database-next text:condition %formula; #IMPLIED> + +<!ELEMENT text:database-row-select (#PCDATA)> +<!ATTLIST text:database-row-select %database-table;> +<!ATTLIST text:database-row-select text:condition %formula; #IMPLIED> +<!ATTLIST text:database-row-select text:row-number %integer; #REQUIRED> + +<!ELEMENT text:database-row-number (#PCDATA)> +<!ATTLIST text:database-row-number %database-table;> +<!ATTLIST text:database-row-number %numFormat;> +<!ATTLIST text:database-row-number text:value %integer; #IMPLIED> + +<!ELEMENT text:database-name (#PCDATA)> +<!ATTLIST text:database-name %database-table;> + +<!ELEMENT text:initial-creator (#PCDATA)> +<!ATTLIST text:initial-creator text:fixed %boolean; "false"> + +<!ELEMENT text:creation-date (#PCDATA)> +<!ATTLIST text:creation-date text:fixed %boolean; "false"> +<!ATTLIST text:creation-date text:date-value %date; #IMPLIED> +<!ATTLIST text:creation-date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:creation-time (#PCDATA)> +<!ATTLIST text:creation-time text:fixed %boolean; "false"> +<!ATTLIST text:creation-time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:creation-time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:description (#PCDATA)> +<!ATTLIST text:description text:fixed %boolean; "false"> + +<!ELEMENT text:user-defined (#PCDATA)> +<!ATTLIST text:user-defined text:fixed %boolean; "false"> +<!ATTLIST text:user-defined text:name %string; #REQUIRED> + +<!ELEMENT text:print-time (#PCDATA)> +<!ATTLIST text:print-time text:fixed %boolean; "false"> +<!ATTLIST text:print-time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:print-time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:print-date (#PCDATA)> +<!ATTLIST text:print-date text:fixed %boolean; "false"> +<!ATTLIST text:print-date text:date-value %date; #IMPLIED> +<!ATTLIST text:print-date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:printed-by (#PCDATA)> +<!ATTLIST text:printed-by text:fixed %boolean; "false"> + +<!ELEMENT text:title (#PCDATA)> +<!ATTLIST text:title text:fixed %boolean; "false"> + +<!ELEMENT text:subject (#PCDATA)> +<!ATTLIST text:subject text:fixed %boolean; "false"> + +<!ELEMENT text:keywords (#PCDATA)> +<!ATTLIST text:keywords text:fixed %boolean; "false"> + +<!ELEMENT text:editing-cycles (#PCDATA)> +<!ATTLIST text:editing-cycles text:fixed %boolean; "false"> + +<!ELEMENT text:editing-duration (#PCDATA)> +<!ATTLIST text:editing-duration text:fixed %boolean; "false"> +<!ATTLIST text:editing-duration text:duration %timeDuration; #IMPLIED> +<!ATTLIST text:editing-duration style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:modification-time (#PCDATA)> +<!ATTLIST text:modification-time text:fixed %boolean; "false"> +<!ATTLIST text:modification-time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:modification-time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:modification-date (#PCDATA)> +<!ATTLIST text:modification-date text:fixed %boolean; "false"> +<!ATTLIST text:modification-date text:date-value %date; #IMPLIED> +<!ATTLIST text:modification-date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:creator (#PCDATA)> +<!ATTLIST text:creator text:fixed %boolean; "false"> + +<!ELEMENT text:conditional-text (#PCDATA)> +<!ATTLIST text:conditional-text text:condition %formula; #REQUIRED> +<!ATTLIST text:conditional-text text:string-value-if-false %string; #REQUIRED> +<!ATTLIST text:conditional-text text:string-value-if-true %string; #REQUIRED> +<!ATTLIST text:conditional-text text:current-value %boolean; "false"> + +<!ELEMENT text:hidden-text (#PCDATA)> +<!ATTLIST text:hidden-text text:condition %formula; #REQUIRED> +<!ATTLIST text:hidden-text text:string-value %string; #REQUIRED> +<!ATTLIST text:hidden-text text:is-hidden %boolean; "false"> + +<!ELEMENT text:hidden-paragraph EMPTY> +<!ATTLIST text:hidden-paragraph text:condition %formula; #REQUIRED> +<!ATTLIST text:hidden-paragraph text:is-hidden %boolean; "false"> + +<!ELEMENT text:chapter (#PCDATA)> +<!ATTLIST text:chapter text:display (name|number|number-and-name| + plain-number-and-name|plain-number) + "number-and-name"> +<!ATTLIST text:chapter text:outline-level %integer; "1"> + +<!ELEMENT text:file-name (#PCDATA)> +<!ATTLIST text:file-name text:display (full|path|name|name-and-extension) + "full"> +<!ATTLIST text:file-name text:fixed %boolean; "false"> + +<!ELEMENT text:template-name (#PCDATA)> +<!ATTLIST text:template-name text:display (full|path|name|name-and-extension| + area|title) "full"> + +<!ELEMENT text:set-page-variable EMPTY> +<!ATTLIST text:set-page-variable text:active %boolean; "true"> +<!ATTLIST text:set-page-variable text:page-adjust %integer; "0"> + +<!ELEMENT text:get-page-variable (#PCDATA)> +<!ATTLIST text:get-page-variable %numFormat;> + +<!ELEMENT text:execute-macro (#PCDATA|office:events)* > +<!ATTLIST text:execute-macro text:description %string; #IMPLIED> + + +<!ELEMENT text:dde-connection-decls (text:dde-connection-decl)*> + +<!ELEMENT text:dde-connection-decl EMPTY> +<!ATTLIST text:dde-connection-decl text:name %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:dde-application %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:dde-topic %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:dde-item %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:automatic-update %boolean; "false"> + +<!ELEMENT text:dde-connection (#PCDATA)> +<!ATTLIST text:dde-connection text:connection-name %string; #REQUIRED> + +<!ELEMENT text:reference-ref (#PCDATA)> +<!ATTLIST text:reference-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:reference-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:sequence-ref (#PCDATA)> +<!ATTLIST text:sequence-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:sequence-ref text:reference-format (page|chapter|text|direction|category-and-value|caption|value) #IMPLIED> + +<!ELEMENT text:bookmark-ref (#PCDATA)> +<!ATTLIST text:bookmark-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:bookmark-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:footnote-ref (#PCDATA)> +<!ATTLIST text:footnote-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:footnote-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:endnote-ref (#PCDATA)> +<!ATTLIST text:endnote-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:endnote-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:sheet-name (#PCDATA)> + +<!ELEMENT text:page-count (#PCDATA)> +<!ATTLIST text:page-count style:num-format %string; #IMPLIED> +<!ATTLIST text:page-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:paragraph-count (#PCDATA)> +<!ATTLIST text:paragraph-count style:num-format %string; #IMPLIED> +<!ATTLIST text:paragraph-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:word-count (#PCDATA)> +<!ATTLIST text:word-count style:num-format %string; #IMPLIED> +<!ATTLIST text:word-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:character-count (#PCDATA)> +<!ATTLIST text:character-count style:num-format %string; #IMPLIED> +<!ATTLIST text:character-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:table-count (#PCDATA)> +<!ATTLIST text:table-count style:num-format %string; #IMPLIED> +<!ATTLIST text:table-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:image-count (#PCDATA)> +<!ATTLIST text:image-count style:num-format %string; #IMPLIED> +<!ATTLIST text:image-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:object-count (#PCDATA)> +<!ATTLIST text:object-count style:num-format %string; #IMPLIED> +<!ATTLIST text:object-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:bibliography-mark (#PCDATA)> +<!ATTLIST text:bibliography-mark text:bibiliographic-type + ( article | book | booklet | conference | custom1 | custom2 | custom3 | + custom4 | custom5 | email | inbook | incollection | inproceedings | + journal | manual | mastersthesis | misc | phdthesis | proceedings | + techreport | unpublished | www ) #REQUIRED > +<!ATTLIST text:bibliography-mark text:identifier CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:address CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:annote CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:author CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:booktitle CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:chapter CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:edition CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:editor CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:howpublished CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:institution CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:journal CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:month CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:note CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:number CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:organizations CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:pages CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:publisher CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:school CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:series CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:title CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:report-type CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:volume CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:year CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:url CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom1 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom2 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom3 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom4 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom5 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:isbn CDATA #IMPLIED> + + +<!ELEMENT text:bookmark EMPTY> +<!ATTLIST text:bookmark text:name CDATA #REQUIRED> + +<!ELEMENT text:bookmark-start EMPTY> +<!ATTLIST text:bookmark-start text:name CDATA #REQUIRED> + +<!ELEMENT text:bookmark-end EMPTY> +<!ATTLIST text:bookmark-end text:name CDATA #REQUIRED> + +<!ELEMENT text:reference-mark EMPTY> +<!ATTLIST text:reference-mark text:name CDATA #REQUIRED> + +<!ELEMENT text:reference-mark-start EMPTY> +<!ATTLIST text:reference-mark-start text:name CDATA #REQUIRED> + +<!ELEMENT text:reference-mark-end EMPTY> +<!ATTLIST text:reference-mark-end text:name CDATA #REQUIRED> + +<!ELEMENT text:footnotes-configuration (text:footnote-continuation-notice-forward?,text:footnote-continuation-notice-backward?)> +<!ATTLIST text:footnotes-configuration style:num-prefix %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration style:num-suffix %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration style:num-format %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration style:num-letter-sync %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:citation-body-style-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:citation-style-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:default-style-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:master-page-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:start-value %integer; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:footnotes-position (document|page) "page"> +<!ATTLIST text:footnotes-configuration text:start-numbering-at (document|chapter|page) "document"> + +<!ELEMENT text:footnote-continuation-notice-forward (#PCDATA)> +<!ELEMENT text:footnote-continuation-notice-backward (#PCDATA)> + +<!ELEMENT text:endnotes-configuration EMPTY> +<!ATTLIST text:endnotes-configuration style:num-prefix %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration style:num-suffix %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration style:num-format %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration style:num-letter-sync %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:start-value %integer; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:citation-style-name %styleName; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:citation-body-style-name %styleName; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:default-style-name %styleName; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:master-page-name %styleName; #IMPLIED> + +<!-- Validity constraint: text:footnote and text:endnote elements may not + contain other text:footnote or text:endnote elements, even though the DTD + allows this (via the %text; in the foot-/endnote-body). + Unfortunatetly, this constraint cannot be easily specified in the DTD. +--> +<!ELEMENT text:footnote (text:footnote-citation, text:footnote-body)> +<!ATTLIST text:footnote text:id ID #IMPLIED> + +<!ELEMENT text:footnote-citation (#PCDATA)> +<!ATTLIST text:footnote-citation text:label %string; #IMPLIED> + +<!ELEMENT text:footnote-body (text:h|text:p| + text:ordered-list|text:unordered-list)*> + +<!ELEMENT text:endnote (text:endnote-citation, text:endnote-body)> +<!ATTLIST text:endnote text:id ID #IMPLIED> + +<!ELEMENT text:endnote-citation (#PCDATA)> +<!ATTLIST text:endnote-citation text:label %string; #IMPLIED> + +<!ELEMENT text:endnote-body (text:h|text:p| + text:ordered-list|text:unordered-list)*> + +<!ENTITY % sectionText "(text:h|text:p|text:ordered-list| + text:unordered-list|table:table|chart:chart|draw:page| + draw:a|draw:text-box|draw:image|text:section| + text:table-of-content|text:illustration-index| + text:table-index|text:object-index|text:user-index| + text:alphabetical-index|text:bibliography| + text:index-title|%change-marks;)*"> + +<!ELEMENT text:section ((text:section-source|office:dde-source)?, + %sectionText;) > + +<!ATTLIST text:section text:name CDATA #REQUIRED> +<!ATTLIST text:section text:style-name %styleName; #IMPLIED> +<!ATTLIST text:section text:display (true|none|condition) "true"> +<!ATTLIST text:section text:condition %formula; #IMPLIED> +<!ATTLIST text:section text:protected %boolean; "false"> +<!ATTLIST text:section text:protection-key CDATA #IMPLIED> + +<!ELEMENT text:section-source EMPTY> +<!ATTLIST text:section-source xlink:href %string; #IMPLIED> +<!ATTLIST text:section-source xlink:type (simple) #FIXED "simple"> +<!ATTLIST text:section-source xlink:show (embed) #FIXED "embed"> +<!ATTLIST text:section-source text:section-name %string; #IMPLIED> +<!ATTLIST text:section-source text:filter-name %string; #IMPLIED> + +<!ELEMENT text:table-of-content (text:table-of-content-source, + text:index-body) > +<!ATTLIST text:table-of-content text:style-name %styleName; #IMPLIED> +<!ATTLIST text:table-of-content text:protected %boolean; "false"> + +<!ELEMENT text:table-of-content-source (text:index-title-template? , + text:table-of-content-entry-template*, + text:index-source-styles* ) > +<!ATTLIST text:table-of-content-source text:outline-level %integer; #IMPLIED> +<!ATTLIST text:table-of-content-source text:use-index-marks %boolean; "true"> +<!ATTLIST text:table-of-content-source text:use-index-source-styles + %boolean; "false"> +<!ATTLIST text:table-of-content-source text:index-scope (document|chapter) + "document"> +<!ATTLIST text:table-of-content-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:table-of-content-source fo:language %string; #IMPLIED> +<!ATTLIST text:table-of-content-source fo:country %string; #IMPLIED> +<!ATTLIST text:table-of-content-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:table-of-content-entry-template (text:index-entry-chapter-number | + text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop | + text:index-entry-link-start | + text:index-entry-link-end)* > +<!ATTLIST text:table-of-content-entry-template text:outline-level + %integer; #REQUIRED> +<!ATTLIST text:table-of-content-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:illustration-index + (text:illustration-index-source, text:index-body)> +<!ATTLIST text:illustration-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:illustration-index text:protected %boolean; "false"> + +<!ELEMENT text:illustration-index-source (text:index-title-template?, + text:illustration-index-entry-template?) > +<!ATTLIST text:illustration-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:illustration-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:illustration-index-source text:use-caption %boolean; "true"> +<!ATTLIST text:illustration-index-source text:caption-sequence-name + %string; #IMPLIED> +<!ATTLIST text:illustration-index-source text:caption-sequence-format + (text|category-and-value|caption) "text"> +<!ATTLIST text:illustration-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:illustration-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:illustration-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:illustration-index-entry-template + ( text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:illustration-index-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:table-index (text:table-index-source, text:index-body)> +<!ATTLIST text:table-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:table-index text:protected %boolean; "false"> + +<!ELEMENT text:table-index-source (text:index-title-template?, + text:table-index-entry-template?) > +<!ATTLIST text:table-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:table-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:table-index-source text:use-caption %boolean; "true"> +<!ATTLIST text:table-index-source text:caption-sequence-name + %string; #IMPLIED> +<!ATTLIST text:table-index-source text:caption-sequence-format + (text|category-and-value|caption) "text"> +<!ATTLIST text:table-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:table-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:table-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:table-index-entry-template ( text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:table-index-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:object-index ( text:object-index-source, text:index-body ) > +<!ATTLIST text:object-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:object-index text:protected %boolean; "false"> + +<!ELEMENT text:object-index-source ( text:index-title-template?, + text:object-index-entry-template? ) > +<!ATTLIST text:object-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:object-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:object-index-source text:use-spreadsheet-objects + %boolean; "false"> +<!ATTLIST text:object-index-source text:use-draw-objects %boolean; "false"> +<!ATTLIST text:object-index-source text:use-chart-objects %boolean; "false"> +<!ATTLIST text:object-index-source text:use-other-objects %boolean; "false"> +<!ATTLIST text:object-index-source text:use-math-objects %boolean; "false"> +<!ATTLIST text:object-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:object-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:object-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:object-index-entry-template ( text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:object-index-entry-template text:style-name + %styleName; #REQUIRED > + +<!ELEMENT text:user-index (text:user-index-source, text:index-body) > +<!ATTLIST text:user-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:user-index text:protected %boolean; "false"> + +<!ELEMENT text:user-index-source ( text:index-title-template?, + text:user-index-entry-template*, + text:index-source-styles* ) > +<!ATTLIST text:user-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:user-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:user-index-source text:use-index-marks %boolean; "false"> +<!ATTLIST text:user-index-source text:use-graphics %boolean; "false"> +<!ATTLIST text:user-index-source text:use-tables %boolean; "false"> +<!ATTLIST text:user-index-source text:use-floating-frames %boolean; "false"> +<!ATTLIST text:user-index-source text:use-objects %boolean; "false"> +<!ATTLIST text:user-index-source text:use-index-source-styles + %boolean; "false"> +<!ATTLIST text:user-index-source text:copy-outline-level %boolean; "false"> +<!ATTLIST text:user-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:user-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:user-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:user-index-entry-template ( text:index-entry-chapter | + text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:user-index-entry-template text:outline-level %integer; #REQUIRED> +<!ATTLIST text:user-index-entry-template text:style-name %styleName; #REQUIRED> + +<!ELEMENT text:alphabetical-index (text:alphabetical-index-source, + text:index-body)> +<!ATTLIST text:alphabetical-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:alphabetical-index text:protected %boolean; "false"> + +<!ELEMENT text:alphabetical-index-source ( text:index-title-template?, + text:alphabetical-index-entry-template* ) > +<!ATTLIST text:alphabetical-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:alphabetical-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:alphabetical-index-source text:ignore-case %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:main-entry-style-name + %styleName; #IMPLIED> +<!ATTLIST text:alphabetical-index-source text:alphabetical-separators + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:combine-entries + %boolean; "true"> +<!ATTLIST text:alphabetical-index-source text:combine-entries-with-dash + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:combine-entries-with-pp + %boolean; "true"> +<!ATTLIST text:alphabetical-index-source text:use-keys-as-entries + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:capitalize-entries + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:comma-separated + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:alphabetical-index-entry-template ( text:index-entry-chapter | + text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:alphabetical-index-entry-template text:outline-level + (1|2|3|separator) #REQUIRED> +<!ATTLIST text:alphabetical-index-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:alphabetical-index-auto-mark-file EMPTY> +<!ATTLIST text:alphabetical-index-auto-mark-file xlink:href CDATA #IMPLIED> +<!ATTLIST text:alphabetical-index-auto-mark-file xlink:type (simple) #FIXED "simple"> + +<!ELEMENT text:bibliography (text:bibliography-source, text:index-body) > +<!ATTLIST text:bibliography text:style-name %styleName; #IMPLIED> +<!ATTLIST text:bibliography text:protected %boolean; "false"> + +<!ELEMENT text:bibliography-source ( text:index-title-template?, + text:bibliography-entry-template* ) > + +<!ELEMENT text:bibliography-entry-template ( text:index-entry-span | + text:index-entry-tab-stop | + text:index-entry-bibliography )* > +<!ATTLIST text:bibliography-entry-template text:bibliography-type + ( article | book | booklet | conference | custom1 | custom2 | + custom3 | custom4 | custom5 | email | inbook | incollection | + inproceedings | journal | manual | mastersthesis | misc | + phdthesis | proceedings | techreport | unpublished | www ) + #REQUIRED > +<!ATTLIST text:bibliography-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:index-body %sectionText; > + +<!-- +Validity constraint: text:index-title elements may appear only in +indices, and there may be only one text:index-title element. +--> +<!ELEMENT text:index-title %sectionText; > +<!ATTLIST text:index-title text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-title text:name %string; #IMPLIED> + +<!ELEMENT text:index-title-template (#PCDATA)> +<!ATTLIST text:index-title-template text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-chapter-number EMPTY> +<!ATTLIST text:index-entry-chapter-number text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-chapter EMPTY> +<!ATTLIST text:index-entry-chapter text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-entry-chapter text:display (name|number|number-and-name) + "number-and-name" > + +<!ELEMENT text:index-entry-text EMPTY> +<!ATTLIST text:index-entry-text text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-page-number EMPTY> +<!ATTLIST text:index-entry-page-number text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-span (#PCDATA)> +<!ATTLIST text:index-entry-span text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-bibliography EMPTY> +<!ATTLIST text:index-entry-bibliography text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-entry-bibliography text:bibliography-data-field + ( address | annote | author | bibiliographic_type | + booktitle | chapter | custom1 | custom2 | + custom3 | custom4 | custom5 | edition | editor | + howpublished | identifier | institution | isbn | + journal | month | note | number | organizations | + pages | publisher | report_type | school | + series | title | url | volume | year ) #REQUIRED> + + +<!ELEMENT text:index-entry-tab-stop EMPTY> +<!ATTLIST text:index-entry-tab-stop text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-entry-tab-stop style:leader-char %character; " "> +<!ATTLIST text:index-entry-tab-stop style:type (left|right) "left"> +<!ATTLIST text:index-entry-tab-stop style:position %length; #IMPLIED> + +<!ELEMENT text:index-entry-link-start EMPTY> +<!ATTLIST text:index-entry-link-start text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-link-end EMPTY> +<!ATTLIST text:index-entry-link-end text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-source-styles (text:index-source-style)*> +<!ATTLIST text:index-source-styles text:outline-level %integer; #REQUIRED> + +<!ELEMENT text:index-source-style EMPTY> +<!ATTLIST text:index-source-style text:style-name %styleName; #REQUIRED> + +<!ELEMENT text:toc-mark-start EMPTY> +<!ATTLIST text:toc-mark-start text:id %string; #REQUIRED> +<!ATTLIST text:toc-mark-start text:outline-level %integer; #IMPLIED> + +<!ELEMENT text:toc-mark-end EMPTY> +<!ATTLIST text:toc-mark-end text:id %string; #REQUIRED> + +<!ELEMENT text:toc-mark EMPTY> +<!ATTLIST text:toc-mark text:string-value %string; #REQUIRED> +<!ATTLIST text:toc-mark text:outline-level %integer; #IMPLIED> + +<!ELEMENT text:user-index-mark-start EMPTY> +<!ATTLIST text:user-index-mark-start text:id %string; #REQUIRED> +<!ATTLIST text:user-index-mark-start text:outline-level %integer; #IMPLIED> +<!ATTLIST text:user-index-mark-start text:index-name %string; #IMPLIED> + +<!ELEMENT text:user-index-mark-end EMPTY> +<!ATTLIST text:user-index-mark-end text:id %string; #REQUIRED> + +<!ELEMENT text:user-index-mark EMPTY> +<!ATTLIST text:user-index-mark text:string-value %string; #REQUIRED> +<!ATTLIST text:user-index-mark text:outline-level %integer; #IMPLIED> +<!ATTLIST text:user-index-mark text:index-name %string; #IMPLIED> + +<!ELEMENT text:alphabetical-index-mark-start EMPTY> +<!ATTLIST text:alphabetical-index-mark-start text:id %string; #REQUIRED> +<!ATTLIST text:alphabetical-index-mark-start text:key1 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark-start text:key2 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark-start text:main-etry %boolean; "false"> + +<!ELEMENT text:alphabetical-index-mark-end EMPTY> +<!ATTLIST text:alphabetical-index-mark-end text:id %string; #REQUIRED> + +<!ELEMENT text:alphabetical-index-mark EMPTY> +<!ATTLIST text:alphabetical-index-mark text:string-value %string; #REQUIRED> +<!ATTLIST text:alphabetical-index-mark text:key1 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark text:key2 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark text:main-etry %boolean; "false"> + +<!ELEMENT text:bibliography-configuration (text:sort-key)*> +<!ATTLIST text:bibliography-configuration text:prefix %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration text:suffix %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration text:sort-by-position %boolean; "true"> +<!ATTLIST text:bibliography-configuration text:numbered-entries %boolean; "false"> +<!ATTLIST text:bibliography-configuration fo:language %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration fo:country %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:sort-key EMPTY> +<!ATTLIST text:sort-key text:key ( address | annote | author | + bibiliographic_type | booktitle | chapter | custom1 | custom2 | + custom3 | custom4 | custom5 | edition | editor | howpublished | + identifier | institution | isbn | journal | month | note | number | + organizations | pages | publisher | report_type | school | series | + title | url | volume | year ) #REQUIRED> +<!ATTLIST text:sort-key text:sort-ascending %boolean; "true"> + +<!ELEMENT text:linenumbering-configuration (text:linenumbering-separator?)> +<!ATTLIST text:linenumbering-configuration text:style-name %styleName; #IMPLIED> +<!ATTLIST text:linenumbering-configuration text:number-lines %boolean; "true"> +<!ATTLIST text:linenumbering-configuration text:count-empty-lines %boolean; "true"> +<!ATTLIST text:linenumbering-configuration text:count-in-floating-frames %boolean; "false"> +<!ATTLIST text:linenumbering-configuration text:restart-numbering %boolean; "false"> +<!ATTLIST text:linenumbering-configuration text:offset %nonNegativeLength; #IMPLIED> +<!ATTLIST text:linenumbering-configuration style:num-format (1|a|A|i|I) "1"> +<!ATTLIST text:linenumbering-configuration style:num-letter-sync %boolean; "false"> +<!ATTLIST text:linenumbering-configuration text:number-position (left|rigth|inner|outer) "left"> +<!ATTLIST text:linenumbering-configuration text:increment %nonNegativeInteger; #IMPLIED> + +<!ELEMENT text:linenumbering-separator (#PCDATA)> +<!ATTLIST text:linenumbering-separator text:increment %nonNegativeInteger; #IMPLIED> + +<!ELEMENT text:script (#PCDATA)> +<!ATTLIST text:script script:language CDATA #REQUIRED> +<!ATTLIST text:script xlink:href CDATA #IMPLIED> +<!ATTLIST text:script xlink:type (simple) #FIXED "simple"> + +<!ELEMENT text:measure (#PCDATA)> +<!ATTLIST text:measure text:kind (value|unit|gap) #REQUIRED> + +<!ELEMENT text:ruby (text:ruby-base, text:ruby-text)> +<!ATTLIST text:ruby text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:ruby-base %inline-text;> + +<!ELEMENT text:ruby-text (#PCDATA)> +<!ATTLIST text:ruby-text text:style-name %styleName; #IMPLIED> + +<!-- elements for change tracking --> + +<!ELEMENT text:change EMPTY> +<!ATTLIST text:change text:change-id CDATA #REQUIRED> + +<!ELEMENT text:change-start EMPTY> +<!ATTLIST text:change-start text:change-id CDATA #REQUIRED> + +<!ELEMENT text:change-end EMPTY> +<!ATTLIST text:change-end text:change-id CDATA #REQUIRED> + +<!ELEMENT text:tracked-changes (text:changed-region)*> +<!ATTLIST text:tracked-changes text:track-changes %boolean; "true"> +<!ATTLIST text:tracked-changes text:protection-key CDATA #IMPLIED> + +<!ELEMENT text:changed-region (text:insertion | + (text:deletion, text:insertion?) | + text:format-change) > +<!ATTLIST text:changed-region text:id ID #REQUIRED> + +<!ELEMENT text:insertion (office:change-info, %sectionText;)> +<!ELEMENT text:deletion (office:change-info, %sectionText;)> +<!ELEMENT text:format-change (office:change-info)> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_animatedgif.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_animatedgif.infile new file mode 100644 index 000000000000..e1e8de3632d0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_animatedgif.infile @@ -0,0 +1,4 @@ +#testing animated gif conversion +# +TEST||QUICKWORD|a_animatedgif +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bolddoc.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bolddoc.infile new file mode 100644 index 000000000000..c545805e37e2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bolddoc.infile @@ -0,0 +1,4 @@ +#testing bold type conversion +# +TEST||QUICKWORD|a_bolddoc +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bookmarks.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bookmarks.infile new file mode 100644 index 000000000000..f350b6acdc18 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bookmarks.infile @@ -0,0 +1,4 @@ +#testing bookmark conversion +# +TEST||QUICKWORD|a_bookmarks +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bulletorderedlist.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bulletorderedlist.infile new file mode 100644 index 000000000000..bd9617d3892a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_bulletorderedlist.infile @@ -0,0 +1,4 @@ +#testing bullet ordered list conversion +# +TEST||QUICKWORD|a_bulletorderedlist +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_emptydoc-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_emptydoc-mod.infile new file mode 100644 index 000000000000..846bb80b44d3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_emptydoc-mod.infile @@ -0,0 +1,9 @@ +#testing modification to an empty document conversion +# +TEST||QUICKWORD|a_emptydoc-mod +ENTER_STRING_AT_LOCATION|108|20|New line of text added\n +ENTER_STRING_AT_LOCATION|108|40|This is 108, 40\n +ENTER_STRING_AT_LOCATION|150|208|This is 150, 208\n +ENTER_STRING_AT_LOCATION|150|308|This is 150, 308\n + +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_emptydoc.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_emptydoc.infile new file mode 100644 index 000000000000..ba5eef77ff2e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_emptydoc.infile @@ -0,0 +1,4 @@ +#testing empty document conversion +# +TEST||QUICKWORD|a_emptydoc +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_firstlineindent.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_firstlineindent.infile new file mode 100644 index 000000000000..31fb962eeb29 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_firstlineindent.infile @@ -0,0 +1,4 @@ +#testing indent conversion +# +TEST||QUICKWORD|a_firstlineindent +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_fontsize.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_fontsize.infile new file mode 100644 index 000000000000..f9a12659ac67 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_fontsize.infile @@ -0,0 +1,4 @@ +#testing fontsize conversion +# +TEST||QUICKWORD|a_fontsize +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading.infile new file mode 100644 index 000000000000..ca580f445cec --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading.infile @@ -0,0 +1,4 @@ +#testing basic heading conversion +# +TEST||QUICKWORD|a_heading +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading1.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading1.infile new file mode 100644 index 000000000000..4a73d5ead0e2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading1.infile @@ -0,0 +1,4 @@ +#testing heading1 type conversion +# +TEST||QUICKWORD|a_heading1 +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading2.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading2.infile new file mode 100644 index 000000000000..265e2fd1e629 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_heading2.infile @@ -0,0 +1,4 @@ +#testing heading2 type conversion +# +TEST||QUICKWORD|a_heading2 +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_hyperlink.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_hyperlink.infile new file mode 100644 index 000000000000..19fb1fd93f74 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_hyperlink.infile @@ -0,0 +1,4 @@ +#testing hyperlink conversion +# +TEST||QUICKWORD|a_hyperlink +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_justified.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_justified.infile new file mode 100644 index 000000000000..a9f1eee7016b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_justified.infile @@ -0,0 +1,4 @@ +#testing justified conversion +# +TEST||QUICKWORD|a_justified +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_linebreaks.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_linebreaks.infile new file mode 100644 index 000000000000..ebabb26a691a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_linebreaks.infile @@ -0,0 +1,4 @@ +#testing line break conversion +# +TEST||QUICKWORD|a_linebreaks +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_linespacing.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_linespacing.infile new file mode 100644 index 000000000000..ccb76ed0675f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_linespacing.infile @@ -0,0 +1,4 @@ +#testing line spacing conversion +# +TEST||QUICKWORD|a_linespacing +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_numberorderedlist.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_numberorderedlist.infile new file mode 100644 index 000000000000..4075e16b0516 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_numberorderedlist.infile @@ -0,0 +1,4 @@ +#testing number ordered list conversion +# +TEST||QUICKWORD|a_numberorderedlist +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_pagebreak.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_pagebreak.infile new file mode 100644 index 000000000000..10d2f2ceba0a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_pagebreak.infile @@ -0,0 +1,4 @@ +#testing page break conversion +# +TEST||QUICKWORD|a_pagebreak +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_paragraph.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_paragraph.infile new file mode 100644 index 000000000000..c74558b60c7e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_paragraph.infile @@ -0,0 +1,4 @@ +#testing paragraph conversion +# +TEST||QUICKWORD|a_paragraph +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple01.infile new file mode 100644 index 000000000000..f08c1fa14af1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple01.infile @@ -0,0 +1,4 @@ +# simple01 +TEST|Simple 1|QUICKWORD|a_simple01 +ENTER_STRING_AT_LOCATION|LEFT|TOP|New text added to simple file.\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple02.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple02.infile new file mode 100644 index 000000000000..f56a6b0fe2c3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple02.infile @@ -0,0 +1,4 @@ +# simple02 +TEST|Simple 2|QUICKWORD|a_simple02 +ENTER_STRING_AT_LOCATION|64|20|, including this inserted phrase, +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple03.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple03.infile new file mode 100644 index 000000000000..3a957ab5e2ea --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple03.infile @@ -0,0 +1,4 @@ +# simple03 +TEST|Simple 3|QUICKWORD|a_simple03 +ENTER_STRING_AT_LOCATION|LEFT|42|This is also in standard style\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple04.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple04.infile new file mode 100644 index 000000000000..1631885a6d77 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple04.infile @@ -0,0 +1,4 @@ +# simple04 +TEST|Simple 4|QUICKWORD|a_simple04 +ENTER_STRING_AT_LOCATION|66|20| +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple05.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple05.infile new file mode 100644 index 000000000000..242285797c3b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_simple05.infile @@ -0,0 +1,5 @@ +# simple05 +TEST|Simple 5|QUICKWORD|a_simple05 +ENTER_STRING_AT_LOCATION|108|20| +ENTER_STRING_AT_LOCATION|19|20|document uses +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_standard.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_standard.infile new file mode 100644 index 000000000000..c7a6ebf1fcfb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_standard.infile @@ -0,0 +1,4 @@ +#testing standard conversion +# +TEST||QUICKWORD|a_standard +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_subscript.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_subscript.infile new file mode 100644 index 000000000000..d4751de288c1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_subscript.infile @@ -0,0 +1,4 @@ +#testing subscript conversion +# +TEST||QUICKWORD|a_subscript +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_superscript.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_superscript.infile new file mode 100644 index 000000000000..1233754e9f37 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_superscript.infile @@ -0,0 +1,4 @@ +#testing superscript conversion +# +TEST||QUICKWORD|a_superscript +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_symbols.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_symbols.infile new file mode 100644 index 000000000000..5a89e15ca22f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_symbols.infile @@ -0,0 +1,4 @@ +#testing symbol conversion +# +TEST||QUICKWORD|a_symbols +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_tab.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_tab.infile new file mode 100644 index 000000000000..7b5d319fa2a1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_tab.infile @@ -0,0 +1,4 @@ +#testing tab conversion +# +TEST||QUICKWORD|a_tab +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_table.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_table.infile new file mode 100644 index 000000000000..b7d991e7033d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_table.infile @@ -0,0 +1,5 @@ +#testing table contents conversion +# +TEST||QUICKWORD|a_table +#ENTER_STRING_AT_LOCATION|LEFT|42|This is also in standard style\n +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_textspan.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_textspan.infile new file mode 100644 index 000000000000..493032299b1e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_textspan.infile @@ -0,0 +1,4 @@ +#testing textspan conversion +# +TEST||QUICKWORD|a_textspan +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_unorderedlist.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_unorderedlist.infile new file mode 100644 index 000000000000..6990e3ed58e6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_unorderedlist.infile @@ -0,0 +1,4 @@ +#testing unorderedlist conversion +# +TEST||QUICKWORD|a_unorderedlist +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_wordwrap.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_wordwrap.infile new file mode 100644 index 000000000000..22e5573f29d6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/a_wordwrap.infile @@ -0,0 +1,4 @@ +#testing wordwrapping conversion +# +TEST||QUICKWORD|a_wordwrap +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_addition01-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_addition01-mod.infile new file mode 100755 index 000000000000..17c2293ed6be --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_addition01-mod.infile @@ -0,0 +1,5 @@ +# +# +TEST||MINICALC|c_addition +MINICALC_ENTER_CELL|0|0| 3\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_alignment.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_alignment.infile new file mode 100755 index 000000000000..ae607f2a9ca6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_alignment.infile @@ -0,0 +1,4 @@ +# +# +TEST||MINICALC|c_alignment +SLEEP|10 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_backwardrange-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_backwardrange-mod.infile new file mode 100755 index 000000000000..5e869f491f5a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_backwardrange-mod.infile @@ -0,0 +1,6 @@ +# +# Test for backwardrange of spreadsheet - change a value in a set range +# +TEST||MINICALC|c_backwardrange +MINICALC_ENTER_CELL|1|1|=AVERAGE(2;5;5)\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_basic-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_basic-mod.infile new file mode 100755 index 000000000000..a2f1d3c342f8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_basic-mod.infile @@ -0,0 +1,5 @@ +# +# basic spreadsheet round trip conversion no modification +# +TEST||MINICALC|c_basic + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_bob-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_bob-mod.infile new file mode 100755 index 000000000000..f868004d1d5e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_bob-mod.infile @@ -0,0 +1,5 @@ +# +# +TEST||MINICALC|c_bob +MINICALC_ENTER_CELL|0|0| 3\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_boolean-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_boolean-mod.infile new file mode 100755 index 000000000000..2d69bb8cedf0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_boolean-mod.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet - test Boolean entry change. +# +TEST||MINICALC|c_boolean +MINICALC_ENTER_CELL|1|0|TRUE\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellcurrencyvalue.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellcurrencyvalue.infile new file mode 100644 index 000000000000..f58003dedd23 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellcurrencyvalue.infile @@ -0,0 +1,5 @@ +# +# basic spreadsheet with currency format round trip conversion no modification +# +TEST||MINICALC|c_cellcurrencyalue + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellpercentvalue-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellpercentvalue-mod.infile new file mode 100755 index 000000000000..440c82d2fbc2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellpercentvalue-mod.infile @@ -0,0 +1,8 @@ +# +# Spreadsheet percentage value precision +# +TEST||MINICALC|c_cellpercentvalue +MINICALC_ENTER_CELL|0|0|120%\n +SLEEP|3 +MINICALC_ENTER_CELL|0|1|10%\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellstringvalue-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellstringvalue-mod.infile new file mode 100755 index 000000000000..5e67ea28c49f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cellstringvalue-mod.infile @@ -0,0 +1,10 @@ +# +# Spreadsheet string value changes. +# +TEST||MINICALC|c_cellstringvalue +MINICALC_ENTER_CELL|1|2|Testing\n +SLEEP|3 +MINICALC_ENTER_CELL|1|3|\n +SLEEP|3 +MINICALC_ENTER_CELL|2|1|;\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_columnswidth-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_columnswidth-mod.infile new file mode 100755 index 000000000000..5fe9942beabc --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_columnswidth-mod.infile @@ -0,0 +1,3 @@ +# +# +TEST||MINICALC|c_columnswidth diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cyclic-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cyclic-mod.infile new file mode 100755 index 000000000000..ab9ac1b29d4a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_cyclic-mod.infile @@ -0,0 +1,12 @@ +# +# Spreadsheet error messages. +# +TEST||MINICALC|c_cyclic +MINICALC_ENTER_CELL|3|0|0\n +SLEEP|3 +MINICALC_ENTER_CELL|4|0|0\n +SLEEP|3 +MINICALC_ENTER_CELL|3|1|=(A1/A4)\n +SLEEP|3 +MINICALC_ENTER_CELL|4|1|=(A4/A5)\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_dividefloating-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_dividefloating-mod.infile new file mode 100755 index 000000000000..ce216e167f5e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_dividefloating-mod.infile @@ -0,0 +1,8 @@ +# +# Spreadsheet - dividing floating points. +# +TEST||MINICALC|c_dividefloating +MINICALC_ENTER_CELL|3|0|=-(12.2)/(5-1)\n +SLEEP|3 +MINICALC_ENTER_CELL|1|1|=(12.2)/(5-1)\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_forwardrange-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_forwardrange-mod.infile new file mode 100755 index 000000000000..0c29937a0198 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_forwardrange-mod.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet forwardrange & logical function test +# +TEST||MINICALC|c_forwardrange +MINICALC_ENTER_CELL|3|1|=IF(0;45.45;54.54)\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_insertimage.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_insertimage.infile new file mode 100755 index 000000000000..6801a23fa455 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_insertimage.infile @@ -0,0 +1,4 @@ +# +# Spreadsheet with image insert conversion test. +# +TEST||MINICALC|c_insertimage diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_insertrow-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_insertrow-mod.infile new file mode 100755 index 000000000000..a56fcf0b2a13 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_insertrow-mod.infile @@ -0,0 +1,13 @@ +# +# simple spreadsheet - insert a new row +# +TEST||MINICALC|c_insertrow +TAP_PEN_HARD|10|40| +SLEEP|3 +TAP_PEN_HARD|110|140 +SLEEP|3 +TAP_PEN_HARD|110|130 +SLEEP|3 +MINICALC_ENTER_CELL|3|0|1\n +SLEEP|5 + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_invalidcellref-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_invalidcellref-mod.infile new file mode 100755 index 000000000000..dc2675c2d13a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_invalidcellref-mod.infile @@ -0,0 +1,10 @@ +# +# Spreadsheet invalid references test. +# +TEST||MINICALC|c_invalidcellref +MINICALC_ENTER_CELL|2|0|=MAX(1;2;3)\n +SLEEP|3 +MINICALC_ENTER_CELL|1|2| \n +SLEEP|3 +MINICALC_ENTER_CELL|2|2|=a0 \n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_largerange-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_largerange-mod.infile new file mode 100755 index 000000000000..7bc7b53e8423 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_largerange-mod.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet large range test +# +TEST||MINICALC|c_largerange +MINICALC_ENTER_CELL|2|1|=SUM(E7:G10)\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_listrange-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_listrange-mod.infile new file mode 100755 index 000000000000..252dbe45d34c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_listrange-mod.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet listrange test. +# +TEST||MINICALC|c_listrange +MINICALC_ENTER_CELL|2|3|24\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_mathematical-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_mathematical-mod.infile new file mode 100755 index 000000000000..f45b347b1760 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_mathematical-mod.infile @@ -0,0 +1,10 @@ +# +# Spreadsheet standard math functs +# +TEST||MINICALC|c_mathematical +MINICALC_ENTER_CELL|0|1|=SIN(3.14/2)\n +SLEEP8| +MINICALC_ENTER_CELL|1|1|=COS(0)\n +SLEEP|8 +MINICALC_ENTER_CELL|2|2|=TAN(1.57/2)\n +SLEEP|8 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_multi_boolean.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_multi_boolean.infile new file mode 100644 index 000000000000..ef77f2a143b2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_multi_boolean.infile @@ -0,0 +1,5 @@ +# +# Spreadsheet - test multi Boolean entry no change. +# +TEST||MINICALC|c_multi_boolean +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_protection-mod01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_protection-mod01.infile new file mode 100755 index 000000000000..d1557eab26da --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_protection-mod01.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet change protection test. +# +TEST||MINICALC|c_protection +MINICALC_ENTER_CELL|0|0| 1\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_sheetreference-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_sheetreference-mod.infile new file mode 100755 index 000000000000..3b9d76bb02bf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_sheetreference-mod.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet sheet reference test. +# +TEST||MINICALC|c_sheetreference +MINICALC_ENTER_CELL|2|0|=Sheet3.B1\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple01-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple01-mod.infile new file mode 100755 index 000000000000..2ae81831384c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple01-mod.infile @@ -0,0 +1,13 @@ +# +# simple spreadsheet - insert text & numbers +# +TEST||MINICALC|c_simple01 +MINICALC_ENTER_CELL|0|0|Col1\n +SLEEP|3 +MINICALC_ENTER_CELL|1|0|1\n +SLEEP|3 +MINICALC_ENTER_CELL|2|0|1\n +SLEEP|3 +MINICALC_ENTER_CELL|3|0|1\n +SLEEP|5 + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple02-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple02-mod.infile new file mode 100755 index 000000000000..a6414e9a5168 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple02-mod.infile @@ -0,0 +1,13 @@ +# +# simple spreadsheet - append a new column to end +# +TEST||MINICALC|c_simple02 +MINICALC_ENTER_CELL|0|1|Col3\n +SLEEP|3 +MINICALC_ENTER_CELL|1|1|3\n +SLEEP|3 +MINICALC_ENTER_CELL|2|1|3\n +SLEEP|3 +MINICALC_ENTER_CELL|3|1|3\n +SLEEP|5 + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple03-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple03-mod.infile new file mode 100755 index 000000000000..00ad02334b45 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple03-mod.infile @@ -0,0 +1,22 @@ +# +# simple spreadsheet - insert a new column in middle +# +TEST||MINICALC|c_simple03 +MINICALC_ENTER_CELL|0|1|Col2\n +SLEEP|3 +MINICALC_ENTER_CELL|1|1|2\n +SLEEP|3 +MINICALC_ENTER_CELL|2|1|2\n +SLEEP|3 +MINICALC_ENTER_CELL|3|1|2\n +SLEEP|5 +MINICALC_ENTER_CELL|0|2|Col3\n +SLEEP|3 +MINICALC_ENTER_CELL|1|2|3\n +SLEEP|3 +MINICALC_ENTER_CELL|2|2|3\n +SLEEP|3 +MINICALC_ENTER_CELL|3|2|3\n +SLEEP|5 + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple04-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple04-mod.infile new file mode 100755 index 000000000000..4c5b8828038c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_simple04-mod.infile @@ -0,0 +1,14 @@ +# +# simple spreadsheet - delete text & numbers +# +TEST||MINICALC|c_simple04 +MINICALC_ENTER_CELL|0|2|\n +SLEEP|3 +MINICALC_ENTER_CELL|1|2|\n +SLEEP|3 +MINICALC_ENTER_CELL|2|2|\n +SLEEP|3 +MINICALC_ENTER_CELL|3|2|\n +SLEEP|5 + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_smallrange-mod.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_smallrange-mod.infile new file mode 100755 index 000000000000..81c8ab33bdf8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_smallrange-mod.infile @@ -0,0 +1,6 @@ +# +# Spreadsheet smallrange test. +# +TEST||MINICALC|c_smallrange +MINICALC_ENTER_CELL|2|1|=AVERAGE(A1:B2)\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_styles.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_styles.infile new file mode 100755 index 000000000000..26c3446dffd5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_styles.infile @@ -0,0 +1,3 @@ +# +# +TEST||MINICALC|c_styles diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_textimage.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_textimage.infile new file mode 100755 index 000000000000..71416244e9d4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/c_textimage.infile @@ -0,0 +1,12 @@ +# +# Spreadsheet image text insert. +# +TEST||MINICALC|c_textimage +MINICALC_ENTER_CELL|0|0|This is a green car.\n +SLEEP|3 +MINICALC_ENTER_CELL|14|1|This line is below the green car.\n +SLEEP|3 +MINICALC_ENTER_CELL|15|2|This is a bird.\n +SLEEP|3 +MINICALC_ENTER_CELL|32|2|This line is below the bird.\n +SLEEP|5 diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/empty01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/empty01.infile new file mode 100755 index 000000000000..4100bb47178e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/empty01.infile @@ -0,0 +1,3 @@ +# empty01 +TEST|Empty 1|QUICKWORD|empty01 +ENTER_STRING_AT_LOCATION|LEFT|TOP|New text added to empty file.\n diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/hyperlink01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/hyperlink01.infile new file mode 100755 index 000000000000..75f4acb1123b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/hyperlink01.infile @@ -0,0 +1,4 @@ +# hyperlink01 +TEST|Hyperlink 1|QUICKWORD|hyperlink01 +ENTER_STRING_AT_LOCATION|114|64| +ENTER_STRING_AT_LOCATION|33|64|SunWeb Central diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/image01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/image01.infile new file mode 100755 index 000000000000..88da6efab59d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/image01.infile @@ -0,0 +1,4 @@ +# image01 +TEST|Image 1|QUICKWORD|image01 +ENTER_STRING_AT_LOCATION|86|53|\nReal start of animated gif +ENTER_STRING_AT_LOCATION|LEFT|97|Real end of animated gif\n diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple01.infile new file mode 100755 index 000000000000..9b8d2c3f26eb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple01.infile @@ -0,0 +1,3 @@ +# simple01 +TEST|Simple 1|QUICKWORD|simple01 +ENTER_STRING_AT_LOCATION|LEFT|TOP|New text added to simple file.\n diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple02.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple02.infile new file mode 100755 index 000000000000..ec139bdacafe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple02.infile @@ -0,0 +1,3 @@ +# simple02 +TEST|Simple 2|QUICKWORD|simple02 +ENTER_STRING_AT_LOCATION|64|20|, including this inserted phrase, diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple03.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple03.infile new file mode 100755 index 000000000000..0755a23b55db --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple03.infile @@ -0,0 +1,3 @@ +# simple03 +TEST|Simple 3|QUICKWORD|simple03 +ENTER_STRING_AT_LOCATION|LEFT|42|This is also in standard style\n diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple04.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple04.infile new file mode 100755 index 000000000000..7c6419dd91a4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple04.infile @@ -0,0 +1,3 @@ +# simple04 +TEST|Simple 4|QUICKWORD|simple04 +ENTER_STRING_AT_LOCATION|66|20| diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple05.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple05.infile new file mode 100755 index 000000000000..5296d4d953d9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/simple05.infile @@ -0,0 +1,4 @@ +# simple05 +TEST|Simple 5|QUICKWORD|simple05 +ENTER_STRING_AT_LOCATION|108|20| +ENTER_STRING_AT_LOCATION|19|20|document uses diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table01.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table01.infile new file mode 100755 index 000000000000..fe197e63ad82 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table01.infile @@ -0,0 +1,3 @@ +# table01 +TEST|Table 1|QUICKWORD|table01 +ENTER_STRING_AT_LOCATION|77|31|, immediately after this sentence diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table02.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table02.infile new file mode 100755 index 000000000000..c5570610e083 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table02.infile @@ -0,0 +1,3 @@ +# table02 +TEST|Table 2|QUICKWORD|table02 +ENTER_STRING_AT_LOCATION|LEFT|64|This sentence comes after the table. diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table03.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table03.infile new file mode 100755 index 000000000000..22a22cbaa492 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table03.infile @@ -0,0 +1,4 @@ +# table03 +TEST|Table 3|QUICKWORD|table03 +ENTER_STRING_AT_LOCATION|77|31|, immediately after this sentence +ENTER_STRING_AT_LOCATION|LEFT|75|This sentence comes after the table. diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table04.infile b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table04.infile new file mode 100755 index 000000000000..beeb6baf6e06 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/table04.infile @@ -0,0 +1,4 @@ +# table04 +TEST|Table 4|QUICKWORD|table04 +ENTER_STRING_AT_LOCATION|77|31| +ENTER_STRING_AT_LOCATION|62|20|a une table avec 3 lignes et 3 colonnes diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_animatedgif.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_animatedgif.sxw Binary files differnew file mode 100644 index 000000000000..690e5611a4b6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_animatedgif.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bolddoc.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bolddoc.sxw Binary files differnew file mode 100644 index 000000000000..314a4adc0eb9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bolddoc.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bookmarks.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bookmarks.sxw Binary files differnew file mode 100644 index 000000000000..c0f7c7ba632c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bookmarks.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bulletorderedlist.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bulletorderedlist.sxw Binary files differnew file mode 100644 index 000000000000..bd640d575fb2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_bulletorderedlist.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_emptydoc-mod.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_emptydoc-mod.sxw Binary files differnew file mode 100644 index 000000000000..d4d4eff4df96 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_emptydoc-mod.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_emptydoc.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_emptydoc.sxw Binary files differnew file mode 100644 index 000000000000..d4d4eff4df96 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_emptydoc.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_firstlineindent.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_firstlineindent.sxw Binary files differnew file mode 100644 index 000000000000..0729f3d25cdf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_firstlineindent.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_fontsize.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_fontsize.sxw Binary files differnew file mode 100644 index 000000000000..0b5717728617 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_fontsize.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading.sxw Binary files differnew file mode 100644 index 000000000000..915dce52c846 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading1.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading1.sxw Binary files differnew file mode 100644 index 000000000000..ebf0b2a44a3d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading1.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading2.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading2.sxw Binary files differnew file mode 100644 index 000000000000..42645eb2a0e6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_heading2.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_hyperlink.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_hyperlink.sxw Binary files differnew file mode 100644 index 000000000000..68632c7799cb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_hyperlink.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_justified.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_justified.sxw Binary files differnew file mode 100644 index 000000000000..37fa79a5db3b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_justified.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_linebreaks.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_linebreaks.sxw Binary files differnew file mode 100644 index 000000000000..519d12ef6acd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_linebreaks.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_linespacing.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_linespacing.sxw Binary files differnew file mode 100644 index 000000000000..f640bf826395 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_linespacing.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_numberorderedlist.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_numberorderedlist.sxw Binary files differnew file mode 100644 index 000000000000..9ea9bcdb2195 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_numberorderedlist.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_pagebreak.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_pagebreak.sxw Binary files differnew file mode 100644 index 000000000000..389520790d52 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_pagebreak.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_paragraph.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_paragraph.sxw Binary files differnew file mode 100644 index 000000000000..b19b4439b2e0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_paragraph.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple01.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple02.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple02.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple02.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple03.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple03.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple03.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple04.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple04.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple04.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple05.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple05.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_simple05.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_standard.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_standard.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_standard.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_subscript.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_subscript.sxw Binary files differnew file mode 100644 index 000000000000..486a8fb92d8d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_subscript.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_superscript.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_superscript.sxw Binary files differnew file mode 100644 index 000000000000..cc65c10281df --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_superscript.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_symbols.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_symbols.sxw Binary files differnew file mode 100644 index 000000000000..7d8961b142bd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_symbols.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_tab.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_tab.sxw Binary files differnew file mode 100644 index 000000000000..878707db6816 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_tab.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_table.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_table.sxw Binary files differnew file mode 100644 index 000000000000..34634a4ec542 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_table.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_textspan.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_textspan.sxw Binary files differnew file mode 100644 index 000000000000..c42751fa6ee4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_textspan.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_unorderedlist.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_unorderedlist.sxw Binary files differnew file mode 100644 index 000000000000..ca5ee406ccc5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_unorderedlist.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_wordwrap.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_wordwrap.sxw Binary files differnew file mode 100644 index 000000000000..168ebc72dfd1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/a_wordwrap.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_addition.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_addition.sxc Binary files differnew file mode 100644 index 000000000000..9bd5c1a7ee73 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_addition.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_alignment.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_alignment.sxc Binary files differnew file mode 100644 index 000000000000..b1fdbd58b7a8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_alignment.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_backwardrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_backwardrange.sxc Binary files differnew file mode 100644 index 000000000000..f319ed9feb8d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_backwardrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_basic.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_basic.sxc Binary files differnew file mode 100644 index 000000000000..9bd5c1a7ee73 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_basic.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_boolean.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_boolean.sxc Binary files differnew file mode 100644 index 000000000000..b6e876605be5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_boolean.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellcurrencyalue.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellcurrencyalue.sxc Binary files differnew file mode 100644 index 000000000000..808d781162e6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellcurrencyalue.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellpercentvalue.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellpercentvalue.sxc Binary files differnew file mode 100644 index 000000000000..e0499ce95c17 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellpercentvalue.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellstringvalue.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellstringvalue.sxc Binary files differnew file mode 100644 index 000000000000..f6fb4dc5de1a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cellstringvalue.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_columnswidth.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_columnswidth.sxc Binary files differnew file mode 100644 index 000000000000..24aa28e71fbd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_columnswidth.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cyclic.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cyclic.sxc Binary files differnew file mode 100644 index 000000000000..196bd78962a9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_cyclic.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_dividefloating.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_dividefloating.sxc Binary files differnew file mode 100644 index 000000000000..1e2c55b448c8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_dividefloating.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_forwardrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_forwardrange.sxc Binary files differnew file mode 100644 index 000000000000..f37c97d7e2a8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_forwardrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_insertimage.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_insertimage.sxc Binary files differnew file mode 100644 index 000000000000..9f42285d2881 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_insertimage.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_insertrow.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_insertrow.sxc Binary files differnew file mode 100644 index 000000000000..e20c0fff4414 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_insertrow.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_invalidcellref.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_invalidcellref.sxc Binary files differnew file mode 100644 index 000000000000..28fa241d7112 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_invalidcellref.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_largerange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_largerange.sxc Binary files differnew file mode 100644 index 000000000000..618e9ee73478 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_largerange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_listrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_listrange.sxc Binary files differnew file mode 100644 index 000000000000..b29b34d589ad --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_listrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_mathematical.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_mathematical.sxc Binary files differnew file mode 100644 index 000000000000..deab6092dc97 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_mathematical.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_multi_boolean.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_multi_boolean.sxc Binary files differnew file mode 100644 index 000000000000..38bc90cf0e52 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_multi_boolean.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_protection.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_protection.sxc Binary files differnew file mode 100644 index 000000000000..64f89cc61ce7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_protection.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_sheetreference.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_sheetreference.sxc Binary files differnew file mode 100644 index 000000000000..0ebb013db25d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_sheetreference.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple01.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple01.sxc Binary files differnew file mode 100755 index 000000000000..b4417b983444 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple01.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple02.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple02.sxc Binary files differnew file mode 100755 index 000000000000..7a4d69640f0a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple02.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple03.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple03.sxc Binary files differnew file mode 100755 index 000000000000..bb29f91d6b29 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple03.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple04.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple04.sxc Binary files differnew file mode 100755 index 000000000000..318129c421c4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_simple04.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_smallrange.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_smallrange.sxc Binary files differnew file mode 100644 index 000000000000..ea7dacc2464d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_smallrange.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_styles.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_styles.sxc Binary files differnew file mode 100644 index 000000000000..21e0f1ab5ac0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_styles.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_textimage.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_textimage.sxc Binary files differnew file mode 100644 index 000000000000..9f42285d2881 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/c_textimage.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/empty01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/empty01.sxw Binary files differnew file mode 100644 index 000000000000..d4d4eff4df96 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/empty01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/hyperlink01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/hyperlink01.sxw Binary files differnew file mode 100644 index 000000000000..d000f2974b23 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/hyperlink01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/image01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/image01.sxw Binary files differnew file mode 100644 index 000000000000..690e5611a4b6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/image01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple01.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple02.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple02.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple02.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple03.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple03.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple03.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple04.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple04.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple04.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple05.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple05.sxw Binary files differnew file mode 100644 index 000000000000..be65343e2ffe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/simple05.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table01.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table01.sxw Binary files differnew file mode 100644 index 000000000000..956bedcc24e2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table01.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table02.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table02.sxw Binary files differnew file mode 100644 index 000000000000..956bedcc24e2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table02.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table03.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table03.sxw Binary files differnew file mode 100644 index 000000000000..956bedcc24e2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table03.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table04.sxw b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table04.sxw Binary files differnew file mode 100644 index 000000000000..956bedcc24e2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa-wrapper/testcases/xml-orig/table04.sxw diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/mysplit.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/mysplit.pl new file mode 100755 index 000000000000..9eea6c551798 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/mysplit.pl @@ -0,0 +1,60 @@ +#!/usr/local/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: mysplit.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +open(TESTFILE, $ARGV[0]); + +while (<TESTFILE>) +{ + if ($_[1] eq "-q") + { + chomp $_; + @args = split('\|', $_); + @filestuff = split('\.', @args[0]); + $filename = @filestuff[0] . ".infile"; + open (TESTCASE, ">$filename") || die "Error opening $filename"; + print TESTCASE "# @args[1]\n# @args[2]\n"; + print TESTCASE "TEST|@args[1]|QUICKWORD|@filestuff[0]\n" ; + close TESTCASE; + } + if ($_[1] eq "-m") + { + chomp $_; + @args = split('\|', $_); + @filestuff = split('\.', @args[0]); + $filename = @filestuff[0] . ".infile"; + open (TESTCASE, ">$filename") || die "Error opening $filename"; + print TESTCASE "# @args[1]\n# @args[2]\n"; + print TESTCASE "TEST|@args[1]|MINICALC|@filestuff[0]\n" ; + close TESTCASE; + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/tappen.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/tappen.pl new file mode 100755 index 000000000000..d2187757ef59 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/tappen.pl @@ -0,0 +1,63 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: tappen.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#################################################################### +# File Name: template.pl +# Version : 1.0 +# Project : XMerge +# Author : Brian Cameron +# Date : 5th Sept. 2001 +# +# Takes x and y from the command line and taps the screen there. +# Assumes pose is already running. +# +########################################################################## + +if ($#ARGV != 1) +{ + print "\nUsage: $0 x y\n\n"; + exit -1; +} + +use lib "$ENV{qa-dir}/lib"; +use converterlib; + +# Put commands to run between the open_connection() and +# close_connection() calls... +# +open_connection(); + +TapPen($ARGV[0], $ARGV[1]); + +close_connection(); + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/template.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/template.pl new file mode 100755 index 000000000000..a9af244a84b2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/template.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: template.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#################################################################### +# File Name: template.pl +# Version : 1.0 +# Project : XMERGE +# Author : Brian Cameron +# Date : 5th Sept. 2001 +# +# This is just a useful script to use as a template to run +# commands. Assumes that pose is already running. +# +########################################################################## + +use lib "$ENV{qa-dir}/lib"; +use converterlib; + +# Put commands to run between the open_connection() and +# close_connection() calls... +# +open_connection(); + +# command(s) go here. + +close_connection(); + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/test_driver.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/test_driver.pl new file mode 100755 index 000000000000..a4dc46fb5e8f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/bin/test_driver.pl @@ -0,0 +1,787 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: test_driver.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#################################################################### +# File Name: test_driver.pl +# Version : 1.0 +# Project : Xmerge +# Author : Brian Cameron +# Date : 5th Sept. 2001 +# +# This script does the following: +# +# Processes the input file, and runs the tests specified in that +# file. This will do the following for each test: +# +# 1. Convert a file from XML to PDB format +# 2. Starts up the Palm OS emulator with the appropriate program +# running and the converted file loaded the program. +# 3. Makes automated changes as specified in the inputfile to +# this script.. +# 4. Returns to the main applications window. +# +# Parameter +# Filename to convert and change +# +########################################################################## + +# Turn on auto-flushing +# +$|=1; + +use EmRPC; + +# Directory where converterlib is located... +# +use lib "$ENV{qa-dir}/lib"; +use converterlib; + +#-------------------- Start of main script ------------------------------------ + +# Environmental Settings + +$pose_exe = "$ENV{pose-dir}/pose/posedist/pose"; +$pose_prc = "$ENV{thirdpartyapps-dir}"; +$test_list = ""; +$infile = ""; +$merge_opt = 0; + +# You may need to change this from the default if your pose emulator +# starts faster or slower than mine. +# +if ($ENV{'POSE_TIMEOUT'}) +{ + $pose_timeout = "$ENV{'POSE_TIMEOUT'}"; +} +else +{ + $pose_timeout = 15; +} + +$cmdline_len = @ARGV; +if ($cmdline_len <= 0) +{ + print_usage(); + exit (0); +} + +&process_cmdline(@ARGV); +&print_env(); +&verify_env_options(); + +# Make the output directories with timestamps included in the +# directory names. +# +mkdir $pdb_orig, 0777 || die "can not create directory <$pdb_new>."; +`chmod 777 $pdb_orig`; +mkdir $pdb_new, 0777 || die "can not create directory <$pdb_new>."; +`chmod 777 $pdb_new`; +mkdir $xml_new, 0777 || die "can not create directory <$pdb_new>."; +`chmod 777 $xml_new`; + +&verify_prcs_exist("DBExporter.prc"); + +if ($test_list ne "") +{ + open (TESTLIST, $test_list) || die "Couldn't open testcase list file $test_list"; + + while (<TESTLIST>) + { + &process_testcase($_); + } +} +elsif ($infile ne "") +{ + &process_testcase($infile); +} +else +{ + die ("You didn't supply any test cases to process"); +} + +print "Finished.\n"; +exit(0); + +#-------------------- End of main script ---------------------------------------- + +#-------------------------------------------------------------------------------- +# Various sub routines +#-------------------------------------------------------------------------------- + +# process_testcase +# infile - test case file name +# +# This is the main driver function +# Opens the infile, reads it in parses it, runs the appropriate conversion +# starts pose and load the file into the emulator. It launches the +# appropriate editor and then runs the commands specified in the test case. +# It then exports the file and saves it locally. Finally it is converted +# back to the original office format. +# +sub process_testcase +{ + my $infile = $_[0]; + my $convert_file = ""; + my $rc; + + # Process the inputfile + # + open (INFILE, $infile) || die "Failed to open test case <$infile>"; + + $running_testtype = ""; + + # Process the input file. + # + while ($c_inline = <INFILE>) + { + chomp $c_inline; + @entry = split('\|', $c_inline); + + # Process TEST + # + if ($c_inline =~ /^ *#/ || $c_inline =~ /^[ \t]*$/) + { + # skip comments and blank lines. + # + next; + } + elsif ("$entry[0]" eq "TEST") + { + # Close the test if one is running. + # + &close_program($convert_file); + $running_testtype = ""; + + $valid_test = 0; + + if ($#entry != 3) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + # Start the test. + # + print "\nStarting test: $entry[1]\n"; + $convert_file = $entry[3]; + + if ("$entry[2]" =~ /[Qq][Uu][Ii][Cc][Kk][Ww][Oo][Rr][Dd]/) + { + $xml_extension = "sxw"; + $convert_to = "doc"; + + # Convert XML file to pdb format. + # + $rc = &convert_to_pdb("$xml_orig", $convert_file, $xml_extension , + $convert_to,"$pdb_orig"); + if ($rc != 0) + { + print "\nERROR, problem converting file $convert_file\n\n"; + } + else + { + # Start pose + # + $rc = &start_pose("$pose_exe", + "$pose_prc/Quickword.PRC,$pose_prc/DBExporter.prc,$pdb_orig/$convert_file.pdb", + "Quickword", $pose_timeout); + + if ($rc == 0) + { + &start_quickword(); + $valid_test = 1; + $running_testtype = "QUICKWORD"; + print "\npose launched, begin automated test sequence for QuickWord\n"; + } + else + { + &kill_pose(); + $running_testtype = ""; + } + } + } + elsif ("$entry[2]" =~ /[Mm][Ii][Nn][Ii][Cc][Aa][Ll][Cc]/) + { + $xml_extension = "sxc"; + $convert_to = "minicalc"; + + # Convert XML file to pdb format. + # + $rc = &convert_to_pdb("$xml_orig", $convert_file, + $xml_extension, $convert_to,"$pdb_orig"); + if ($rc != 0) + { + print "\nERROR, problem converting file $convert_file\n\n"; + } + else + { + # Get minicalc PDB file names, since an SXC file can + # be converted to more than one. + # + $pdb_files=""; + $i = 1; + while (-f "$pdb_orig/$convert_file-Sheet$i.pdb") + { + if ($i > 1) + { + $pdb_files .= ","; + } + $pdb_files .= "$pdb_orig/$convert_file-Sheet$i.pdb"; + $i++; + } + $number = $i-1; + + # Start pose + # + $rc = &start_pose("$pose_exe", + "$pose_prc/MiniCalc.prc,$pose_prc/DBExporter.prc,$pdb_files", + "MiniCalc", $pose_timeout); + + if ($rc == 0) + { + &start_minicalc(); + $valid_test = 1; + $running_testtype = "MINICALC"; + print "pose launched, begin automated test sequence for MiniCalc\n"; + } + else + { + &kill_pose(); + $running_testtype = ""; + } + } + } + else + { + print "\nERROR, invalid extension <$entry[2]>\n\n"; + } + } + } + + # Process DB_EXPORT + # + elsif ("$entry[0]" eq "DB_EXPORT") + { + if ($#entry != 1) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + &db_export($entry[1]); + } + } + + # Process TAP_APPLICATIONS + # + elsif ("$entry[0]" eq "TAP_APPLICATIONS") + { + if ($#entry != 0) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + &tap_applications(0); + } + } + + # Process ENTER_STRING_AT_LOCATION + # + elsif ("$entry[0]" eq "ENTER_STRING_AT_LOCATION") + { + if ($#entry != 3) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &enter_string_at_location($entry[1], $entry[2], + $entry[3], $running_testtype); + } + } + + # Process TAP_PEN + # + elsif ("$entry[0]" eq "TAP_PEN") + { + if ($#entry != 2) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &pose_tap_pen($entry[1], $entry[2], 0); + } + } + + # Process TAP_BUTTON + # + elsif ("$entry[0]" eq "TAP_BUTTON") + { + if ($#entry != 1) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &pose_tap_button($entry[1], 0); + } + } + + # Process SLEEP + # + elsif ("$entry[0]" eq "SLEEP") + { + if ($#entry != 1) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + else + { + &pose_sleep($entry[1]); + } + } + + # Process MINICALC_ENTER_CELL + # + elsif ("$entry[0]" eq "MINICALC_ENTER_CELL") + { + if ($#entry != 3) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &minicalc_enter_cell($entry[1], $entry[2], $entry[3]); + } + } + + # Process QUICKWORD_FIND_REPLACE + # + elsif ("$entry[0]" eq "QUICKWORD_FIND_REPLACE") + { + if ($#entry != 2) + { + print "\nERROR, $entry[0] invalid number of arguments\n\n"; + } + elsif ($valid_test == 0) + { + print "\nERROR, can not process $entry[0] for invalid test\n\n"; + } + else + { + &quickword_find_replace($entry[1], $entry[2]); + } + } + else + { + print "\nERROR, invalid line <$c_inline>\n"; + } + } + + &close_program($convert_file); +} + +# close_program +# convert_file - file to export +# +# closes the program running in pose and kills pose +# +sub close_program +{ + my $convert_file = $_[0]; + + if ($running_testtype eq "QUICKWORD") + { + print "QuickWord test completed.\n"; + &close_program_quickword($convert_file); + } + elsif ($running_testtype eq "MINICALC") + { + print "MiniCalc test completed.\n"; + &close_program_minicalc($convert_file, $number); + } +} + +# close_program_quickword +# convert_file - file to export +# +# Closes quickword and kills pose +# +sub close_program_quickword +{ + my $convert_file = $_[0]; + my $error_file = "./error.txt"; + my $rc; + + &close_quickword(); + + &db_export($convert_file); + print "Moving /tmp/$convert_file.pdb to $pdb_new\n"; + `mv /tmp/$convert_file.pdb $pdb_new`; + `chmod 666 $pdb_new/$convert_file.pdb`; + + &close_connection(1); + &kill_pose(); + print "\nFinishing test...\n"; + + # The path of where to put the error file should be specified + # in the properties file. Not sure if it is really necessary + # to put this out to a separate file. STDOUT should be fine. + # + $rc = &convert_to_xml($xml_new, $xml_orig, + "$pdb_new/$convert_file.pdb", "doc" , + "sxw", $convert_file, $merge_opt); + if ($rc != 0) + { + print "\nERROR, problem converting file $pdb_new/$convert_file.pdb\n\n"; + } +} + +# close_program_minicalc +# convert_file - file to export +# +# Closes minicalc and kills pose +# +sub close_program_minicalc +{ + my $convert_file = $_[0]; + my $num_files = $_[1]; + my $list=""; + my $rc; + + &close_minicalc(); + + for ($a=1; $a <= $num_files; $a++) + { + &db_export("$convert_file-Sheet$a"); + print "Moving /tmp/$convert_file-Sheet$a.pdb to $pdb_new/\n"; + `mv /tmp/$convert_file-Sheet$a.pdb $pdb_new/`; + `chmod 666 $pdb_new/$convert_file-Sheet$a.pdb`; + } + + &close_connection(1); + &kill_pose(); + print "\nFinishing test...\n"; + + for ($a=1; $a <= $num_files; $a++) + { + $list .="$pdb_new/$convert_file-Sheet$a.pdb " + } + + $rc = &convert_to_xml($xml_new, $xml_orig, "$list", + "minicalc", "sxc", $convert_file, $merge_opt); + if ($rc != 0) + { + print "\nERROR, problem converting file(s) $list\n\n"; + } + + &pose_sleep(5); +} + +# print_usage +# +# prints the usage for this program. +# +sub print_usage +{ + print "Usage : test_driver.pl\n"; + print "\t-test=<file> \t\t: individual test case file to run\n"; + print "\t-list=<file> \t\t: list of test case files\n"; + print "\t-env=<file> \t\t: Properites like file defining env\n"; + print "\t-pose-exe=<fullpath> \t: path to pose executable\n"; + print "\t-pose-prc=<path> \t: path to directory holding prc files\n"; + print "\t-pdb-orig=<path> \t: directory to hold original pdb files\n"; + print "\t-pdb-new=<path> \t: directory to hold new pdb files\n"; + print "\t-xml-orig=<path> \t: directory to hold original office documents\n"; + print "\t-xml-new=<path> \t: directory to hold new office documents\n"; + print "\t-merge \t: Invokes the merge option when converting\n"; + print "\t \t from PDB back to XML.\n"; +} + +# print_env +# +# Prints the current environment. +# +sub print_env +{ + print "\nUsing the following environment:\n"; + print "\tPOSE_EXE = $pose_exe\n"; + print "\tPOSE_PRC = $pose_prc\n"; + print "\tPDB_ORIG = $pdb_orig\n"; + print "\tPDB_NEW = $pdb_new\n"; + print "\tXML_ORIG = $xml_orig\n"; + print "\tXML_NEW = $xml_new\n"; +} + +# process_cmdline +# +# command line options come in as key/value pairs. +# read them and set the appropriate global variable +# +# Sets these globals: pose_exe, pose_prc, xml_orig, xml_new_dir, +# xml_new, pdb_orig_dir, pdb_orig, pdb_new_dir, pdb_new. +# +sub process_cmdline +{ + my $lu_str = &get_date_string(); + + foreach $i (@_) + { + my @arg= split('=', $i); + @arg[0] =~ tr/A-Z/a-z/; + + if (@arg[0] eq "-pose-exe") + { + $pose_exe=$arg[1]; + } + elsif (@arg[0] eq "-pose-prc") + { + $pose_prc=$arg[1]; + } + elsif (@arg[0] eq "-pdb-orig") + { + $pdb_orig_dir=$arg[1]; + $pdb_orig=$arg[1]; + $pdb_orig .= "/"; + $pdb_orig .= "$lu_str"; + } + elsif (@arg[0] eq "-pdb-new") + { + $pdb_new_dir=$arg[1]; + $pdb_new=$arg[1]; + $pdb_new .= "/"; + $pdb_new .= "$lu_str"; + } + elsif (@arg[0] eq "-xml-orig") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "-xml-new") + { + $xml_new_dir=$arg[1]; + $xml_new=$arg[1]; + $xml_new .= "/"; + $xml_new .= "$lu_str"; + } + elsif (@arg[0] eq "-env") + { + &set_env_from_props($arg[1]); + } + elsif (@arg[0] eq "-list") + { + $test_list = $arg[1]; + } + elsif (@arg[0] eq "-test") + { + $infile = $arg[1]; + } + elsif (@arg[0] eq "-merge") + { + $merge_opt = 1; + } + else + { + print_usage(); + die "Incorrect command line"; + } + } +} + +# set_env_from_props +# infile - property file +# +# Read the properties file, of the form key=value +# Valid key values are : +# POSE_EXE +# POSE_PRC +# POSE_PERL +# TEST_HOME +# PDB_ORIG +# PDB_NEW +# XML_ORIG +# XML_NEW +# If a value is found the appropriate global variable is set. +# +# Sets these globals: pose_exe, pose_prc, xml_orig, xml_new_dir, +# xml_new, pdb_orig_dir, pdb_orig, pdb_new_dir, pdb_new. +# +sub set_env_from_props +{ + my $infile = $_[0]; + my $lu_str = &get_date_string(); + + open(PROPSFILE, $infile) || die "Could not open properties file <$infile>"; + + while (<PROPSFILE>) + { + chomp $_; + my @arg = split('=', $_); + @arg[0] =~ tr/a-z/A-Z/; + my $len = @arg; + if ($len != 2) + { + die "Malformed property in $arg[0]"; + } + if (@arg[0] eq "POSE_EXE") + { + $pose_exe=$arg[1]; + } + elsif (@arg[0] eq "POSE_PRC") + { + $pose_prc=$arg[1]; + } + elsif (@arg[0] eq "PDB_ORIG") + { + $pdb_orig_dir=$arg[1]; + $pdb_orig=$arg[1]; + $pdb_orig .= "/"; + $pdb_orig .= "$lu_str"; + } + elsif (@arg[0] eq "PDB_NEW") + { + $pdb_new_dir=$arg[1]; + $pdb_new=$arg[1]; + $pdb_new .= "/"; + $pdb_new .= "$lu_str"; + } + elsif (@arg[0] eq "XML_ORIG") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "XML_NEW") + { + $xml_new_dir=$arg[1]; + $xml_new=$arg[1]; + $xml_new .= "/"; + $xml_new .= "$lu_str"; + } + + } + close PROPSFILE; +} + +# verify_env_options +# +# Verify that input options are correctly set. +# Assumes pose_exe, pose_prc, xml_orig, xml_new_dir, +# pdb_orig_dir, and pdb_new_dir are already set. +# +sub verify_env_options +{ + if (!-e "$pose_exe") + { + die "The pose executable cannot be found at $pose_exe."; + } + if (!-x $pose_exe) + { + die "$pose_exe exists but is not executable."; + } + + if (!-e "$pose_prc") + { + die "The PRC directory specified as $pose_prc does not exist."; + } + if (!-d "$pose_prc") + { + die "The PRC location specified as $pose_prc exists, but is not a directory."; + } + + if (!-e "$pdb_orig_dir") + { + die "The original PDB directory specified as $pdb_orig_dir does not exist."; + } + if (!-d "$pdb_orig_dir") + { + die "The original PDB directory specified as $pdb_orig_dir exists but is not a directory."; + } + + if (!-e "$pdb_new_dir") + { + die "The new PDB directory specified as $pdb_new_dir does not exist."; + } + if (!-d "$pdb_new_dir") + { + die "The new PDB directory specified as $pdb_new_dir exists but is not a directory."; + } + + if (!-e "$xml_orig") + { + die "The original Office document directory specified as $xml_orig does not exist."; + } + if (!-d "$xml_orig") + { + die "The original Office document location specified as $xml_orig exists but is not a directory."; + } + + if (!-e "$xml_new_dir") + { + die "The new Office document directory specified as $xml_new_dir does not exist."; + } + if (!-d "$xml_new_dir") + { + die "The new Office document location specified as $xml_new_dir exists but is not a directory."; + } +} + +# verify_prcs_exist +# prcfile - the PRC file to check +# +# Verifies that the specified PRC file exists. +# +sub verify_prcs_exist +{ + my $prcfile = $_[0]; + + if (!-e "$pose_prc/$prcfile") + { + die "The pose PRC directory ($pose_prc) is correct, but I can't find $prcfile there."; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/OfficeZip.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/OfficeZip.java new file mode 100644 index 000000000000..301c62aa123f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/OfficeZip.java @@ -0,0 +1,244 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OfficeZip.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +import java.util.List; +import java.util.ListIterator; +import java.util.LinkedList; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.CRC32; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import org.openoffice.xmerge.util.Debug; + +/** + * Class used by OfficeDocument to handle zip reading and writing, + * as well as storing zip entries. + * + * @author Herbie Ong + */ + +class OfficeZip { + + /** file name of the xml file in a zipped document. */ + private final static String XMLFILE = "content.xml"; + + private final static int BUFFERSIZE = 1024; + + private List entryList = null; + + private int contentIndex = -1; + + private String filename = null; + + private class Entry { + + ZipEntry zipEntry = null; + byte bytes[] = null; + } + + /** + * Constructor + * + * @param filename Full Path to Zip file to process + * + */ + public OfficeZip(String filename) { + this.filename = filename; + } + + + /** + * Read each zip entry in the given InputStream object + * and store in entryList both the ZipEntry object as well + * as the bits of each entry. Return the bytes for the + * entry of XMLFILE. + * + * @param is InputStream object to read from + * @return byte[] byte array of XML file + * @throws IOException if any I/O error occurs + */ + + byte[] read(InputStream is) throws IOException { + + ZipInputStream zis = new ZipInputStream(is); + ZipEntry ze = null; + int i = -1; + + entryList = new LinkedList(); + + while ((ze = zis.getNextEntry()) != null) { + + String name = ze.getName(); + + Entry entry = new Entry(); + entry.zipEntry = ze; + + Debug.log(Debug.TRACE, "reading entry: " + name); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int len = 0; + byte bytes[] = new byte[BUFFERSIZE]; + + while ((len = zis.read(bytes)) > 0) { + baos.write(bytes, 0, len); + } + + entry.bytes = baos.toByteArray(); + + entryList.add(entry); + + i++; + + if (isContentXML(name)) { + contentIndex = i; + } + } + + if (contentIndex == -1) { + throw new IOException(XMLFILE + " not found."); + } + + Entry contentEntry = (Entry) entryList.get(contentIndex); + + return contentEntry.bytes; + } + + /** + * Write out the XMLFILE as a zip into the OutputStream object. + * + * If a zip inputstream was previously read, then use + * those zip contents to recreate the zip, except for XMLFILE, + * update it using the new content from xmlBytes. + * + * If there was no zip inputstream previously read, write + * XMLFILE out into the zip outputstream. + * + * @param os OutputStream object to write zip + * @param xmlBytes bytes of XMLFILE + * @throws IOException if any I/O errors occur. + */ + + void write(OutputStream os, byte xmlBytes[]) throws IOException { + + ZipOutputStream zos = new ZipOutputStream(os); + + // if read was not invoked previously, store the bytes directly. + if (contentIndex == -1) { + + Debug.log(Debug.TRACE, "Writing out " + XMLFILE + " into zip."); + + ZipEntry ze = new ZipEntry(XMLFILE); + ze.setSize(xmlBytes.length); + + CRC32 crc = new CRC32(); + crc.reset(); + crc.update(xmlBytes); + ze.setCrc(crc.getValue()); + + ze.setTime(System.currentTimeMillis()); + ze.setMethod(ZipEntry.DEFLATED); + + zos.putNextEntry(ze); + zos.write(xmlBytes); + + } else { + + saveEntries(zos, xmlBytes); + } + + zos.close(); + } + + /** + * Used by write method if there was a zip inputstream + * previously read. It would write out each ZipEntry of + * the previously read zip, except for XMLFILE, it would + * update it with new values and with the content from + * xmlBytes. + * + * @param os OutputStream object to write zip + * @param xmlBytes bytes of XMLFILE + * @throws ZipException if any zip I/O errors occur. + */ + + private void saveEntries(ZipOutputStream zos, byte xmlBytes[]) + throws IOException { + + Debug.log(Debug.TRACE, "Writing out the following entries into zip."); + + ListIterator iterator = entryList.listIterator(); + + while (iterator.hasNext()) { + + Entry entry = (Entry) iterator.next(); + ZipEntry ze = entry.zipEntry; + + String name = ze.getName(); + + Debug.log(Debug.TRACE, "... " + name); + + if (isContentXML(name)) { + + // set new values for this ZipEntry + + ZipEntry zipEntry = new ZipEntry(name); + + zipEntry.setMethod(ze.getMethod()); + zipEntry.setSize(xmlBytes.length); + + CRC32 crc = new CRC32(); + crc.reset(); + crc.update(xmlBytes); + zipEntry.setCrc(crc.getValue()); + + zipEntry.setTime(System.currentTimeMillis()); + + zos.putNextEntry(zipEntry); + zos.write(xmlBytes); + + } else { + + zos.putNextEntry(ze); + zos.write(entry.bytes); + } + } + } + + private boolean isContentXML(String name) { + + String lname = name.toLowerCase(); + return lname.equals(XMLFILE); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBDecoder.java new file mode 100644 index 000000000000..417d886cecea --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBDecoder.java @@ -0,0 +1,138 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PDBDecoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +import java.io.RandomAccessFile; +import java.io.IOException; + + +/** + * <p>Provides functionality to decode a pdb formatted file into + * a <code>PalmDB</code> object given a file input stream</p> + * + * <p>Sample usage:</p> + * + * <p><blockquote><pre> + * PDBDecoder decoder = new PDBDecoder("sample.pdb"); + * PalmDB palmDB = decoder.parse(); + * </pre></blockquote></p> + * + * <p>Refer to the + * <a href="http://starlite.eng/zensync/eng/converters/palmfileformats.pdf"> + * Palm file format specification</a> for details on the pdb format.</p> + * + * <p>This decoder has the following assumptions on the pdb file ...</p> + * <ol> + * <li><p>There is only one RecordList section in the pdb.</p></li> + * <li><p>The record indices in the RecordList are sorted in order, i.e. the + * first record index refers to record 0, and so forth.</p></li> + * <li><p>The raw records in the record section are sorted as well in order, + * i.e. first record comes ahead of second record, etc.</p></li> + * </ol> + * + * Other decoders assume these as well. + * + * @author Herbie Ong + * @see PalmDB + * @see PDBHeader + * + * @author Herbie Ong + */ + +public final class PDBDecoder { + + /** + * <p>This method decodes a pdb file into a PalmDB object.</p> + * + * <p>First, read in the header data using <code>PDBHeader</code>'s + * <code>read</code> method</p>. Next, read in the record list + * section. Store the record offsets for use when parsing the records. + * Based on these offsets, read in each record's bytes and store + * each in a <code>Record</code> object. Lastly, create a + * <code>PalmDB</code> object with the read in <code>Record</code>s. + * + * @param fileName pdb file name + * @throws IOException if I/O error occurs + */ + + public PalmDB parse(String fileName) throws IOException { + + RandomAccessFile file = new RandomAccessFile(fileName, "r"); + + // read the pdb header + PDBHeader header = new PDBHeader(); + header.read(file); + + Record recArray[] = new Record[header.numRecords]; + + if (header.numRecords != 0) { + + // read in the record indices + offsets + + int recOffset[] = new int[header.numRecords]; + + for (int i = 0; i < header.numRecords; i++) { + + recOffset[i] = file.readInt(); + int attr = file.readInt(); // read in attribute. + } + + // read the records + + int len = 0; + byte[] bytes = null; + + int lastIndex = header.numRecords - 1; + + for (int i = 0; i < lastIndex; i++) { + + file.seek(recOffset[i]); + len = recOffset[i+1] - recOffset[i]; + bytes = new byte[len]; + file.readFully(bytes); + recArray[i] = new Record(bytes); + } + + // last record + file.seek(recOffset[lastIndex]); + len = (int) file.length() - recOffset[lastIndex]; + bytes = new byte[len]; + file.readFully(bytes); + recArray[lastIndex] = new Record(bytes); + } + + file.close(); + + // create PalmDB and return it + PalmDB pdb = new PalmDB(header.pdbName, recArray); + return pdb; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBHeader.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBHeader.java new file mode 100644 index 000000000000..3029149db22d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBHeader.java @@ -0,0 +1,157 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PDBHeader.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** + * <p>Class used only internally by <code>PDBEncoder</code> and + * <code>PDBDecoder</code> to store, read and write a pdb header.</p> + * + * <p>Note that fields are intended to be accessible only at the + * package level.</p> + * + * <p>Some of the fields are internally represented using a + * larger type since Java does not have unsigned types. + * Some are not since they are not relevant for now. + * The <code>read</code> and <code>write</code> methods should + * handle them properly.</p> + * + * @author Herbie Ong + */ + +final class PDBHeader { + + /** name of the database. 32 bytes. */ + byte[] pdbName = null; + + /** flags for the database. Palm UInt16. Unsignedness should be irrelevant. */ + short attribute = 0; + + /** application-specific version for the database. Palm UInt16 */ + int version = 0; + + /** date created. Palm UInt32 */ + long creationDate = 0; + + /** date last modified. Palm UInt32 */ + long modificationDate = 0; + + /** date last backup. Palm UInt32 */ + long lastBackupDate = 0; + + /** + * incremented every time a record is + * added, deleted or modified. Palm UInt32. + */ + long modificationNumber = 0; + + /** optional field. Palm UInt32. Unsignedness should be irrelevant. */ + int appInfoID = 0; + + /** optional field. Palm UInt32. Unsignedness should be irrelevant. */ + int sortInfoID = 0; + + /** database type id. Palm UInt32. Unsignedness should be irrelevant. */ + int typeID = 0; + + /** database creator id. Palm UInt32. Unsignedness should be irrelevant. */ + int creatorID = 0; + + /** ??? */ + int uniqueIDSeed = 0; + + /** see numRecords. 4 bytes. */ + int nextRecordListID = 0; + + /** + * number of records stored in the database header. + * If all the record entries cannot fit in the header, + * then nextRecordList has the local ID of a + * recordList that contains the next set of records. + * Palm UInt16. + */ + int numRecords = 0; + + /** + * Read in the data for the pdb header. Need to + * preserve the unsigned value for some of the fields. + * + * @param di a DataInput object + * @throws IOException if I/O error occurs + */ + + public void read(DataInput in) throws IOException { + + pdbName = new byte[PalmDB.NAME_LENGTH]; + in.readFully(pdbName); + attribute = in.readShort(); + version = in.readUnsignedShort(); + creationDate = ((long) in.readInt()) & 0xffffffffL; + modificationDate = ((long) in.readInt()) & 0xffffffffL; + lastBackupDate = ((long) in.readInt()) & 0xffffffffL; + modificationNumber = ((long) in.readInt()) & 0xffffffffL; + appInfoID = in.readInt(); + sortInfoID = in.readInt(); + creatorID = in.readInt(); + typeID = in.readInt(); + uniqueIDSeed = in.readInt(); + nextRecordListID = in.readInt(); + numRecords = in.readUnsignedShort(); + } + + /** + * Write out pdb header data. + * + * @param out a DataOut object + * @throws IOException if I/O error occurs + */ + + public void write(DataOutput out) throws IOException { + + out.write(pdbName); + out.writeShort(attribute); + out.writeShort(version); + out.writeInt((int) creationDate); + out.writeInt((int) modificationDate); + out.writeInt((int) lastBackupDate); + out.writeInt((int) modificationNumber); + out.writeInt(appInfoID); + out.writeInt(sortInfoID); + out.writeInt(typeID); + out.writeInt(creatorID); + out.writeInt(uniqueIDSeed); + out.writeInt(nextRecordListID); + out.writeShort(numRecords); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBUtil.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBUtil.java new file mode 100644 index 000000000000..5f18b73e2884 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBUtil.java @@ -0,0 +1,104 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PDBUtil.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +/** + * Contains common static methods and contants for use within the package. + * + * @author Herbie Ong + */ + +public final class PDBUtil { + + /** difference in seconds from Jan 01, 1904 to Jan 01, 1970 */ + final static long TIME_DIFF = 2082844800; + + /** encoding scheme used */ + final static String ENCODING = "8859_1"; + + /** size of a pdb header in bytes */ + final static int HEADER_SIZE = 78; + + /** + * This method converts a 4 letter string into the Palm ID integer. + * + * It is normally used to convert the Palm creator ID string into + * the integer version of it. Also use for data types, etc. + * + * @param s 4 character string. + * @return int Palm ID representing the string. + * @throws ArrayIndexOutOfBoundsException if string parameter + * contains less than 4 characters. + */ + + public static int intID(String s) { + + int id = -1; + int temp = 0; + + // grab the first char and put it in the high bits + // note that we only want 8 lower bits of it. + temp = (int) s.charAt(0); + id = temp << 24; + + // grab the second char and add it in. + temp = ((int) s.charAt(1)) & 0x00ff; + id += temp << 16; + + // grab the second char and add it in. + temp = ((int) s.charAt(2)) & 0x00ff; + id += temp << 8; + + // grab the last char and add it in + id += ((int) s.charAt(3)) & 0x00ff; + + return id; + } + + /** + * This method converts an integer into a String given + * the Palm ID format. + * + * @param i Palm id. + * @return String string representation. + */ + + public static String stringID(int i) { + + char ch[] = new char[4]; + ch[0] = (char) (i >>> 24); + ch[1] = (char) ((i >> 16) & 0x00ff); + ch[2] = (char) ((i >> 8) & 0x00ff); + ch[3] = (char) (i & 0x00ff); + + return new String(ch); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PalmDB.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PalmDB.java new file mode 100644 index 000000000000..cc5eab0b2249 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PalmDB.java @@ -0,0 +1,353 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PalmDB.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.DataOutputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +/** + * <p>This class contains data for a single Palm database for use during + * a conversion process.</p> + * + * <p>It contains zero or more <code>Record</code> objects stored in an + * array. The index of the <code>Record</code> object in the array is + * the record id or number for that specific <code>Record</code> object. + * Note that this class does not check for maximum number of records + * allowable in an actual pdb.</p> + * + * <p>This class also contains the pdb name associated with the Palm database + * it represents. A pdb name consists of 32 bytes of a certain encoding + * (extended ASCII in this case).</p> + * + * <p>The non default constructors take in a name parameter which may not + * be the exact pdb name to be used. The name parameter in + * <code>String</code> or <code>byte[]</code> are converted to an exact + * <code>NAME_LENGTH</code> byte array. If the length of the name is less + * than <code>NAME_LENGTH</code>, it is padded with '\0' characters. If it + * is more, it gets truncated. The last character in the resulting byte + * array is always a '\0' character. The resulting byte array is stored in + * <code>bName</code>, and a corresponding String object <code>sName</code> + * that contains characters without the '\0' characters.</p> + * + * <p>The {@link #write write} method is called within the + * {@link zensync.util.palm.PalmDBSet#write PalmDBSet.write} method + * for writing out its data to the <code>OutputStream</code> object.</p> + * + * <p>The {@link #read read} method is called within the + * {@link zensync.util.palm.PalmDBSet#read PalmDBSet.read} method + * for reading in its data from the <code>InputStream</code> object.</p> + * + * @author Akhil Arora, Herbie Ong + * @see PalmDBSet + * @see Record + */ + +public final class PalmDB { + + /** number of bytes for the name field in the pdb */ + public final static int NAME_LENGTH = 32; + + /** list of Record objects */ + private Record[] records; + + /** pdb name in bytes */ + private byte[] bName = null; + + /** pdb name in String */ + private String sName = null; + + + /** + * Default constructor for use after a read(). + */ + + public PalmDB() { + + records = new Record[0]; + } + + /** + * Constructor to create object with Record objects. + * recs.length can be zero for an empty pdb. + * + * @param name suggested pdb name in String + * @param recs array of Record objects + * @throws NullPointerException if recs is null + */ + + public PalmDB(String name, Record[] recs) + throws UnsupportedEncodingException { + + this(name.getBytes(PDBUtil.ENCODING), recs); + } + + /** + * Constructor to create object with Record objects. + * recs.length can be zero for an empty pdb. + * + * @param name suggested pdb name in byte array + * @param recs array of Record objects + * @throws NullPointerException if recs is null + */ + + public PalmDB(byte[] name, Record[] recs) + throws UnsupportedEncodingException { + + store(name); + + records = new Record[recs.length]; + System.arraycopy(recs, 0, records, 0, recs.length); + } + + /** + * This private method is mainly used by the constructors above. + * to store bytes into name and also create a String representation. + * and also by the read method. + * + * TODO: Note that this method assumes that the byte array parameter + * contains one character per byte, else it would truncate + * improperly. + * + * @param bytes pdb name in byte array + * @throws UnsupportedEncodingException if ENCODING is not supported + */ + + private void store(byte[] bytes) throws UnsupportedEncodingException { + + // note that this will initialize all bytes in name to 0. + bName = new byte[NAME_LENGTH]; + + // determine minimum length to copy over from bytes to bName. + // Note that the last byte in bName has to be '\0'. + + int lastIndex = NAME_LENGTH - 1; + + int len = (bytes.length < lastIndex)? bytes.length: lastIndex; + + int i; + + for (i = 0; i < len; i++) { + + if (bytes[i] == 0) { + break; + } + + bName[i] = bytes[i]; + } + + // set sName, no need to include the '\0' character. + sName = new String(bName, 0, i, PDBUtil.ENCODING); + } + + /** + * Return the number of records contained in this + * pdb PalmDB object. + * + * @return int number of Record objects + */ + + public int getRecordCount() { + + return records.length; + } + + /** + * Return the specific Record object associated + * with the record number. + * + * @param index record index number + * @return Record the Record object in the specified index + * @throws ArrayIndexOutOfBoundsException if index is out of bounds + */ + + public Record getRecord(int index) { + + return records[index]; + } + + /** + * Return the list of Record objects + * + * @return Record[] the list of Record objects + */ + + public Record[] getRecords() { + + return records; + } + + /** + * Return the PDBName associated with this object in String + * + * @return String pdb name in String + */ + + public String getPDBNameString() { + + return sName; + } + + /** + * Return the PDBName associated with this object + * in byte array of exact length of 32 bytes. + * + * @return byte[] pdb name in byte[] of length 32. + */ + + public byte[] getPDBNameBytes() { + + return bName; + } + + /** + * Write out the number of records followed by what + * will be written out by each Record object. + * + * @param os the stream to write the object to + * @throws IOException if any I/O error occurs + */ + + public void write(OutputStream os) throws IOException { + + DataOutputStream out = new DataOutputStream(os); + + // write out pdb name + out.write(bName); + + // write out 2 bytes for number of records + out.writeShort(records.length); + + // let each Record object write out its own info. + for (int i = 0; i < records.length; i++) + records[i].write(out); + } + + /** + * Read the necessary data to create a pdb from + * the input stream. + * + * @param is the stream to read data from in order + * to restore the object + * @throws IOException if any I/O error occurs + */ + + public void read(InputStream is) throws IOException { + + DataInputStream in = new DataInputStream(is); + + // read in the pdb name. + byte[] bytes = new byte[NAME_LENGTH]; + in.readFully(bytes); + store(bytes); + + // read in number of records + int nrec = in.readUnsignedShort(); + records = new Record[nrec]; + + // read in the Record infos + for (int i = 0; i < nrec; i++) { + + records[i] = new Record(); + records[i].read(in); + } + } + + /** + * Override equals method of Object. + * + * 2 PalmDB objects are equal if they contain the same information, + * i.e. pdb name and records. + * + * This is used primarily for testing purposes only for now. + * + * @param obj a PalmDB object to compare with + * @return boolean true if obj is equal to this, else false. + */ + + public boolean equals(Object obj) { + + boolean bool = false; + + if (obj instanceof PalmDB) { + + PalmDB pdb = (PalmDB) obj; + + checkLabel: { + + // compare sName + + if (!sName.equals(pdb.sName)) { + + break checkLabel; + } + + // compare bName + + if (bName.length != pdb.bName.length) { + + break checkLabel; + } + + for (int i = 0; i < bName.length; i++) { + + if (bName[i] != pdb.bName[i]) { + + break checkLabel; + } + } + + // compare each Record + + if (records.length != pdb.records.length) { + + break checkLabel; + } + + for (int i = 0; i < records.length; i++) { + + if (!records[i].equals(pdb.records[i])) { + + break checkLabel; + } + } + + // all checks done + bool = true; + } + } + + return bool; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/README b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/README new file mode 100644 index 000000000000..ad08e7592d0d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/README @@ -0,0 +1,10 @@ +Building the Comparator code +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +To build the comparator code, the following is required in your classpath. + + xerces.jar + xmerge.jar + +To Build type + + javac *.java diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/Record.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/Record.java new file mode 100644 index 000000000000..da36105d3eb9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/Record.java @@ -0,0 +1,170 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Record.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.DataOutputStream; +import java.io.DataInputStream; +import java.io.IOException; + +/** + * <p>Contains the raw bytes for a record in a pdb.</p> + * + * <p>Note that it is not associated with a record number or id.</p> + * + * @author Akhil Arora, Herbie Ong + * @see PalmDB + */ + + +public final class Record { + + /** record bytes */ + private byte[] data; + + /** + * Default constructor. + */ + + public Record() { + + data = new byte[0]; + } + + /** + * Constructor to create a Record filled with bytes. + * Note that this does not check for 64k record sizes. + * User of this class has to check for that. + * + * @param d byte array contents for this object. + */ + + public Record(byte[] d) { + + data = new byte[d.length]; + System.arraycopy(d, 0, data, 0, d.length); + } + + /** + * This method returns the number of bytes in this object. + * + * @return int number of bytes in this object. + */ + + public int getSize() { + + return data.length; + } + + /** + * This method returns the contents of this object. + * + * @return byte[] contents in byte array + */ + + public byte[] getBytes() { + + return data; + } + + /** + * Write out the record length followed by the data + * in this Record object. + * + * @param out the stream to write the object to + * @throws IOException if any I/O error occurs + */ + + + public void write(OutputStream outs) throws IOException { + + DataOutputStream out = new DataOutputStream(outs); + out.writeShort(data.length); + out.write(data); + } + + /** + * Read the necessary data to create a pdb from + * the input stream. + * + * @param in the stream to read data from in order to + * restore the object + * @throws IOException if any I/O error occurs + */ + + public void read(InputStream ins) throws IOException { + + DataInputStream in = new DataInputStream(ins); + int len = in.readUnsignedShort(); + data = new byte[len]; + in.readFully(data); + } + + /** + * Override equals method of Object. + * + * 2 Record objects are equal if they contain the same bytes + * in the array. + * + * This is used primarily for testing purposes only for now. + * + * @param obj a Record object to compare with + * @return boolean true if obj is equal to this, else false. + */ + + public boolean equals(Object obj) { + + boolean bool = false; + + if (obj instanceof Record) { + + Record rec = (Record) obj; + + checkLabel: { + + if (rec.getSize() == data.length) { + + for (int i = 0; i < data.length; i++) { + + if (data[i] != rec.data[i]) { + break checkLabel; + } + } + + bool = true; + } + } + } + + return bool; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/SimplePdbCompare.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/SimplePdbCompare.java new file mode 100644 index 000000000000..b15593757f5d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/SimplePdbCompare.java @@ -0,0 +1,97 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SimplePdbCompare.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/* + * SimplePdbCompare.java + * + * Created on September 21, 2001, 10:23 AM + */ + +/** + * + * @author mh101528 + * @version + */ +public final class SimplePdbCompare { + + /** Creates new SimplePdbCompare */ + public SimplePdbCompare() { + } + + /** + * @param args the command line arguments + */ + public static void main (String args[]) + { + SimplePdbCompare comparator = new SimplePdbCompare(); + if (comparator.comparePDB(args[0], args[1])) + System.exit(2); + else + System.exit(3); + } + + public boolean comparePDB(String pdbname1, String pdbname2) + { + PalmDB pdb1=null, pdb2=null; + PDBDecoder decoder = new PDBDecoder(); + try + { + pdb1 = decoder.parse(pdbname1); + } + catch (Exception e) + { + System.out.println("Could not parse PDB " + pdbname1); + return false; + } + + try + { + pdb2 = decoder.parse(pdbname2); + } + catch (Exception e) + { + System.out.println("Could not parse PDB " + pdbname2); + return false; + } + + if (pdb1.equals(pdb2)) + { + //writeToLog("PDB " + pdbname1 + " and PDB " + pdbname2 + " are equal"); + System.out.println("PDB " + pdbname1 + " and PDB " + pdbname2 + " are equal"); + return true; + } + else + { + //writeToLog("PDB " + pdbname1 + " and PDB " + pdbname2 + " are not equal"); + System.out.println("PDB " + pdbname1 + " and PDB " + pdbname2 + " are not equal"); + return false; + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlDiff.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlDiff.java new file mode 100644 index 000000000000..b02812ebb24b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlDiff.java @@ -0,0 +1,468 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: XmlDiff.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +import java.io.FileWriter; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.BufferedInputStream; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.io.PrintWriter; +import java.util.Vector; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Node; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +/** + * This class will diff 2 Xml files. + * + * @author Stephen Mak + */ + +public final class XmlDiff { + + private static final String PROPSFILE = "XmlDiff.properties"; + private static final String FILE1 = "XmlDiff.file1"; + private static final String FILE2 = "XmlDiff.file2"; + private static final String OUTPUT= "XmlDiff.output"; + private static final String IGNORE_TAGS= "XmlDiff.tags"; + + private Properties props_ = null; + private static PrintWriter writer_ = null; + private String[] tags_ = null; + private String file1_ = null; + private String file2_ = null; + + /** + * Constructor. Load the properties file. + */ + + public XmlDiff() throws IOException { + + Class c = this.getClass(); + InputStream is = c.getResourceAsStream(PROPSFILE); + BufferedInputStream bis = new BufferedInputStream(is); + props_ = new Properties(); + props_.load(bis); + bis.close(); + + String file1 = props_.getProperty(FILE1, ""); + String file2 = props_.getProperty(FILE2, ""); + String tagsString = props_.getProperty(IGNORE_TAGS, ""); + String output = props_.getProperty("debug.output", "System.out"); + setOutput(output); + tags_ = parseTags(tagsString); + } + + /** + * diff 2 xml, but overwrite the property file's file1/2 setting with + * the input argument + */ + public boolean diff(String file1, String file2) throws IOException { + file1_ = file1; + file2_ = file2; + return diff(); + } + + public boolean diff() throws IOException { + + boolean result = false; + + writer_.println("parsing "+ file1_ + "..."); + // parse the Xml file + Document doc1 = parseXml(file1_); + + writer_.println("parsing "+ file1_ + "..."); + Document doc2 = parseXml(file2_); + + if (doc1 != null && doc2 != null) { + writer_.println("diffing "+ file1_ + " & " + file2_ + "..."); + result = compareNode(doc1, doc2); + } + return result; + } + + private void diffLog(String errMsg, Node node1, Node node2) { + + String node1Str = ""; + String node2Str = ""; + + if (node1 != null) { + node1Str = "[Type]:" + nodeInfo(node1) + + " [Name]:" + node1.getNodeName(); + if (node1.getNodeValue() != null) + node1Str += " [Value]:" + node1.getNodeValue(); + } + + if (node2 != null) { + node2Str = "[Type]:" + nodeInfo(node2) + + " [Name]:" + node2.getNodeName(); + if (node2.getNodeValue() != null) + node2Str += " [Value]:" + node2.getNodeValue(); + } + + writer_.println(errMsg); + writer_.println(" Node1 - " + node1Str); + writer_.println(" Node2 - " + node2Str); + } + + private String nodeInfo(Node node) { + + String str = null; + switch (node.getNodeType()) { + + case Node.ELEMENT_NODE: + str = "ELEMENT"; + break; + case Node.ATTRIBUTE_NODE: + str = "ATTRIBUTE"; + break; + case Node.TEXT_NODE: + str = "TEXT"; + break; + case Node.CDATA_SECTION_NODE: + str = "CDATA_SECTION"; + break; + case Node.ENTITY_REFERENCE_NODE: + str = "ENTITY_REFERENCE"; + break; + case Node.ENTITY_NODE: + str = "ENTITY"; + break; + case Node.PROCESSING_INSTRUCTION_NODE: + str = "PROCESSING_INSTRUCTION"; + break; + case Node.COMMENT_NODE: + str = "COMMENT"; + break; + case Node.DOCUMENT_NODE: + str = "DOCUMENT"; + break; + case Node.DOCUMENT_TYPE_NODE: + str = "DOCUMENT_TYPE"; + break; + case Node.DOCUMENT_FRAGMENT_NODE: + str = "DOCUMENT_FRAGMENT"; + break; + case Node.NOTATION_NODE: + str = "NOTATION"; + break; + } + return str; + } + + private boolean ignoreTag(String nodeName) { + + + if (tags_ != null) { + for (int i = 0; i < tags_.length; i++) { + if (tags_[i].equals(nodeName)) + return true; + } + } + return false; + } + + // for future use if we want to compare attributes + private boolean attributesEqual(Node node1, Node node2) { + return true; + } + + private boolean compareNode(Node node1, Node node2) { + boolean equal = false; + + while (true) { + + if (node1 == null && node2 == null) { + equal = true; + break; + } else if (node1 == null || node2 == null) { + diffLog("DIFF: one of the node is null", node1, node2); + break; + } + + if (node1.getNodeType() != node2.getNodeType()) { + diffLog("DIFF: nodetype is different", node1, node2); + break; + } + + if (node1.getNodeName() == null && node2.getNodeName() == null) { + // empty + } else if (node1.getNodeName() == null || + node2.getNodeName() == null) { + diffLog("DIFF: one of the nodeName is null", node1, node2); + break; + } else if (!node1.getNodeName().equals(node2.getNodeName())) { + diffLog("DIFF: nodeName is different", node1, node2); + break; + } + + if (ignoreTag(node1.getNodeName())) { + diffLog("DIFF: Some tag(s) is ignored", node1, node2); + equal = true; + break; + } + + if (node1.getNodeValue() == null && node2.getNodeValue() == null) { + // empty + } else if (node1.getNodeValue() == null || + node2.getNodeValue() == null) { + diffLog("DIFF: one of the nodevalue is null", node1, node2); + break; + } else if (!node1.getNodeValue().equals(node2.getNodeValue())) { + diffLog("DIFF: nodeValue is different", node1, node2); + break; + } + + // try to compare attributes if necessary + if (!attributesEqual(node1, node2)) + break; + + NodeList node1Children = node1.getChildNodes(); + NodeList node2Children = node2.getChildNodes(); + + // number of children have to be the same + if (node1Children == null && node2Children == null) { + equal = true; + break; + } + + if (node1Children == null || node2Children == null) { + diffLog("DIFF: one node's children is null", node1, node2); + break; + } + + if (node1Children.getLength() != node2Children.getLength()) { + diffLog("DIFF: num of children is different", node1, node2); + break; + } + + // compare all the childrens + equal = true; + + for (int i = 0; i < node1Children.getLength(); i++) { + if (!compareNode(node1Children.item(i), + node2Children.item(i))) { + equal = false; + break; + } + } + break; + } + + return equal; + } + + private Document parseXml (String filename) throws IOException { + + Document w3cDocument = null; + + FileInputStream fis; + + try { + fis = new FileInputStream(filename); + } catch (FileNotFoundException ex) { + ex.printStackTrace(writer_); + writer_.println(ex.getMessage()); + return w3cDocument; + } + + /** factory for DocumentBuilder objects */ + DocumentBuilderFactory factory = null; + factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(false); + + /** DocumentBuilder object */ + DocumentBuilder builder = null; + + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + ex.printStackTrace(writer_); + writer_.println(ex.getMessage()); + return null; + } + + + builder.setErrorHandler( + new org.xml.sax.ErrorHandler() { + // ignore fatal errors (an exception is guaranteed) + public void fatalError(SAXParseException e) + throws SAXException { + throw e; + } + + public void error(SAXParseException e) + throws SAXParseException { + // make sure validation error is thrown. + throw e; + } + + public void warning(SAXParseException e) + throws SAXParseException { + } + } + ); + + try { + w3cDocument = builder.parse(fis); + w3cDocument.getDocumentElement().normalize(); + } catch (SAXException ex) { + ex.printStackTrace(writer_); + writer_.println(ex.getMessage()); + return w3cDocument; + } + + return w3cDocument; + } + + private String [] parseTags(String tagsString) { + Vector tagsVector = new Vector(); + if (tagsString.length() == 0) + return null; + + int start = 0; + int end = 0; + // break the tag string into a vector of strings by words + for (end = tagsString.indexOf(" ", start); + end != -1 ; + start = end + 1, end = tagsString.indexOf(" ", start)) { + tagsVector.add(tagsString.substring(start,end)); + } + + tagsVector.add(tagsString.substring(start,tagsString.length())); + + // convert the vector to array + String[] tags= new String[tagsVector.size()]; + tagsVector.copyInto(tags); + + return tags; + } + + + /** + * Set the output to the specified argument. + * This method is only used internally to prevent + * invalid string parameter. + * + * @param str output specifier + */ + private static void setOutput(String str) { + + if (writer_ == null) { + + if (str.equals("System.out")) { + + setOutput(System.out); + + } else if (str.equals("System.err")) { + + setOutput(System.err); + + } else { + + try { + + setOutput(new FileWriter(str)); + + } catch (IOException e) { + + e.printStackTrace(System.err); + } + } + } + } + + /** + * Set the output to an OutputStream object. + * + * @param stream OutputStream object + */ + + private static void setOutput(OutputStream stream) { + + setOutput(new OutputStreamWriter(stream)); + } + + /** + * Set the Writer object to manage the output. + * + * @param w Writer object to write out + */ + + private static void setOutput(Writer w) { + + if (writer_ != null) { + + writer_.close(); + } + + writer_ = new PrintWriter(new BufferedWriter(w), true); + } + + public static void main(String args[]) throws IOException { + + if (args.length != 0 && args.length != 2) { + System.out.println("Usage: XmlDiff [<file1> <file2>]."); + return; + } + + XmlDiff xmldiff = new XmlDiff(); + + boolean same = false; + if (args.length == 2) { + same = xmldiff.diff(args[0], args[1]); + } else { + same = xmldiff.diff(); + } + + System.out.println("Diff result: " + same); + if (same) + { + System.out.println("XMLDIFFRESULT:PASSED"); + } else { + System.out.println("XMLDIFFRESULT:FAILED"); + } + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlDiff.properties b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlDiff.properties new file mode 100644 index 000000000000..513add086214 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlDiff.properties @@ -0,0 +1,13 @@ +# +# $Id: XmlDiff.properties,v 1.1 2002-04-16 13:53:20 aidan Exp $ +# +# This properties file provides info for XmlDiff program +# XmlDiff.file1 is the first input XML file +# XmlDiff.file2 is the second input XML file +# XmlDiff.output is where the output (err/message) go +# XmlDiff.tags are what tagname should ignore (and the subtree under it) +# +XmlDiff.file1=test1.xml +XmlDiff.file2=test2.xml +XmlDiff.output=System.err +XmlDiff.tags= diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlWrapper.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlWrapper.java new file mode 100644 index 000000000000..19a69602ee29 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlWrapper.java @@ -0,0 +1,156 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: XmlWrapper.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +import java.io.IOException; +import java.io.File; +import java.util.zip.*; + +public class XmlWrapper +{ + public static void main(String args[]) throws IOException + { + System.out.println("args.length is " + args.length); + if (args.length < 2) { + System.out.println("Usage: java XmlWrapper [<zipfile1> <zipfile2>]."); + //return; + System.exit(-1); + + } + + XmlWrapper w = new XmlWrapper(); + File currdirfp = null; + try { + currdirfp = new File("."); + } catch (Exception fx) { + System.out.println("Could not get File instance for current directory \n"); + //return; + System.exit(-1); + } + + File f1 = null; + File f2 = null; + String fname1,fname2; + try { + f1 = File.createTempFile("xmlcomp", ".tmp", currdirfp); + f2 = File.createTempFile("xmlcomp", ".tmp", currdirfp); + } catch (Exception tx) { + System.out.println("Could not create TempFile "); + System.out.println("Exception: " + tx.toString()); + //return; + System.exit(-1); + } + + fname1 = f1.getAbsolutePath(); + fname2 = f2.getAbsolutePath(); + + // get content.xml file from zip file and copy it to temporary + // filename + XmlZipExtract xw1 = new XmlZipExtract(args[0]); + try { + xw1.getContentXml(fname1); + } catch (ZipException e) { + System.out.println("Exception: file is not a ZIP file: " + args[0]); + f1.delete(); + f2.delete(); + //return; + System.exit(-1); + } catch (Exception e) { + System.out.println("Exception: Could not extract XML from " + args[0]); + System.out.println("Exception: " + e.toString()); + f1.delete(); + f2.delete(); + //return; + System.exit(-1); + } + + // get content.xml file from zip file and copy it to temporary + // filename + XmlZipExtract xw2 = new XmlZipExtract(args[1]); + try { + xw2.getContentXml(fname2); + } catch (ZipException e) { + System.out.println("Exception: file is not a ZIP file: " + args[0]); + f1.delete(); + f2.delete(); + //return; + System.exit(-1); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + System.out.println("Exception: Could not extract XML from " + args[1]); + System.out.println("Exception: " + ex.toString()); + f1.delete(); + f2.delete(); + //return; + System.exit(-1); + } + + boolean same = false; + + try + { + XmlDiff xmldiff = new XmlDiff(); + + if (args.length == 2) { + same = xmldiff.diff(fname1, fname2); + } else { + same = xmldiff.diff(); + } + } + catch (Exception ex) + { + System.out.println("XmlDiff failed"); + System.out.println("Exception: " + ex.toString()); + f1.delete(); + f2.delete(); + //return; + System.exit(-1); + } + + System.out.println("Diff result: " + same); + if (same) + { + System.out.println("XMLDIFFRESULT:PASSED"); + } else { + System.out.println("XMLDIFFRESULT:FAILED"); + } + + f1.delete(); + f2.delete(); + + if (same) + { + System.exit(2); + } + else + { + System.exit(3); + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlZipExtract.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlZipExtract.java new file mode 100644 index 000000000000..fb1b25eaee4a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/XmlZipExtract.java @@ -0,0 +1,149 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: XmlZipExtract.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +import java.io.IOException; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.RandomAccessFile; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Enumeration; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; + +public class XmlZipExtract +{ + + public static final String CONTENT = "Content.xml"; + public static final String OLDCONTENT = "content.xml"; + private static final int BUFFER_SIZE = 2048; + + + /** + * Full path of the Zip file to process. + */ + private String filename = null; + + + /** + * Constructor + * + * @param filename Full Path to Zip file to process + * + */ + public XmlZipExtract(String filename) { + this.filename = filename; + } + + /** + * Copies Content.xml from zip file onto the filename passed as + * an argument + * + * @param fname Full Path to file to which contents have to be copied + * + */ + public void getContentXml(String fname) throws IOException + { + try + { + getContentXmlInt(fname, XmlZipExtract.CONTENT); + } + catch (NullPointerException e1) + { + // If the new name of the content file failed, try + // the older name. + // + System.out.println(filename + " Content.xml does not exist, trying content.xml..."); + try + { + getContentXmlInt(fname, XmlZipExtract.OLDCONTENT); + } + catch (NullPointerException e2) + { + System.out.println(filename + " content.xml does not exist, trying content.xml..."); + throw e2; + } + } + } + + public void getContentXmlInt(String fname, String cname) throws IOException + { + byte b[] = getEntry(cname); + + RandomAccessFile raf=null; + raf = new RandomAccessFile(fname, "rw"); + raf.write(b); + raf.close(); + } + + /** + * Get the specified entry in the zip file as a stream. + * + * @param entryName The name of the entry in the zipfile to get. + * This should be one of the constants defined above. + * + * @return byte[] bits for entryName + * + * @throws IOException if something goes wrong + */ + public byte[] getEntry(String entryName) throws IOException + { + ZipFile zf = new ZipFile(filename); + ZipEntry ze = zf.getEntry(entryName); + byte[] bits = readStream(zf.getInputStream(ze)); + zf.close(); + return bits; + } + + + /** + * Read an InputStream into an array of bytes. + * + * @param is InputStream of data from Zip file + * + * @return an array of Bytes + */ + private byte[] readStream(InputStream is) throws IOException + { + BufferedInputStream bis = new BufferedInputStream(is); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[BUFFER_SIZE]; + int eof = 0; + while ((eof = bis.read(buffer, 0, buffer.length)) > 0) { + baos.write(buffer, 0, eof); + } + + return baos.toByteArray(); + } +} + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/comparator.pl b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/comparator.pl new file mode 100755 index 000000000000..9a5bf484947e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/comparator.pl @@ -0,0 +1,249 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: comparator.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$compare_home = "$ENV{QA_COMPARATOR_HOME}"; + +if ($ENV{'CLASSPATH'}) +{ + $classpath_val = "$compare_home:$ENV{'CLASSPATH'}"; +} +else +{ + $classpath_val = "$compare_home"; +} + +print "classpath is $classpath_val\n"; + +$list_file=""; +$orig_dir=""; +$new_dir=""; +$diff_type=""; + +####### BEGIN MAIN ############## +$cmdline_len = @ARGV; +if ($cmdline_len <= 0) +{ + print_usage(); + exit (0); +} + +process_cmdline(@ARGV); +print_env(); +open (LOGFILE, ">$logfile") || die "Cannot open log file $logfile"; +if ($test_list ne "") +{ + open (TESTLIST, $test_list) || die "Couldn't open diff list file $test_list"; + + while (<TESTLIST>) + { + chomp $_; + process_diff(get_file_title($_)); + } +} +close TESTLIST; +close LOGFILE; + +####### END MAIN ############## + +sub process_diff +{ + $_[0] =~ tr/A-Z/a-z/; + + # chdir to the output directory so the temporary files created by + # the java programs are put in the right place. + # + chdir ($xml_new); + + if ($diff_type eq "xml") + { + # Ugly hack, probably a way to tell xerces directly that the dtd's + # are in $compare_home/dtd. + # + `cp $compare_home/dtd/* $xml_new`; + + $cmd = "java -classpath $classpath_val XmlWrapper $xml_orig/$_[0].sxw $xml_new/$_[0].sxw"; + $val = system($cmd)/256; + if ($val == 2) + { + print LOGFILE "$_[0]|TRUE|$xml_orig/$_[0].sxw|$xml_new/$_[0].sxw\n"; + } + elsif($val == 3) + { + print LOGFILE "$_[0]|FALSE|$xml_orig/$_[0].sxw|$xml_new/$_[0].sxw\n"; + } + else + { + print LOGFILE "$_[0]|ERROR|$xml_orig/$_[0].sxw|$xml_new/$_[0].sxw\n"; + } + } + elsif ($diff_type eq "pdb") + { + $cmd = "java -classpath $classpath_val SimplePdbCompare $pdb_orig/$_[0].pdb $pdb_new/$_[0].pdb\n"; + print "Executing: $cmd\n"; + $val = system($cmd)/256; + if ($val == 2) + { + print LOGFILE "$_[0]|TRUE|$pdb_orig/$_[0].pdb|$pdb_new/$_[0].pdb\n"; + } + elsif($val == 3) + { + print LOGFILE "$_[0]|FALSE|$pdb_orig/$_[0].pdb|$pdb_new/$_[0].pdb\n"; + } + else + { + print LOGFILE "$_[0]|ERROR|$pdb_orig/$_[0].pdb|$pdb_new/$_[0].pdb\n"; + } + } + else + { + die "Don't understand test type of $diff_type."; + } +} + +sub process_cmdline +{ + foreach $i (@_) + { + @arg= split('=', $i); + @arg[0] =~ tr/A-Z/a-z/; + + if (@arg[0] eq "-pdb-orig") + { + $pdb_orig=$arg[1]; + } + elsif (@arg[0] eq "-pdb-new") + { + $pdb_new=$arg[1]; + } + elsif (@arg[0] eq "-xml-orig") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "-xml-new") + { + $xml_new=$arg[1]; + } + elsif (@arg[0] eq "-env") + { + set_env_from_props($arg[1]); + } + elsif (@arg[0] eq "-list") + { + $test_list = $arg[1]; + } + elsif (@arg[0] eq "-one") + { + $infile = $arg[1]; + } + elsif (@arg[0] eq "-type") + { + $diff_type = $arg[1]; + chomp $diff_type; + } + elsif (@arg[0] eq "-log") + { + $logfile = $arg[1]; + } + else + { + print_usage(); + die "Incorrect command line. Don't understand $i"; + } + } +} + +sub set_env_from_props +{ + open(PROPSFILE, $_[0]) || die "Could not open properties file"; + + while (<PROPSFILE>) + { + chomp $_; + @arg = split('=', $_); + @arg[0] =~ tr/a-z/A-Z/; + $len = @arg; + if ($len != 2) + { + die "Malformed property in $ARGV[0]"; + } + + if (@arg[0] eq "PDB_ORIG") + { + $pdb_orig=$arg[1]; + } + elsif (@arg[0] eq "PDB_NEW") + { + $pdb_new=$arg[1]; + } + elsif (@arg[0] eq "XML_ORIG") + { + $xml_orig=$arg[1]; + } + elsif (@arg[0] eq "XML_NEW") + { + $xml_new=$arg[1]; + } + + } + close PROPSFILE; +} + +sub print_usage +{ + print "Usage : compartor.pl - compare Office or pdb files\n"; + print "\t-one=<file> :\t\t individual test case file to run\n"; + print "\t-list=<file> :\t\t list of test case files\n"; + print "\t-env=<file> :\t\t Properites like file defining env\n"; + print "\t-pdb-orig=<path> :\t directory to hold original pdb files\n"; + print "\t-pdb-new=<path> :\t directory to hold new pdb files\n"; + print "\t-xml-orig=<path> :\t directory to hold original office documents\n"; + print "\t-xml-new=<path> :\t directory to hold new office documents\n"; + print "\t-type=<xml|pdb> :\t Invokes the merge option when converting\n"; + print "\t-log=<logfile> :\t Save results to logfile.\n"; +} + +sub print_env +{ + print "Using the following environment:\n"; + print "\tPDB_ORIG = $pdb_orig\n"; + print "\tPDB_NEW = $pdb_new\n"; + print "\tXML_ORIG = $xml_orig\n"; + print "\tXML_NEW = $xml_new\n\n"; +} + +sub get_file_title +{ + @paths = split('\/', $_[0]); + $len = @paths; + @names = split('\.', @paths[$len-1]); + return $names[0]; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/Blocklist.dtd b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/Blocklist.dtd new file mode 100644 index 000000000000..c1d585a7b0a9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/Blocklist.dtd @@ -0,0 +1,38 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: Blocklist.dtd,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<!ELEMENT block-list:block-list (block-list:block*) > +<!ATTLIST block-list:block-list + block-list:list-name CDATA #REQUIRED> +<!ELEMENT block-list:block EMPTY> +<!ATTLIST block-list:block + block-list:abbreviated-name CDATA #REQUIRED + block-list:package-name CDATA #REQUIRED + block-list:name CDATA #REQUIRED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/chart.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/chart.mod new file mode 100644 index 000000000000..dec81f10aac6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/chart.mod @@ -0,0 +1,232 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: chart.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + +<!ENTITY % chart-class "(line|area|circle|ring|scatter|radar|bar|stock|add-in)"> +<!ENTITY % chart-solid-type "(cuboid|cylinder|cone|pyramid)"> + +<!-- Chart element --> +<!ELEMENT chart:chart ( chart:title?, chart:subtitle?, chart:legend?, + chart:plot-area, + table:table? )> +<!ATTLIST chart:chart + chart:class %chart-class; #REQUIRED + chart:add-in-name %string; #IMPLIED + chart:table-number-list %string; #IMPLIED + draw:name %string; #IMPLIED + %draw-position; + %draw-size; + %draw-style-name; + chart:style-name %styleName; #IMPLIED> + +<!ATTLIST chart:chart %presentation-class; > +<!ATTLIST chart:chart %zindex;> +<!ATTLIST chart:chart %draw-end-position; > +<!ATTLIST chart:chart draw:id %draw-shape-id; > +<!ATTLIST chart:chart draw:layer %layerName; #IMPLIED> + +<!ATTLIST style:properties + chart:scale-text %boolean; "true" + chart:stock-updown-bars %boolean; "false" + chart:stock-with-volume %boolean; "false" + chart:three-dimensional %boolean; "false" + chart:deep %boolean; "false" + chart:lines %boolean; "false" + chart:percentage %boolean; "false" + chart:solid-type %chart-solid-type; "cuboid" + chart:splines %nonNegativeInteger; "0" + chart:stacked %boolean; "false" + chart:symbol %integer; "-1" + chart:vertical %boolean; "false" + chart:lines-used %nonNegativeInteger; "0" + chart:connect-bars %boolean; "false"> + +<!-- Main/Sub Title --> +<!-- the cell-address attribute is currently not supported for titles --> +<!ELEMENT chart:title (text:p)?> +<!ATTLIST chart:title + table:cell-range %cell-address; #IMPLIED + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ELEMENT chart:subtitle (text:p)?> +<!ATTLIST chart:subtitle + table:cell-range %cell-address; #IMPLIED + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- you must specify either a legend-position or both, x and y coordinates --> +<!ELEMENT chart:legend EMPTY> +<!ATTLIST chart:legend + chart:legend-position (top|left|bottom|right) "right" + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- Plot-Area specification --> + +<!ELEMENT chart:plot-area (dr3d:light*, + chart:axis*, + chart:categories?, + chart:series*, + chart:wall?, + chart:floor?) > + +<!ATTLIST chart:plot-area + svg:x %coordinate; #IMPLIED + svg:y %coordinate; #IMPLIED + svg:width %length; #IMPLIED + svg:height %length; #IMPLIED + chart:style-name %styleName; #IMPLIED + table:cell-range-address %cell-range-address; #IMPLIED + chart:table-number-list %string; #IMPLIED + chart:data-source-has-labels (none|row|column|both) "none" > + +<!-- 3d scene attributes on plot-area --> +<!ATTLIST chart:plot-area + dr3d:vrp %vector3D; #IMPLIED + dr3d:vpn %vector3D; #IMPLIED + dr3d:vup %vector3D; #IMPLIED + dr3d:projection (parallel|perspective) #IMPLIED + dr3d:transform CDATA #IMPLIED + dr3d:distance %length; #IMPLIED + dr3d:focal-length %length; #IMPLIED + dr3d:shadow-slant %nonNegativeInteger; #IMPLIED + dr3d:shade-mode (flat|phong|gouraud|draft) #IMPLIED + dr3d:ambient-color %color; #IMPLIED + dr3d:lighting-mode %boolean; #IMPLIED > + +<!ATTLIST style:properties + chart:series-source (columns|rows) "columns" > + +<!ELEMENT chart:wall EMPTY> +<!ATTLIST chart:wall + svg:width %length; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ELEMENT chart:floor EMPTY> +<!ATTLIST chart:floor + svg:width %length; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- Axis --> + +<!ELEMENT chart:axis (chart:title?, chart:grid*)> +<!ATTLIST chart:axis + chart:class (category|value|series|domain) #REQUIRED + chart:name %string; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ATTLIST style:properties + chart:tick-marks-major-inner %boolean; "false" + chart:tick-marks-major-outer %boolean; "true" + chart:tick-marks-minor-inner %boolean; "false" + chart:tick-marks-minor-outer %boolean; "false" + chart:logarithmic %boolean; "false" + chart:maximum %float; #IMPLIED + chart:minimum %float; #IMPLIED + chart:origin %float; #IMPLIED + chart:interval-major %float; #IMPLIED + chart:interval-minor %float; #IMPLIED + chart:gap-width %integer; #IMPLIED + chart:overlap %integer; #IMPLIED + text:line-break %boolean; "true" + chart:display-label %boolean; "true" + chart:label-arrangement (side-by-side|stagger-even|stagger-odd) "side-by-side" + chart:visible %boolean; "true" + chart:link-data-style-to-source %boolean; "true" > + +<!ELEMENT chart:grid EMPTY> +<!ATTLIST chart:grid + chart:class (major|minor) "major" + chart:style-name %styleName; #IMPLIED > + + +<!ELEMENT chart:categories EMPTY> +<!ATTLIST chart:categories + table:cell-range-address %cell-range-address; #REQUIRED > + +<!-- + each series element must have an cell-range-address element that points + to the underlying table data. + Impl. Note: Internally all href elements are merged to one table range + that represents the data for the whole chart +--> +<!ELEMENT chart:series ( chart:domain*, + chart:data-point* )> +<!ATTLIST chart:series + chart:values-cell-range-address %cell-range-address; #IMPLIED + chart:label-cell-address %cell-address; #IMPLIED + chart:class %chart-class; #IMPLIED + chart:attached-axis %string; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!ELEMENT chart:domain EMPTY> +<!ATTLIST chart:domain + table:cell-range-address %cell-range-address; #IMPLIED > + +<!ELEMENT chart:data-point EMPTY> +<!ATTLIST chart:data-point + chart:repeated %nonNegativeInteger; #IMPLIED + chart:style-name %styleName; #IMPLIED > + +<!-- statistical properties --> + +<!ATTLIST style:properties + chart:mean-value %boolean; #IMPLIED + chart:error-category (none|variance|standard-deviation|percentage|error-margin|constant) "none" + chart:error-percentage %float; #IMPLIED + chart:error-margin %float; #IMPLIED + chart:error-lower-limit %float; #IMPLIED + chart:error-upper-limit %float; #IMPLIED + chart:error-upper-indicator %boolean; #IMPLIED + chart:error-lower-indicator %boolean; #IMPLIED + chart:regression-type (none|linear|logarithmic|exponential|power) "none" > + +<!-- data label properties --> + +<!ATTLIST style:properties + chart:data-label-number (none|value|percentage) "none" + chart:data-label-text %boolean; "false" + chart:data-label-symbol %boolean; "false" > + +<!-- general text properties --> + +<!ATTLIST style:properties text:rotation-angle %integer; "0" > + +<!-- symbol properties --> + +<!ATTLIST style:properties + chart:symbol-width %nonNegativeLength; #IMPLIED + chart:symbol-height %nonNegativeLength; #IMPLIED + chart:symbol-image-name %string; #IMPLIED > diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/datastyl.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/datastyl.mod new file mode 100644 index 000000000000..31bf7a464c77 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/datastyl.mod @@ -0,0 +1,172 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: datastyl.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!-- data styles --> +<!ENTITY % any-number "( number:number | number:scientific-number | number:fraction )"> +<!ENTITY % number-style-content "( (number:text,(%any-number;,number:text?)?) | (%any-number;,number:text?) )"> +<!ELEMENT number:number-style ( style:properties?, %number-style-content;, style:map* )> +<!ELEMENT number:number EMPTY> +<!ELEMENT number:scientific-number EMPTY> +<!ELEMENT number:fraction EMPTY> + +<!ENTITY % currency-symbol-and-text "number:currency-symbol,number:text?"> +<!ENTITY % number-and-text "number:number,number:text?"> +<!ENTITY % currency-symbol-and-number "((%number-and-text;),(%currency-symbol-and-text;)?) | ((%currency-symbol-and-text;),(%number-and-text;)?)"> +<!ENTITY % currency-style-content "number:text?, (%currency-symbol-and-number;)?"> + +<!ELEMENT number:currency-style ( style:properties?, (%currency-style-content;), style:map* )> +<!ELEMENT number:currency-symbol (#PCDATA)> +<!ATTLIST number:currency-symbol number:language CDATA #IMPLIED> +<!ATTLIST number:currency-symbol number:country CDATA #IMPLIED> + +<!ENTITY % percentage-style-content "( (number:text,(%number-and-text;)?) | (%number-and-text;) )"> +<!ELEMENT number:percentage-style ( style:properties?, %percentage-style-content;, style:map* )> + +<!ENTITY % any-date "( number:day | number:month | number:year | number:era | number:day-of-week | number:week-of-year | number:quarter| number:hours | number:am-pm | number:minutes | number:seconds )"> +<!ENTITY % date-style-content "( (number:text,(%any-date;,number:text?)+) | (%any-date;,number:text?)+ )"> +<!ELEMENT number:date-style ( style:properties?, %date-style-content;, style:map* )> +<!ELEMENT number:day EMPTY> +<!ATTLIST number:day number:style (short|long) "short"> +<!ATTLIST number:day number:calendar CDATA #IMPLIED> +<!ELEMENT number:month EMPTY> +<!ATTLIST number:month number:textual %boolean; "false"> +<!ATTLIST number:month number:style (short|long) "short"> +<!ATTLIST number:month number:calendar CDATA #IMPLIED> +<!ELEMENT number:year EMPTY> +<!ATTLIST number:year number:style (short|long) "short"> +<!ATTLIST number:year number:calendar CDATA #IMPLIED> +<!ELEMENT number:era EMPTY> +<!ATTLIST number:era number:style (short|long) "short"> +<!ATTLIST number:era number:calendar CDATA #IMPLIED> +<!ELEMENT number:day-of-week EMPTY> +<!ATTLIST number:day-of-week number:style (short|long) "short"> +<!ATTLIST number:day-of-week number:calendar CDATA #IMPLIED> +<!ELEMENT number:week-of-year EMPTY> +<!ATTLIST number:week-of-year number:calendar CDATA #IMPLIED> +<!ELEMENT number:quarter EMPTY> +<!ATTLIST number:quarter number:style (short|long) "short"> +<!ATTLIST number:quarter number:calendar CDATA #IMPLIED> + +<!ENTITY % any-time "( number:hours | number:am-pm | number:minutes | number:seconds )"> +<!ENTITY % time-style-content "( (number:text,(%any-time;,number:text?)+) | (%any-time;,number:text?)+)"> +<!ELEMENT number:time-style ( style:properties?, %time-style-content;, style:map* )> +<!ELEMENT number:hours EMPTY> +<!ATTLIST number:hours number:style (short|long) "short"> +<!ELEMENT number:minutes EMPTY> +<!ATTLIST number:minutes number:style (short|long) "short"> +<!ELEMENT number:seconds EMPTY> +<!ATTLIST number:seconds number:style (short|long) "short"> +<!ATTLIST number:seconds number:decimal-places %integer; "0"> +<!ELEMENT number:am-pm EMPTY> + +<!ENTITY % boolean-style-content "( (number:text,(number:boolean,number:text?)?) | (number:boolean,number:text?) )"> +<!ELEMENT number:boolean-style ( style:properties?,%boolean-style-content;, style:map* )> +<!ELEMENT number:boolean EMPTY> + +<!ENTITY % text-style-content "( (number:text,(number:text-content,number:text?)?) | (number:text-content,number:text?) )"> +<!ELEMENT number:text-style ( style:properties?,%text-style-content;, style:map* )> +<!ELEMENT number:text (#PCDATA)> +<!ELEMENT number:text-content EMPTY> + +<!ATTLIST number:number-style style:name %styleName; #REQUIRED> +<!ATTLIST number:currency-style style:name %styleName; #REQUIRED> +<!ATTLIST number:percentage-style style:name %styleName; #REQUIRED> +<!ATTLIST number:date-style style:name %styleName; #REQUIRED> +<!ATTLIST number:time-style style:name %styleName; #REQUIRED> +<!ATTLIST number:boolean-style style:name %styleName; #REQUIRED> +<!ATTLIST number:text-style style:name %styleName; #REQUIRED> + +<!ATTLIST number:number-style style:family CDATA #REQUIRED> +<!ATTLIST number:currency-style style:family CDATA #REQUIRED> +<!ATTLIST number:percentage-style style:family CDATA #REQUIRED> +<!ATTLIST number:date-style style:family CDATA #REQUIRED> +<!ATTLIST number:time-style style:family CDATA #REQUIRED> +<!ATTLIST number:boolean-style style:family CDATA #REQUIRED> +<!ATTLIST number:text-style style:family CDATA #REQUIRED> + +<!ATTLIST number:number-style number:language CDATA #IMPLIED> +<!ATTLIST number:currency-style number:language CDATA #IMPLIED> +<!ATTLIST number:percentage-style number:language CDATA #IMPLIED> +<!ATTLIST number:date-style number:language CDATA #IMPLIED> +<!ATTLIST number:time-style number:language CDATA #IMPLIED> +<!ATTLIST number:boolean-style number:language CDATA #IMPLIED> +<!ATTLIST number:text-style number:language CDATA #IMPLIED> + +<!ATTLIST number:number-style number:country CDATA #IMPLIED> +<!ATTLIST number:currency-style number:country CDATA #IMPLIED> +<!ATTLIST number:percentage-style number:country CDATA #IMPLIED> +<!ATTLIST number:date-style number:country CDATA #IMPLIED> +<!ATTLIST number:time-style number:country CDATA #IMPLIED> +<!ATTLIST number:boolean-style number:country CDATA #IMPLIED> +<!ATTLIST number:text-style number:country CDATA #IMPLIED> + +<!ATTLIST number:number-style number:title CDATA #IMPLIED> +<!ATTLIST number:currency-style number:title CDATA #IMPLIED> +<!ATTLIST number:percentage-style number:title CDATA #IMPLIED> +<!ATTLIST number:date-style number:title CDATA #IMPLIED> +<!ATTLIST number:time-style number:title CDATA #IMPLIED> +<!ATTLIST number:boolean-style number:title CDATA #IMPLIED> +<!ATTLIST number:text-style number:title CDATA #IMPLIED> + +<!ATTLIST number:number-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:currency-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:percentage-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:date-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:time-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:boolean-style style:volatile %boolean; #IMPLIED> +<!ATTLIST number:text-style style:volatile %boolean; #IMPLIED> + +<!ATTLIST number:currency-style number:automatic-order %boolean; "false"> +<!ATTLIST number:date-style number:automatic-order %boolean; "false"> + +<!ATTLIST number:date-style number:format-source (fixed|language) "fixed"> +<!ATTLIST number:time-style number:format-source (fixed|language) "fixed"> + +<!ATTLIST number:time-style number:truncate-on-overflow %boolean; "true"> + +<!ATTLIST number:number number:decimal-places %integer; #IMPLIED> +<!ATTLIST number:scientific-number number:decimal-places %integer; #IMPLIED> + +<!ATTLIST number:number number:min-integer-digits %integer; #IMPLIED> +<!ATTLIST number:scientific-number number:min-integer-digits %integer; #IMPLIED> +<!ATTLIST number:fraction number:min-integer-digits %integer; #IMPLIED> + +<!ATTLIST number:number number:grouping %boolean; "false"> +<!ATTLIST number:scientific-number number:grouping %boolean; "false"> +<!ATTLIST number:fraction number:grouping %boolean; "false"> + +<!ATTLIST number:number number:decimal-replacement CDATA #IMPLIED> + +<!ATTLIST number:scientific-number number:min-exponent-digits %integer; #IMPLIED> + +<!ATTLIST number:fraction number:min-numerator-digits %integer; #IMPLIED> + +<!ATTLIST number:fraction number:min-denominator-digits %integer; #IMPLIED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/drawing.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/drawing.mod new file mode 100644 index 000000000000..d200a39fe7f9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/drawing.mod @@ -0,0 +1,841 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: drawing.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % points "CDATA" > +<!ENTITY % pathData "CDATA" > +<!ENTITY % gradient-style "(linear|axial|radial|ellipsoid|square|rectangular)" > +<!ENTITY % draw-position "svg:x %coordinate; #IMPLIED svg:y %coordinate; #IMPLIED"> +<!ENTITY % draw-end-position "table:end-cell-address %cell-address; #IMPLIED table:end-x %coordinate; #IMPLIED table:end-y %coordinate; #IMPLIED"> +<!ENTITY % draw-size "svg:width %coordinate; #IMPLIED svg:height %coordinate; #IMPLIED"> +<!ENTITY % draw-transform "draw:transform CDATA #IMPLIED"> +<!ENTITY % draw-viewbox "svg:viewBox CDATA #REQUIRED"> +<!ENTITY % draw-style-name "draw:style-name %styleName; #IMPLIED presentation:style-name %styleName; #IMPLIED draw:text-style-name %styleName; #IMPLIED"> +<!ENTITY % draw-shape-id "CDATA #IMPLIED" > +<!ENTITY % draw-text "(text:p|text:unordered-list|text:ordered-list)*"> +<!ENTITY % zindex "draw:z-index %nonNegativeInteger; #IMPLIED"> +<!ENTITY % distance "CDATA"> +<!ENTITY % rectanglePoint "(top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right)"> +<!ENTITY % vector3D "CDATA"> +<!ENTITY % text-anchor "text:anchor-type %anchorType; #IMPLIED text:anchor-page-number %positiveInteger; #IMPLIED"> +<!ENTITY % layerName "CDATA"> +<!ENTITY % table-background "table:table-background (true | false) #IMPLIED"> + +<!-- commont presentation shape attributes --> +<!ENTITY % presentation-style-name "presentation:style-name %styleName; #IMPLIED"> +<!ENTITY % presentation-classes "(title|outline|subtitle|text|graphic|object|chart|table|orgchart|page|notes)" > +<!-- ENTITY % presentation-class "presentation:class %presentation-classes; #IMPLIED" --> +<!ENTITY % presentation-class "presentation:class %presentation-classes; #IMPLIED presentation:placeholder (true|false) #IMPLIED presentation:user-transformed (true|false) #IMPLIED"> +<!ENTITY % presentationEffects "(none|fade|move|stripes|open|close|dissolve|wavyline|random|lines|laser|appear|hide|move-short|checkerboard|rotate|stretch)" > +<!ENTITY % presentationEffectDirections "(none|from-left|from-top|from-right|from-bottom|from-center|from-upper-left|from-upper-right|from-lower-left|from-lower-right|to-left|to-top|to-right|to-bottom|to-upper-left|to-upper-right|to-lower-right|to-lower-left|path|spiral-inward-left|spiral-inward-right|spiral-outward-left|spiral-outward-right|vertical|horizontal|to-center|clockwise|counter-clockwise)" > +<!ENTITY % presentationSpeeds "(slow|medium|fast)" > + +<!-- Drawing shapes --> +<!ELEMENT draw:rect ( office:events?, %draw-text; )> +<!ATTLIST draw:rect %draw-position; > +<!ATTLIST draw:rect %draw-end-position; > +<!ATTLIST draw:rect %table-background; > +<!ATTLIST draw:rect %draw-size; > +<!ATTLIST draw:rect %draw-style-name; > +<!ATTLIST draw:rect %draw-transform; > +<!ATTLIST draw:rect draw:corner-radius %nonNegativeLength; #IMPLIED> +<!ATTLIST draw:rect %zindex;> +<!ATTLIST draw:rect draw:id %draw-shape-id;> +<!ATTLIST draw:rect %text-anchor;> +<!ATTLIST draw:rect draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:line ( office:events?, %draw-text; )> +<!ATTLIST draw:line svg:x1 %length; #REQUIRED> +<!ATTLIST draw:line svg:y1 %length; #REQUIRED> +<!ATTLIST draw:line svg:x2 %length; #REQUIRED> +<!ATTLIST draw:line svg:y2 %length; #REQUIRED> +<!ATTLIST draw:line %draw-style-name; > +<!ATTLIST draw:line %draw-transform; > +<!ATTLIST draw:line %zindex;> +<!ATTLIST draw:line %draw-end-position; > +<!ATTLIST draw:line %table-background; > +<!ATTLIST draw:line draw:id %draw-shape-id;> +<!ATTLIST draw:line %text-anchor;> +<!ATTLIST draw:line draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:polyline ( office:events?, %draw-text; )> +<!ATTLIST draw:polyline %draw-position; > +<!ATTLIST draw:polyline %draw-size; > +<!ATTLIST draw:polyline %draw-viewbox; > +<!ATTLIST draw:polyline draw:points %points; #REQUIRED> +<!ATTLIST draw:polyline %draw-style-name; > +<!ATTLIST draw:polyline %draw-transform; > +<!ATTLIST draw:polyline %zindex;> +<!ATTLIST draw:polyline %draw-end-position; > +<!ATTLIST draw:polyline %table-background; > +<!ATTLIST draw:polyline draw:id %draw-shape-id;> +<!ATTLIST draw:polyline %text-anchor;> +<!ATTLIST draw:polyline draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:polygon ( office:events?, %draw-text; )> +<!ATTLIST draw:polygon %draw-position; > +<!ATTLIST draw:polygon %draw-end-position; > +<!ATTLIST draw:polygon %table-background; > +<!ATTLIST draw:polygon %draw-size; > +<!ATTLIST draw:polygon %draw-viewbox; > +<!ATTLIST draw:polygon draw:points %points; #REQUIRED > +<!ATTLIST draw:polygon %draw-style-name; > +<!ATTLIST draw:polygon %draw-transform; > +<!ATTLIST draw:polygon %zindex;> +<!ATTLIST draw:polygon draw:id %draw-shape-id;> +<!ATTLIST draw:polygon %text-anchor;> +<!ATTLIST draw:polygon draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:path ( office:events?, %draw-text; )> +<!ATTLIST draw:path %draw-position;> +<!ATTLIST draw:path %draw-end-position; > +<!ATTLIST draw:path %table-background; > +<!ATTLIST draw:path %draw-size; > +<!ATTLIST draw:path %draw-viewbox; > +<!ATTLIST draw:path svg:d %pathData; #REQUIRED > +<!ATTLIST draw:path %draw-style-name; > +<!ATTLIST draw:path %draw-transform; > +<!ATTLIST draw:path %zindex;> +<!ATTLIST draw:path draw:id %draw-shape-id;> +<!ATTLIST draw:path %text-anchor;> +<!ATTLIST draw:path draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:circle ( office:events?, %draw-text; )> +<!ATTLIST draw:circle %draw-position; > +<!ATTLIST draw:circle %draw-size; > +<!ATTLIST draw:circle %draw-style-name; > +<!ATTLIST draw:circle %draw-transform; > +<!ATTLIST draw:circle %zindex;> +<!ATTLIST draw:circle %draw-end-position; > +<!ATTLIST draw:circle %table-background; > +<!ATTLIST draw:circle draw:id %draw-shape-id;> +<!ATTLIST draw:circle draw:kind (full|section|cut|arc) "full"> +<!ATTLIST draw:circle draw:start-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:circle draw:end-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:circle %text-anchor;> +<!ATTLIST draw:circle draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:ellipse ( office:events?, %draw-text; )> +<!ATTLIST draw:ellipse %draw-position; > +<!ATTLIST draw:ellipse %draw-size; > +<!ATTLIST draw:ellipse %draw-style-name; > +<!ATTLIST draw:ellipse %draw-transform; > +<!ATTLIST draw:ellipse %zindex;> +<!ATTLIST draw:ellipse %draw-end-position; > +<!ATTLIST draw:ellipse %table-background; > +<!ATTLIST draw:ellipse draw:id %draw-shape-id;> +<!ATTLIST draw:ellipse draw:kind (full|section|cut|arc) "full"> +<!ATTLIST draw:ellipse draw:start-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:ellipse draw:end-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST draw:ellipse %text-anchor;> +<!ATTLIST draw:ellipse draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:connector ( office:events?, %draw-text;)> +<!ATTLIST draw:connector draw:type (standard|lines|line|curve) "standard"> +<!ATTLIST draw:connector draw:line-skew CDATA #IMPLIED> +<!ATTLIST draw:connector %draw-style-name;> +<!ATTLIST draw:connector svg:x1 %coordinate; #REQUIRED> +<!ATTLIST draw:connector svg:y1 %coordinate; #REQUIRED> +<!ATTLIST draw:connector svg:x2 %coordinate; #REQUIRED> +<!ATTLIST draw:connector svg:y2 %coordinate; #REQUIRED> +<!ATTLIST draw:connector draw:start-shape %draw-shape-id;> +<!ATTLIST draw:connector draw:start-glue-point %integer; #IMPLIED> +<!ATTLIST draw:connector draw:end-shape %draw-shape-id;> +<!ATTLIST draw:connector draw:end-glue-point %integer; #IMPLIED> +<!ATTLIST draw:connector %zindex;> +<!ATTLIST draw:connector %draw-end-position; > +<!ATTLIST draw:connector %table-background; > +<!ATTLIST draw:connector draw:id %draw-shape-id;> +<!ATTLIST draw:connector %text-anchor;> +<!ATTLIST draw:connector draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:control EMPTY> +<!ATTLIST draw:control %draw-style-name;> +<!ATTLIST draw:control %draw-position; > +<!ATTLIST draw:control %draw-size; > +<!ATTLIST draw:control %control-id; > +<!ATTLIST draw:control %zindex;> +<!ATTLIST draw:control %draw-end-position; > +<!ATTLIST draw:control %table-background; > +<!ATTLIST draw:control draw:id %draw-shape-id;> +<!ATTLIST draw:control %text-anchor;> +<!ATTLIST draw:control draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:g ( office:events?, (%shapes;)* ) > +<!ATTLIST draw:g %draw-transform; > +<!ATTLIST draw:g %draw-style-name; > +<!ATTLIST draw:g %zindex;> +<!ATTLIST draw:g %draw-end-position; > +<!ATTLIST draw:g %table-background; > +<!ATTLIST draw:g draw:id %draw-shape-id;> +<!ATTLIST draw:g %text-anchor;> +<!ATTLIST draw:g draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:page-thumbnail EMPTY> +<!ATTLIST draw:page-thumbnail draw:page-number %positiveInteger; #IMPLIED> +<!ATTLIST draw:page-thumbnail %draw-position; > +<!ATTLIST draw:page-thumbnail %draw-size; > +<!ATTLIST draw:page-thumbnail %draw-style-name; > +<!ATTLIST draw:page-thumbnail %presentation-class; > +<!ATTLIST draw:page-thumbnail %zindex;> +<!ATTLIST draw:page-thumbnail %draw-end-position; > +<!ATTLIST draw:page-thumbnail %table-background; > +<!ATTLIST draw:page-thumbnail draw:id %draw-shape-id;> +<!ATTLIST draw:page-thumbnail %text-anchor;> +<!ATTLIST draw:page-thumbnail draw:layer %layerName; #IMPLIED> + +<!ELEMENT draw:caption ( office:events?, %draw-text;)> +<!ATTLIST draw:caption %draw-position; > +<!ATTLIST draw:caption %draw-end-position; > +<!ATTLIST draw:caption %table-background; > +<!ATTLIST draw:caption %draw-size; > +<!ATTLIST draw:caption %draw-style-name; > +<!ATTLIST draw:caption %draw-transform; > +<!ATTLIST draw:caption draw:caption-point-x %coordinate; #IMPLIED> +<!ATTLIST draw:caption draw:caption-point-y %coordinate; #IMPLIED> +<!ATTLIST draw:caption %zindex;> +<!ATTLIST draw:caption draw:id %draw-shape-id;> +<!ATTLIST draw:caption %text-anchor;> +<!ATTLIST draw:caption draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:caption draw:corner-radius %nonNegativeLength; #IMPLIED> + +<!ELEMENT draw:measure ( office:events?, %draw-text;)> +<!ATTLIST draw:measure svg:x1 %coordinate; #REQUIRED> +<!ATTLIST draw:measure svg:y1 %coordinate; #REQUIRED> +<!ATTLIST draw:measure svg:x2 %coordinate; #REQUIRED> +<!ATTLIST draw:measure svg:y2 %coordinate; #REQUIRED> +<!ATTLIST draw:measure %draw-end-position; > +<!ATTLIST draw:measure %table-background; > +<!ATTLIST draw:measure %draw-style-name; > +<!ATTLIST draw:measure %draw-transform; > +<!ATTLIST draw:measure %zindex;> +<!ATTLIST draw:measure draw:id %draw-shape-id;> +<!ATTLIST draw:measure %text-anchor;> +<!ATTLIST draw:measure draw:layer %layerName; #IMPLIED> + +<!-- graphic style elements --> +<!ELEMENT draw:gradient EMPTY > +<!ATTLIST draw:gradient draw:name %styleName; #REQUIRED> +<!ATTLIST draw:gradient draw:style %gradient-style; #REQUIRED> +<!ATTLIST draw:gradient draw:cx %coordinate; #IMPLIED> +<!ATTLIST draw:gradient draw:cy %coordinate; #IMPLIED> +<!ATTLIST draw:gradient draw:start-color %color; #IMPLIED> +<!ATTLIST draw:gradient draw:end-color %color; #IMPLIED> +<!ATTLIST draw:gradient draw:start-intensity %percentage; #IMPLIED> +<!ATTLIST draw:gradient draw:end-intensity %percentage; #IMPLIED> +<!ATTLIST draw:gradient draw:angle %integer; #IMPLIED> +<!ATTLIST draw:gradient draw:border %percentage; #IMPLIED> + +<!ELEMENT draw:hatch EMPTY > +<!ATTLIST draw:hatch draw:name %styleName; #REQUIRED> +<!ATTLIST draw:hatch draw:style (single|double|triple) #REQUIRED > +<!ATTLIST draw:hatch draw:color %color; #IMPLIED> +<!ATTLIST draw:hatch draw:distance %length; #IMPLIED> +<!ATTLIST draw:hatch draw:rotation %integer; #IMPLIED> + + +<!ELEMENT draw:fill-image EMPTY > +<!ATTLIST draw:fill-image draw:name %styleName; #REQUIRED> +<!ATTLIST draw:fill-image xlink:href %uriReference; #REQUIRED> +<!ATTLIST draw:fill-image xlink:type (simple) #IMPLIED> +<!ATTLIST draw:fill-image xlink:show (embed) #IMPLIED> +<!ATTLIST draw:fill-image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:fill-image svg:width %length; #IMPLIED> +<!ATTLIST draw:fill-image svg:height %length; #IMPLIED> + +<!ELEMENT draw:transparency EMPTY> +<!ATTLIST draw:transparency draw:name %styleName; #REQUIRED> +<!ATTLIST draw:transparency draw:style %gradient-style; #REQUIRED> +<!ATTLIST draw:transparency draw:cx %coordinate; #IMPLIED> +<!ATTLIST draw:transparency draw:cy %coordinate; #IMPLIED> +<!ATTLIST draw:transparency draw:start %percentage; #IMPLIED> +<!ATTLIST draw:transparency draw:end %percentage; #IMPLIED> +<!ATTLIST draw:transparency draw:angle %integer; #IMPLIED> +<!ATTLIST draw:transparency draw:border %percentage; #IMPLIED> + +<!ELEMENT draw:marker EMPTY> +<!ATTLIST draw:marker draw:name %styleName; #REQUIRED> +<!ATTLIST draw:marker %draw-viewbox; > +<!ATTLIST draw:marker svg:d %pathData; #REQUIRED> + +<!ELEMENT draw:stroke-dash EMPTY> +<!ATTLIST draw:stroke-dash draw:name %styleName; #REQUIRED> +<!ATTLIST draw:stroke-dash draw:style (rect|round) #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots1 %integer; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots1-length %length; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots2 %integer; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:dots2-length %length; #IMPLIED> +<!ATTLIST draw:stroke-dash draw:distance %length; #IMPLIED> + +<!-- stroke attributes --> +<!ATTLIST style:properties draw:stroke (none|dash|solid) #IMPLIED> +<!ATTLIST style:properties draw:stroke-dash CDATA #IMPLIED> +<!ATTLIST style:properties svg:stroke-width %length; #IMPLIED> +<!ATTLIST style:properties svg:stroke-color %color; #IMPLIED> +<!ATTLIST style:properties draw:marker-start %styleName; #IMPLIED> +<!ATTLIST style:properties draw:marker-end %styleName; #IMPLIED> +<!ATTLIST style:properties draw:marker-start-width %length; #IMPLIED> +<!ATTLIST style:properties draw:marker-end-width %length; #IMPLIED> +<!ATTLIST style:properties draw:marker-start-center %boolean; #IMPLIED> +<!ATTLIST style:properties draw:marker-end-center %boolean; #IMPLIED> +<!ATTLIST style:properties svg:stroke-opacity %floatOrPercentage; #IMPLIED> +<!ATTLIST style:properties svg:stroke-linejoin (miter|round|bevel|middle|none|inherit) #IMPLIED> + +<!-- text attributes --> +<!ATTLIST style:properties draw:auto-grow-width %boolean; #IMPLIED> +<!ATTLIST style:properties draw:auto-grow-height %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fit-to-size %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fit-to-contour %boolean; #IMPLIED> +<!ATTLIST style:properties draw:textarea-horizontal-align ( left | center | right | justify ) #IMPLIED> +<!ATTLIST style:properties draw:textarea-vertical-align ( top | middle | bottom ) #IMPLIED> + +<!-- fill attributes --> +<!ATTLIST style:properties draw:fill (none|solid|bitmap|gradient|hatch) #IMPLIED> +<!ATTLIST style:properties draw:fill-color %color; #IMPLIED> +<!ATTLIST style:properties draw:fill-gradient-name %styleName; #IMPLIED> +<!ATTLIST style:properties draw:gradient-step-count CDATA #IMPLIED> +<!ATTLIST style:properties draw:fill-hatch-name %styleName; #IMPLIED> +<!ATTLIST style:properties draw:fill-hatch-solid %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-name %styleName; #IMPLIED> +<!ATTLIST style:properties style:repeat (no-repeat|repeat|stretch) #IMPLIED> +<!ATTLIST style:properties draw:fill-image-width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-ref-point-x %percentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-ref-point-y %percentage; #IMPLIED> +<!ATTLIST style:properties draw:fill-image-ref-point %rectanglePoint; #IMPLIED> +<!ATTLIST style:properties draw:tile-repeat-offset CDATA #IMPLIED> +<!ATTLIST style:properties draw:transparency %percentage; #IMPLIED> +<!ATTLIST style:properties draw:transparency-name %styleName; #IMPLIED> + +<!-- graphic attributes --> +<!ATTLIST style:properties draw:color-mode (greyscale|mono|watermark|standard) #IMPLIED> +<!ATTLIST style:properties draw:luminance %percentage; #IMPLIED> +<!ATTLIST style:properties draw:contrast %percentage; #IMPLIED> +<!ATTLIST style:properties draw:gamma %percentage; #IMPLIED> +<!ATTLIST style:properties draw:red %percentage; #IMPLIED> +<!ATTLIST style:properties draw:green %percentage; #IMPLIED> +<!ATTLIST style:properties draw:blue %percentage; #IMPLIED> +<!ATTLIST style:properties draw:color-inversion %boolean; #IMPLIED> + +<!-- shadow attributes --> +<!ATTLIST style:properties draw:shadow (visible|hidden) #IMPLIED> +<!ATTLIST style:properties draw:shadow-offset-x %length; #IMPLIED> +<!ATTLIST style:properties draw:shadow-offset-y %length; #IMPLIED> +<!ATTLIST style:properties draw:shadow-color %color; #IMPLIED> +<!ATTLIST style:properties draw:shadow-transparency CDATA #IMPLIED> + +<!-- connector attributes --> +<!ATTLIST style:properties draw:start-line-spacing-horizontal %distance; #IMPLIED> +<!ATTLIST style:properties draw:start-line-spacing-vertical %distance; #IMPLIED> +<!ATTLIST style:properties draw:end-line-spacing-horizontal %distance; #IMPLIED> +<!ATTLIST style:properties draw:end-line-spacing-vertical %distance; #IMPLIED> + +<!-- measure attributes --> +<!ATTLIST style:properties draw:line-distance %distance; #IMPLIED> +<!ATTLIST style:properties draw:guide-overhang %distance; #IMPLIED> +<!ATTLIST style:properties draw:guide-distance %distance; #IMPLIED> +<!ATTLIST style:properties draw:start-guide %distance; #IMPLIED> +<!ATTLIST style:properties draw:end-guide %distance; #IMPLIED> +<!ATTLIST style:properties draw:measure-align (automatic|left-outside|inside|right-outside) #IMPLIED> +<!ATTLIST style:properties draw:measure-vertical-align (automatic|above|below|center) #IMPLIED> +<!ATTLIST style:properties draw:unit (automatic|mm|cm|m|km|pt|pc|inch|ft|mi) #IMPLIED> +<!ATTLIST style:properties draw:show-unit %boolean; #IMPLIED> +<!ATTLIST style:properties draw:placing (below|above) #IMPLIED> +<!ATTLIST style:properties draw:parallel %boolean; #IMPLIED> + +<!-- frame attributes --> +<!ATTLIST style:properties draw:frame-display-scrollbar %boolean; #IMPLIED> +<!ATTLIST style:properties draw:frame-display-border %boolean; #IMPLIED> +<!ATTLIST style:properties draw:frame-margin-horizontal %nonNegativePixelLength; #IMPLIED> +<!ATTLIST style:properties draw:frame-margin-vertical %nonNegativePixelLength; #IMPLIED> +<!ATTLIST style:properties draw:size-protect %boolean; #IMPLIED> +<!ATTLIST style:properties draw:move-protect %boolean; #IMPLIED> + +<!-- ole object attributes --> +<!ATTLIST style:properties draw:visible-area-left %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties draw:visible-area-top %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties draw:visible-area-width %positiveLength; #IMPLIED> +<!ATTLIST style:properties draw:visible-area-height %positiveLength; #IMPLIED> + +<!-- fontwork attributes --> +<!ATTLIST style:properties draw:fontwork-style (rotate|upright|slant-x|slant-y|none) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-adjust (left|right|autosize|center) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-distance %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-start %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-mirror %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-outline %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow (normal|slant|none) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-color %color; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-offset-x %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-offset-y %distance; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-form (none|top-circle|bottom-circle|left-circle|right-circle|top-arc|bottom-arc|left-arc|right-arc|button1|button2|button3|button4) #IMPLIED> +<!ATTLIST style:properties draw:fontwork-hide-form %boolean; #IMPLIED> +<!ATTLIST style:properties draw:fontwork-shadow-transparence %percentage; #IMPLIED> + +<!-- caption attributes --> +<!ATTLIST style:properties draw:caption-type (straight-line|angled-line|angled-connector-line) #IMPLIED> +<!ATTLIST style:properties draw:caption-angle-type (fixed|free) #IMPLIED> +<!ATTLIST style:properties draw:caption-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties draw:caption-gap %distance; #IMPLIED> +<!ATTLIST style:properties draw:caption-escape-direction (horizontal|vertical|auto) #IMPLIED> +<!ATTLIST style:properties draw:caption-escape %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties draw:caption-line-length %distance; #IMPLIED> +<!ATTLIST style:properties draw:caption-fit-line-length %boolean; #IMPLIED> + +<!-- Animations --> +<!ELEMENT presentation:sound EMPTY> +<!ATTLIST presentation:sound xlink:href %uriReference; #REQUIRED> +<!ATTLIST presentation:sound xlink:type (simple) #FIXED "simple"> +<!ATTLIST presentation:sound xlink:show (new|replace) #IMPLIED> +<!ATTLIST presentation:sound xlink:actuate (onRequest) "onRequest"> +<!ATTLIST presentation:sound presentation:play-full %boolean; #IMPLIED> + +<!ELEMENT presentation:show-shape (presentation:sound)?> +<!ATTLIST presentation:show-shape draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:show-shape presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:show-shape presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:show-shape presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:show-shape presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:show-shape presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:show-text (presentation:sound)?> +<!ATTLIST presentation:show-text draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:show-text presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:show-text presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:show-text presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:show-text presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:show-text presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:hide-shape (presentation:sound)?> +<!ATTLIST presentation:hide-shape draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:hide-shape presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:hide-shape presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:hide-shape presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:hide-shape presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:hide-shape presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:hide-text (presentation:sound)?> +<!ATTLIST presentation:hide-text draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:hide-text presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:hide-text presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:hide-text presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:hide-text presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:hide-text presentation:path-id CDATA #IMPLIED > + +<!ELEMENT presentation:dim (presentation:sound)?> +<!ATTLIST presentation:dim draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:dim draw:color %color; #REQUIRED> + +<!ELEMENT presentation:play EMPTY> +<!ATTLIST presentation:play draw:shape-id CDATA #REQUIRED> +<!ATTLIST presentation:play presentation:speed %presentationSpeeds; "medium"> + +<!ELEMENT presentation:animations (presentation:show-shape|presentation:show-text|presentation:hide-shape|presentation:hide-text|presentation:dim|presentation:play)*> + +<!ELEMENT presentation:show EMPTY> +<!ATTLIST presentation:show presentation:name %styleName; #REQUIRED> +<!ATTLIST presentation:show presentation:pages CDATA #REQUIRED> + +<!ELEMENT presentation:settings (presentation:show)*> +<!ATTLIST presentation:settings presentation:start-page %styleName; #IMPLIED> +<!ATTLIST presentation:settings presentation:show %styleName; #IMPLIED> +<!ATTLIST presentation:settings presentation:full-screen %boolean; "true"> +<!ATTLIST presentation:settings presentation:endless %boolean; "false"> +<!ATTLIST presentation:settings presentation:pause %timeDuration; #IMPLIED> +<!ATTLIST presentation:settings presentation:show-logo %boolean; "false"> +<!ATTLIST presentation:settings presentation:force-manual %boolean; "false"> +<!ATTLIST presentation:settings presentation:mouse-visible %boolean; "true"> +<!ATTLIST presentation:settings presentation:mouse-as-pen %boolean; "false"> +<!ATTLIST presentation:settings presentation:start-with-navigator %boolean; "false"> +<!ATTLIST presentation:settings presentation:animations (enabled|disabled) "enabled"> +<!ATTLIST presentation:settings presentation:stay-on-top %boolean; "false"> +<!ATTLIST presentation:settings presentation:transition-on-click (enabled|disabled) "enabled"> + +<!-- Drawing page --> +<!ELEMENT draw:page (office:forms?,(%shapes;)*,presentation:animations?,presentation:notes?)> +<!ATTLIST draw:page draw:name %string; #IMPLIED> +<!ATTLIST draw:page draw:style-name %styleName; #IMPLIED> +<!ATTLIST draw:page draw:master-page-name %styleName; #REQUIRED> +<!ATTLIST draw:page presentation:presentation-page-layout-name %styleName; #IMPLIED> +<!ATTLIST draw:page draw:id %nonNegativeInteger; #IMPLIED> + +<!-- Presentation notes --> +<!ELEMENT presentation:notes (%shapes;)*> + + +<!-- presentation page layouts --> +<!ELEMENT style:presentation-page-layout (presentation:placeholder)* > +<!ATTLIST style:presentation-page-layout style:name %styleName; #REQUIRED> +<!ELEMENT presentation:placeholder EMPTY > +<!ATTLIST presentation:placeholder presentation:object (title|outline|subtitle|text|graphic|object|chart|orgchart|page|notes|handout) #REQUIRED> +<!ATTLIST presentation:placeholder svg:x %coordinateOrPercentage; #REQUIRED> +<!ATTLIST presentation:placeholder svg:y %coordinateOrPercentage; #REQUIRED> +<!ATTLIST presentation:placeholder svg:width %lengthOrPercentage; #REQUIRED> +<!ATTLIST presentation:placeholder svg:height %lengthOrPercentage; #REQUIRED> + +<!-- presentation page attributes --> +<!ATTLIST style:properties presentation:transition-type (manual|automatic|semi-automatic) #IMPLIED > +<!ATTLIST style:properties presentation:transition-style (none|fade-from-left|fade-from-top|fade-from-right|fade-from-bottom|fade-to-center|fade-from-center|move-from-left|move-from-top|move-from-right|move-from-bottom|roll-from-top|roll-from-left|roll-from-right|roll-from-bottom|vertical-stripes|horizontal-stripes|clockwise|counterclockwise|fade-from-upperleft|fade-from-upperright|fade-from-lowerleft|fade-from-lowerright|close-vertical|close-horizontal|open-vertical|open-horizontal|spiralin-left|spiralin-right|spiralout-left|spiralout-right|dissolve|wavyline-from-left|wavyline-from-top|wavyline-from-right|wavyline-from-bottom|random|stretch-from-left|stretch-from-top|stretch-from-right|stretch-from-bottom|vertical-lines|horizontal-lines) #IMPLIED > +<!ATTLIST style:properties presentation:transition-speed %presentationSpeeds; #IMPLIED > +<!ATTLIST style:properties presentation:duration %timeDuration; #IMPLIED> +<!ATTLIST style:properties presentation:visibility (visible|hidden) #IMPLIED> +<!ATTLIST style:properties draw:background-size (full|border) #IMPLIED> +<!ATTLIST style:properties presentation:background-objects-visible %boolean; #IMPLIED> +<!ATTLIST style:properties presentation:background-visible %boolean; #IMPLIED> + + +<!-- text boxes --> +<!ELEMENT draw:text-box (office:events?,draw:image-map?, + (text:h|text:p|text:ordered-list| + text:unordered-list|table:table|chart:chart| + draw:a|draw:text-box|draw:image)*)> +<!ATTLIST draw:text-box %draw-style-name;> +<!ATTLIST draw:text-box %draw-transform; > +<!ATTLIST draw:text-box draw:name %string; #IMPLIED> +<!ATTLIST draw:text-box draw:chain-next-name %string; #IMPLIED> + +<!ATTLIST draw:text-box %text-anchor;> +<!ATTLIST draw:text-box %draw-position;> +<!ATTLIST draw:text-box %draw-end-position; > +<!ATTLIST draw:text-box %table-background; > +<!ATTLIST draw:text-box svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:text-box svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:text-box fo:min-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:text-box %zindex;> +<!ATTLIST draw:text-box %presentation-class; > +<!ATTLIST draw:text-box %draw-transform; > +<!ATTLIST draw:text-box draw:id %draw-shape-id;> +<!ATTLIST draw:text-box draw:layer %layerName; #IMPLIED> + +<!-- image --> +<!ELEMENT draw:image (office:binary-data?,office:events?,draw:image-map?,svg:desc?,(draw:contour-polygon|draw:contour-path)?)> +<!ATTLIST draw:image %draw-style-name;> +<!ATTLIST draw:image draw:name %string; #IMPLIED> +<!ATTLIST draw:image xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:image xlink:type (simple) #IMPLIED> +<!ATTLIST draw:image xlink:show (embed) #IMPLIED> +<!ATTLIST draw:image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:image draw:filter-name %string; #IMPLIED> +<!ATTLIST draw:image %text-anchor;> +<!ATTLIST draw:image %draw-position;> +<!ATTLIST draw:image %draw-end-position; > +<!ATTLIST draw:image %table-background; > +<!ATTLIST draw:image svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:image svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:image %presentation-class; > +<!ATTLIST draw:image %zindex;> +<!ATTLIST draw:image draw:id %draw-shape-id;> +<!ATTLIST draw:image draw:layer %layerName; #IMPLIED> + +<!-- objects --> +<!ELEMENT draw:thumbnail EMPTY> +<!ATTLIST draw:thumbnail xlink:href %uriReference; #REQUIRED> +<!ATTLIST draw:thumbnail xlink:type (simple) #IMPLIED> +<!ATTLIST draw:thumbnail xlink:show (embed) #IMPLIED> +<!ATTLIST draw:thumbnail xlink:actuate (onLoad) #IMPLIED> + +<!ELEMENT math:math ANY> <!-- dummy (we have no MathML DTD currently)--> +<!ELEMENT draw:object (draw:thumbnail?,(office:document|math:math)?,office:events?, draw:image-map?, svg:desc?,(draw:contour-polygon|draw:contour-path)?)> +<!ATTLIST draw:object %draw-style-name;> +<!ATTLIST draw:object draw:name %string; #IMPLIED> +<!ATTLIST draw:object xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:object xlink:type (simple) #IMPLIED> +<!ATTLIST draw:object xlink:show (embed) #IMPLIED> +<!ATTLIST draw:object xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:object %text-anchor;> +<!ATTLIST draw:object %draw-position;> +<!ATTLIST draw:object %draw-end-position; > +<!ATTLIST draw:object %table-background; > +<!ATTLIST draw:object svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object %presentation-class; > +<!ATTLIST draw:object %zindex;> +<!ATTLIST draw:object draw:id %draw-shape-id;> +<!ATTLIST draw:object draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:object draw:notify-on-update-of-ranges %string; #IMPLIED> + +<!ELEMENT draw:object-ole (office:binary-data?|office:events?|draw:image-map?|svg:desc?|draw:contour-polygon?|draw:contour-path?|draw:thumbnail?)> +<!ATTLIST draw:object-ole draw:class-id CDATA #IMPLIED> +<!ATTLIST draw:object-ole %draw-style-name;> +<!ATTLIST draw:object-ole draw:name %string; #IMPLIED> +<!ATTLIST draw:object-ole xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:object-ole xlink:type (simple) #IMPLIED> +<!ATTLIST draw:object-ole xlink:show (embed) #IMPLIED> +<!ATTLIST draw:object-ole xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:object-ole %text-anchor;> +<!ATTLIST draw:object-ole %draw-position;> +<!ATTLIST draw:object-ole %draw-end-position; > +<!ATTLIST draw:object-ole %table-background; > +<!ATTLIST draw:object-ole svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object-ole svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:object-ole %presentation-class; > +<!ATTLIST draw:object-ole %zindex;> +<!ATTLIST draw:object-ole draw:id %draw-shape-id;> +<!ATTLIST draw:object-ole draw:layer %layerName; #IMPLIED> + +<!ELEMENT svg:desc (#PCDATA)> + +<!ELEMENT draw:contour-polygon EMPTY> +<!ATTLIST draw:contour-polygon svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:contour-polygon svg:height %coordinate; #REQUIRED> +<!ATTLIST draw:contour-polygon %draw-viewbox;> +<!ATTLIST draw:contour-polygon svg:points %points; #REQUIRED> + +<!ELEMENT draw:contour-path EMPTY> +<!ATTLIST draw:contour-path svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:contour-path svg:height %coordinate; #REQUIRED> +<!ATTLIST draw:contour-path %draw-viewbox;> +<!ATTLIST draw:contour-path svg:d %pathData; #REQUIRED> + +<!-- hyperlink --> +<!ELEMENT draw:a (draw:image|draw:text-box)> +<!ATTLIST draw:a xlink:href %uriReference; #REQUIRED> +<!ATTLIST draw:a xlink:type (simple) #FIXED "simple"> +<!ATTLIST draw:a xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:a xlink:actuate (onRequest) "onRequest"> +<!ATTLIST draw:a office:name %string; #IMPLIED> +<!ATTLIST draw:a office:target-frame-name %string; #IMPLIED> +<!ATTLIST draw:a office:server-map %boolean; "false"> + +<!-- 3d properties --> +<!ATTLIST style:properties dr3d:horizontal-segments %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties dr3d:vertical-segments %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties dr3d:edge-rounding %percentage; #IMPLIED> +<!ATTLIST style:properties dr3d:edge-rounding-mode (correct|attractive) #IMPLIED> +<!ATTLIST style:properties dr3d:back-scale %percentage; #IMPLIED> +<!ATTLIST style:properties dr3d:end-angle %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties dr3d:depth %length; #IMPLIED> +<!ATTLIST style:properties dr3d:backface-culling (enabled|disabled) #IMPLIED> +<!ATTLIST style:properties dr3d:lighting-mode (standard|double-sided) #IMPLIED> +<!ATTLIST style:properties dr3d:normals-kind (object|flat|sphere) #IMPLIED> +<!ATTLIST style:properties dr3d:normals-direction (normal|inverse) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-generation-mode-x (object|parallel|sphere) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-generation-mode-y (object|parallel|sphere) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-kind (luminance|intesity|color) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-filter (enabled|disabled) #IMPLIED> +<!ATTLIST style:properties dr3d:texture-mode (replace|modulate|blend) #IMPLIED> +<!ATTLIST style:properties dr3d:ambient-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:emissive-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:specular-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:diffuse-color %color; #IMPLIED> +<!ATTLIST style:properties dr3d:shininess %percentage; #IMPLIED> +<!ATTLIST style:properties dr3d:shadow (visible|hidden) #IMPLIED> + +<!ELEMENT dr3d:light EMPTY> +<!ATTLIST dr3d:light dr3d:diffuse-color %color; #IMPLIED> +<!ATTLIST dr3d:light dr3d:direction %vector3D; #REQUIRED> +<!ATTLIST dr3d:light dr3d:enabled %boolean; #IMPLIED> +<!ATTLIST dr3d:light dr3d:specular %boolean; #IMPLIED> + +<!ENTITY % shapes3d "(dr3d:scene|dr3d:extrude|dr3d:sphere|dr3d:rotate|dr3d:cube)"> + +<!ELEMENT dr3d:cube EMPTY> +<!ATTLIST dr3d:cube dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:cube dr3d:min-edge %vector3D; #IMPLIED> +<!ATTLIST dr3d:cube dr3d:max-edge %vector3D; #IMPLIED> +<!ATTLIST dr3d:cube %zindex;> +<!ATTLIST dr3d:cube draw:id %draw-shape-id;> +<!ATTLIST dr3d:cube %draw-end-position; > +<!ATTLIST dr3d:cube %table-background; > +<!ATTLIST dr3d:cube %draw-style-name; > +<!ATTLIST dr3d:cube draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:sphere EMPTY> +<!ATTLIST dr3d:sphere dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:sphere dr3d:center %vector3D; #IMPLIED> +<!ATTLIST dr3d:sphere dr3d:size %vector3D; #IMPLIED> +<!ATTLIST dr3d:sphere %zindex;> +<!ATTLIST dr3d:sphere draw:id %draw-shape-id;> +<!ATTLIST dr3d:sphere %draw-end-position; > +<!ATTLIST dr3d:sphere %table-background; > +<!ATTLIST dr3d:sphere %draw-style-name; > +<!ATTLIST dr3d:sphere draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:extrude EMPTY> +<!ATTLIST dr3d:extrude dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:extrude %draw-viewbox;> +<!ATTLIST dr3d:extrude svg:d %pathData; #REQUIRED > +<!ATTLIST dr3d:extrude %zindex;> +<!ATTLIST dr3d:extrude draw:id %draw-shape-id;> +<!ATTLIST dr3d:extrude %draw-end-position; > +<!ATTLIST dr3d:extrude %table-background; > +<!ATTLIST dr3d:extrude %draw-style-name; > +<!ATTLIST dr3d:extrude draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:rotate EMPTY> +<!ATTLIST dr3d:rotate dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:rotate %draw-viewbox;> +<!ATTLIST dr3d:rotate svg:d %pathData; #REQUIRED > +<!ATTLIST dr3d:rotate %zindex;> +<!ATTLIST dr3d:rotate draw:id %draw-shape-id;> +<!ATTLIST dr3d:rotate %draw-end-position; > +<!ATTLIST dr3d:rotate %table-background; > +<!ATTLIST dr3d:rotate %draw-style-name; > +<!ATTLIST dr3d:rotate draw:layer %layerName; #IMPLIED> + +<!ELEMENT dr3d:scene (dr3d:light*,(%shapes3d;)*)> +<!ATTLIST dr3d:scene %draw-style-name; > +<!ATTLIST dr3d:scene svg:x %coordinate; #IMPLIED> +<!ATTLIST dr3d:scene svg:y %coordinate; #IMPLIED> +<!ATTLIST dr3d:scene svg:width %length; #IMPLIED> +<!ATTLIST dr3d:scene svg:height %length; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:vrp %vector3D; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:vpn %vector3D; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:vup %vector3D; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:projection (parallel|perspective) #IMPLIED> +<!ATTLIST dr3d:scene dr3d:transform CDATA #IMPLIED> +<!ATTLIST dr3d:scene dr3d:distance %length; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:focal-length %length; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:shadow-slant %nonNegativeInteger; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:shade-mode (flat|phong|gouraud|draft) #IMPLIED> +<!ATTLIST dr3d:scene dr3d:ambient-color %color; #IMPLIED> +<!ATTLIST dr3d:scene dr3d:lighting-mode %boolean; #IMPLIED> +<!ATTLIST dr3d:scene %zindex;> +<!ATTLIST dr3d:scene draw:id %draw-shape-id;> +<!ATTLIST dr3d:scene %draw-end-position; > +<!ATTLIST dr3d:scene %table-background; > + +<!-- layer --> + +<!ELEMENT draw:layer-set (draw:layer*)> + +<!ELEMENT draw:layer EMPTY> +<!ATTLIST draw:layer draw:name %layerName; #REQUIRED> + +<!-- events --> +<!ELEMENT presentation:event (presentation:sound)?> +<!ATTLIST presentation:event %event-name;> +<!ATTLIST presentation:event presentation:action (none|previous-page|next-page|first-page|last-page|hide|stop|execute|show|verb|fade-out|sound) #REQUIRED> +<!ATTLIST presentation:event presentation:effect %presentationEffects; "none"> +<!ATTLIST presentation:event presentation:direction %presentationEffectDirections; "none"> +<!ATTLIST presentation:event presentation:speed %presentationSpeeds; "medium"> +<!ATTLIST presentation:event presentation:start-scale %percentage; "100%"> +<!ATTLIST presentation:event xlink:href %uriReference; #IMPLIED> +<!ATTLIST presentation:event xlink:type (simple) #IMPLIED> +<!ATTLIST presentation:event xlink:show (embed) #IMPLIED> +<!ATTLIST presentation:event xlink:actuate (onRequest) #IMPLIED> +<!ATTLIST presentation:event presentation:verb %nonNegativeInteger; #IMPLIED> + +<!-- applets --> +<!ELEMENT draw:applet (draw:thumbnail?, draw:param*, svg:desc?)> +<!ATTLIST draw:applet xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:applet xlink:type (simple) #IMPLIED> +<!ATTLIST draw:applet xlink:show (embed) #IMPLIED> +<!ATTLIST draw:applet xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:applet draw:code CDATA #REQUIRED> +<!ATTLIST draw:applet draw:object CDATA #IMPLIED> +<!ATTLIST draw:applet draw:archive CDATA #IMPLIED> +<!ATTLIST draw:applet draw:may-script %boolean; "false"> +<!ATTLIST draw:applet draw:name CDATA #IMPLIED> +<!ATTLIST draw:applet %draw-style-name;> +<!ATTLIST draw:applet svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:applet svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:applet %zindex;> +<!ATTLIST draw:applet draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:applet %draw-position;> +<!ATTLIST draw:applet %draw-end-position; > + +<!-- plugins --> +<!ELEMENT draw:plugin (draw:thumbnail?, draw:param*, svg:desc?)> +<!ATTLIST draw:plugin xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:plugin xlink:type (simple) #IMPLIED> +<!ATTLIST draw:plugin xlink:show (embed) #IMPLIED> +<!ATTLIST draw:plugin xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:plugin draw:mime-type CDATA #IMPLIED> +<!ATTLIST draw:plugin draw:name CDATA #IMPLIED> +<!ATTLIST draw:plugin %draw-style-name;> +<!ATTLIST draw:plugin svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:plugin svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:plugin %zindex;> +<!ATTLIST draw:plugin draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:plugin %draw-position;> +<!ATTLIST draw:plugin %draw-end-position; > + +<!-- Paramaters --> +<!ELEMENT draw:param EMPTY> +<!ATTLIST draw:param draw:name CDATA #IMPLIED> +<!ATTLIST draw:param draw:value CDATA #IMPLIED> + +<!-- Floating Frames --> +<!ELEMENT draw:floating-frame (draw:thumbnail?, svg:desc?)> +<!ATTLIST draw:floating-frame xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:floating-frame xlink:type (simple) #IMPLIED> +<!ATTLIST draw:floating-frame xlink:show (embed) #IMPLIED> +<!ATTLIST draw:floating-frame xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST draw:floating-frame draw:name CDATA #IMPLIED> +<!ATTLIST draw:floating-frame draw:frame-name CDATA #IMPLIED> +<!ATTLIST draw:floating-frame %draw-style-name;> +<!ATTLIST draw:floating-frame svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:floating-frame svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST draw:floating-frame %zindex;> +<!ATTLIST draw:floating-frame draw:layer %layerName; #IMPLIED> +<!ATTLIST draw:floating-frame %draw-position;> +<!ATTLIST draw:floating-frame %draw-end-position; > + +<!-- Image Maps --> +<!ELEMENT draw:image-map + (draw:area-rectangle|draw:area-circle|draw:area-polygon)*> + +<!ELEMENT draw:area-rectangle (svg:desc?,office:events?)> +<!ATTLIST draw:area-rectangle xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:area-rectangle xlink:type (simple) #IMPLIED> +<!ATTLIST draw:area-rectangle office:target-frame-name CDATA #IMPLIED> +<!ATTLIST draw:area-rectangle xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:area-rectangle office:name CDATA #IMPLIED> +<!ATTLIST draw:area-rectangle draw:nohref (nohref) #IMPLIED> +<!ATTLIST draw:area-rectangle svg:x %coordinate; #REQUIRED> +<!ATTLIST draw:area-rectangle svg:y %coordinate; #REQUIRED> +<!ATTLIST draw:area-rectangle svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:area-rectangle svg:height %coordinate; #REQUIRED> + +<!ELEMENT draw:area-circle (svg:desc?,office:events?)> +<!ATTLIST draw:area-circle xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:area-circle xlink:type (simple) #IMPLIED> +<!ATTLIST draw:area-circle office:target-frame-name CDATA #IMPLIED> +<!ATTLIST draw:area-circle xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:area-circle office:name CDATA #IMPLIED> +<!ATTLIST draw:area-circle draw:nohref (nohref) #IMPLIED> +<!ATTLIST draw:area-circle svg:cx %coordinate; #REQUIRED> +<!ATTLIST draw:area-circle svg:cy %coordinate; #REQUIRED> +<!ATTLIST draw:area-circle svg:r %coordinate; #REQUIRED> + +<!ELEMENT draw:area-polygon (svg:desc?,office:events?)> +<!ATTLIST draw:area-polygon xlink:href %uriReference; #IMPLIED> +<!ATTLIST draw:area-polygon xlink:type (simple) #IMPLIED> +<!ATTLIST draw:area-polygon office:target-frame-name CDATA #IMPLIED> +<!ATTLIST draw:area-polygon xlink:show (new|replace) #IMPLIED> +<!ATTLIST draw:area-polygon office:name CDATA #IMPLIED> +<!ATTLIST draw:area-polygon draw:nohref (nohref) #IMPLIED> +<!ATTLIST draw:area-polygon svg:x %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:y %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:width %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:height %coordinate; #REQUIRED> +<!ATTLIST draw:area-polygon svg:points %points; #REQUIRED> +<!ATTLIST draw:area-polygon svg:viewBox CDATA #REQUIRED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/dtypes.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/dtypes.mod new file mode 100644 index 000000000000..1cdd7bf50785 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/dtypes.mod @@ -0,0 +1,147 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: dtypes.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!-- datatypes corresponding to XML Schema Part 2 W3C Working draft of --> +<!-- 07 April 2000 --> + +<!-- string --> +<!ENTITY % string "CDATA"> +<!ENTITY % cString "#PCDATA"> + +<!-- boolean (values are "true" and "false" --> +<!ENTITY % boolean "CDATA"> + +<!-- integer ( ..., -2, -1, 0, 1, 2, ...) --> +<!ENTITY % integer "CDATA"> + +<!-- non negative integer ( 0, 1, 2, ...) --> +<!ENTITY % nonNegativeInteger "CDATA"> + +<!-- positive integer ( 1, 2, ...) --> +<!ENTITY % positiveInteger "CDATA"> +<!ENTITY % cPositiveInteger "#PCDATA"> + +<!ENTITY % positiveNumberOrDefault "CDATA"> + +<!-- time duration as specified by ISO8601, section 5.5.3.2 --> +<!ENTITY % timeDuration "CDATA"> +<!ENTITY % cTimeDuration "#PCDATA"> + +<!-- time instance as specified by ISO8601, section 5.4 --> +<!ENTITY % timeInstance "CDATA"> +<!ENTITY % cTimeInstance "#PCDATA"> + +<!-- date instance as specified by ISO8601, section 5.2.1.1, extended format--> +<!ENTITY % date "CDATA"> +<!ENTITY % cDate "#PCDATA"> + +<!-- date duration, like timDuration but truncated to full dates --> +<!ENTITY % dateDuration "CDATA"> +<!ENTITY % cDateDuration "#PCDATA"> + +<!-- URI reference --> +<!ENTITY % uriReference "CDATA"> + +<!-- language code as specified by RFC1766 --> +<!ENTITY % language "CDATA"> +<!ENTITY % cLanguage "#PCDATA"> + +<!-- float --> +<!ENTITY % float "CDATA"> + +<!-- Some other common used data types --> + +<!-- a single UNICODE character --> +<!ENTITY % character "CDATA"> + +<!-- a style name --> +<!ENTITY % styleName "CDATA"> + +<!-- a target frame mame --> +<!ENTITY % targetFrameName "CDATA"> + +<!-- a language without a country as specified by ISO639 --> +<!ENTITY % languageOnly "CDATA"> + +<!-- a country as specified by ISO3166 --> +<!ENTITY % country "CDATA"> + +<!-- a color value having the format #rrggbb --> +<!ENTITY % color "CDATA"> +<!-- a color value having the format #rrggbb or "transparent" --> +<!ENTITY % transparentOrColor "CDATA"> + +<!-- a percentage --> +<!ENTITY % percentage "CDATA"> + +<!-- a length (i.e. 1cm or .6inch) --> +<!ENTITY % length "CDATA"> +<!ENTITY % positiveLength "CDATA"> +<!ENTITY % nonNegativeLength "CDATA"> +<!ENTITY % lengthOrNoLimit "CDATA"> + +<!-- a length or a percentage --> +<!ENTITY % lengthOrPercentage "CDATA"> +<!ENTITY % positiveLengthOrPercentage "CDATA"> + +<!-- a pixel length (i.e. 2px) --> +<!ENTITY % nonNegativePixelLength "CDATA"> + +<!-- a float or a percentage --> +<!ENTITY % floatOrPercentage "CDATA"> + +<!-- a text encoding --> +<!ENTITY % textEncoding "CDATA"> + +<!-- cell address and cell range address --> +<!ENTITY % cell-address "CDATA"> +<!ENTITY % cell-range-address "CDATA"> +<!ENTITY % cell-range-address-list "CDATA"> + +<!-- value types --> +<!ENTITY % valueType "(float|time|date|percentage|currency|boolean|string)"> + +<!-- an svg coordinate in different distance formats --> +<!ENTITY % coordinate "CDATA"> + +<!ENTITY % coordinateOrPercentage "CDATA"> + +<!ENTITY % shape "draw:rect|draw:line|draw:polyline|draw:polygon|draw:path| + draw:circle|draw:ellipse|draw:g|draw:page-thumbnail| + draw:text-box|draw:image|draw:object|draw:object-ole| + draw:applet|draw:floating-frame|draw:plugin| + draw:measure|draw:caption|draw:connector|chart:chart| + dr3d:scene|draw:control" > +<!ENTITY % shapes "(%shape;)" > + +<!ENTITY % anchorType "(page|frame|paragraph|char|as-char)"> + +<!ENTITY % control-id "form:id CDATA #REQUIRED"> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/form.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/form.mod new file mode 100644 index 000000000000..7c39fe5fd43b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/form.mod @@ -0,0 +1,312 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: form.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % controls "form:text|form:textarea|form:fixed-text|form:file| + form:password|form:formatted-text|form:button|form:image| + form:checkbox|form:radio|form:listbox|form:combobox|form:frame| + form:hidden|form:image-frame|form:grid|form:generic-control"> + +<!ENTITY % name "form:name CDATA #IMPLIED"> +<!ENTITY % service-name "form:service-name CDATA #IMPLIED"> + +<!ENTITY % navigation "(none|current|parent)"> +<!ENTITY % cycles "(records|current|page)"> +<!ENTITY % url "CDATA"> + + +<!ENTITY % types "(submit|reset|push|url)"> +<!ENTITY % button-type "form:button-type %types; 'push'"> +<!ENTITY % current-selected "form:current-selected %boolean; 'false'"> +<!ENTITY % current-value "form:current-value CDATA #IMPLIED"> +<!ENTITY % value "form:value CDATA #IMPLIED"> +<!ENTITY % disabled "form:disabled %boolean; 'false'"> +<!ENTITY % dropdown "form:dropdown %boolean; 'false'"> +<!ENTITY % for "form:for CDATA #IMPLIED"> +<!ENTITY % image-data "form:image-data %url; #IMPLIED"> +<!ENTITY % label "form:label CDATA #IMPLIED"> +<!ENTITY % max-length "form:max-length CDATA #IMPLIED"> +<!ENTITY % printable "form:printable %boolean; 'true'"> +<!ENTITY % readonly "form:readonly %boolean; 'false'"> +<!ENTITY % size "form:size CDATA #IMPLIED"> +<!ENTITY % selected "form:selected %boolean; 'false'"> +<!ENTITY % size "form:size CDATA #IMPLIED"> +<!ENTITY % tab-index "form:tab-index CDATA #IMPLIED"> +<!ENTITY % target-frame "office:target-frame CDATA '_blank'"> +<!ENTITY % target-location "xlink:href %url; #IMPLIED"> +<!ENTITY % tab-stop "form:tab-stop %boolean; 'true'"> +<!ENTITY % title "form:title CDATA #IMPLIED"> +<!ENTITY % default-value "form:default-value CDATA #IMPLIED"> +<!ENTITY % bound-column "form:bound-column CDATA #IMPLIED"> +<!ENTITY % convert-empty "form:convert-empty-to-null %boolean; 'false'"> +<!ENTITY % data-field "form:data-field CDATA #IMPLIED"> +<!ENTITY % list-source "form:list-source CDATA #IMPLIED"> +<!ENTITY % list-source-types "(table|query|sql|sql-pass-through|value-list|table-fields)"> +<!ENTITY % list-source-type "form:list-source-type %list-source-types; #IMPLIED"> + +<!ELEMENT form:control (%controls;)+> +<!ATTLIST form:control %name; + %service-name; + %control-id;> + +<!ELEMENT form:form (form:properties?, office:events?, (form:control|form:form)*)> +<!ATTLIST form:form %name; %service-name;> +<!ATTLIST form:form xlink:href %url; #IMPLIED> +<!ATTLIST form:form form:enctype CDATA "application/x-www-form-urlencoded"> +<!ATTLIST form:form form:method CDATA "get"> +<!ATTLIST form:form office:target-frame CDATA "_blank"> +<!ATTLIST form:form form:allow-deletes %boolean; "true"> +<!ATTLIST form:form form:allow-inserts %boolean; "true"> +<!ATTLIST form:form form:allow-updates %boolean; "true"> +<!ATTLIST form:form form:apply-filter %boolean; "false"> +<!ATTLIST form:form form:command CDATA #IMPLIED> +<!ATTLIST form:form form:command-type (table|query|command) "command"> +<!ATTLIST form:form form:datasource CDATA #IMPLIED> +<!ATTLIST form:form form:detail-fields CDATA #IMPLIED> +<!ATTLIST form:form form:escape-processing %boolean; "true"> +<!ATTLIST form:form form:filter CDATA #IMPLIED> +<!ATTLIST form:form form:ignore-result %boolean; "false"> +<!ATTLIST form:form form:master-fields CDATA #IMPLIED> +<!ATTLIST form:form form:navigation-mode %navigation; #IMPLIED> +<!ATTLIST form:form form:order CDATA #IMPLIED> +<!ATTLIST form:form form:tab-cycle %cycles; #IMPLIED> + +<!ELEMENT office:forms (form:form*)> +<!ATTLIST office:forms form:automatic-focus %boolean; "false"> +<!ATTLIST office:forms form:apply-design-mode %boolean; "true"> + +<!ELEMENT form:text (form:properties?, office:events?)> +<!ATTLIST form:text %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field;> + +<!ELEMENT form:textarea (form:properties?, office:events?)> +<!ATTLIST form:textarea %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field;> + +<!ELEMENT form:password (form:properties?, office:events?)> +<!ATTLIST form:password %disabled; + %max-length; + %printable; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty;> + +<!ATTLIST form:password form:echo-char CDATA "*"> + +<!ELEMENT form:file (form:properties?, office:events?)> +<!ATTLIST form:file %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value;> + +<!ELEMENT form:formatted-text (form:properties?, office:events?)> +<!ATTLIST form:formatted-text %current-value; + %disabled; + %max-length; + %printable; + %readonly; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field;> +<!ATTLIST form:formatted-text form:max-value CDATA #IMPLIED> +<!ATTLIST form:formatted-text form:min-value CDATA #IMPLIED> +<!ATTLIST form:formatted-text form:validation %boolean; "false"> + +<!ELEMENT form:fixed-text (form:properties?, office:events?)> +<!ATTLIST form:fixed-text %for; + %disabled; + %label; + %printable; + %title;> +<!ATTLIST form:fixed-text form:multi-line %boolean; "false"> + +<!ELEMENT form:combobox (form:properties?, office:events?, form:item*)> +<!ATTLIST form:combobox %current-value; + %disabled; + %dropdown; + %max-length; + %printable; + %readonly; + %size; + %tab-index; + %tab-stop; + %title; + %value; + %convert-empty; + %data-field; + %list-source; + %list-source-type;> +<!ATTLIST form:combobox form:auto-complete %boolean; #IMPLIED> + +<!ELEMENT form:item (#PCDATA)> +<!ATTLIST form:item %label;> + +<!ELEMENT form:listbox (form:properties?, office:events?, form:option*)> +<!ATTLIST form:listbox %disabled; + %dropdown; + %printable; + %size; + %tab-index; + %tab-stop; + %title; + %bound-column; + %data-field; + %list-source; + %list-source-type;> +<!ATTLIST form:listbox form:multiple %boolean; "false"> + +<!ELEMENT form:option (#PCDATA)> +<!ATTLIST form:option %current-selected; + %selected; + %label; + %value;> + +<!ELEMENT form:button (form:properties?, office:events?)> +<!ATTLIST form:button %button-type; + %disabled; + %label; + %image-data; + %printable; + %tab-index; + %tab-stop; + %target-frame; + %target-location; + %title; + %value;> +<!ATTLIST form:button form:default-button %boolean; "false"> + +<!ELEMENT form:image (form:properties?, office:events?)> +<!ATTLIST form:image %button-type; + %disabled; + %image-data; + %printable; + %tab-index; + %tab-stop; + %target-frame; + %target-location; + %title; + %value;> + +<!ELEMENT form:checkbox (form:properties?, office:events?)> +<!ATTLIST form:checkbox %disabled; + %label; + %printable; + %tab-index; + %tab-stop; + %title; + %value; + %data-field;> +<!ENTITY % states "(unchecked|checked|unknown)"> +<!ATTLIST form:checkbox form:current-state %states; #IMPLIED> +<!ATTLIST form:checkbox form:is-tristate %boolean; "false"> +<!ATTLIST form:checkbox form:state %states; "unchecked"> + +<!ELEMENT form:radio (form:properties?, office:events?)> +<!ATTLIST form:radio %current-selected; + %disabled; + %label; + %printable; + %selected; + %tab-index; + %tab-stop; + %title; + %value; + %data-field;> + +<!ELEMENT form:frame (form:properties?, office:events?)> +<!ATTLIST form:frame %disabled; + %for; + %label; + %printable; + %title;> + +<!ELEMENT form:image-frame (form:properties?, office:events?)> +<!ATTLIST form:image-frame %disabled; + %image-data; + %printable; + %readonly; + %title; + %data-field;> + +<!ELEMENT form:hidden (form:properties?, office:events?)> +<!ATTLIST form:hidden %name; + %service-name; + %value;> + +<!ELEMENT form:grid (form:properties?, office:events?, form:column*)> +<!ATTLIST form:grid %disabled; + %printable; + %tab-index; + %tab-stop; + %title;> +<!ENTITY % column-type "form:text| form:textarea| form:formatted-text|form:checkbox| form:listbox| form:combobox"> +<!ELEMENT form:column (%column-type;)+> +<!ATTLIST form:column %name; + %service-name; + %label;> + +<!ELEMENT form:generic-control (form:properties?, office:events?)> + + +<!ELEMENT form:properties (form:property+)> +<!ELEMENT form:property (form:property-value*)> +<!ATTLIST form:property form:property-is-list %boolean; #IMPLIED> +<!ATTLIST form:property form:property-name CDATA #REQUIRED> +<!ATTLIST form:property form:property-type (boolean|short|int|long|double|string) #REQUIRED> +<!ELEMENT form:property-value (#PCDATA)> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/meta.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/meta.mod new file mode 100644 index 000000000000..0bef2535bcbf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/meta.mod @@ -0,0 +1,94 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: meta.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + +<!ELEMENT meta:generator (%cString;)> + +<!ELEMENT dc:title (%cString;)> + +<!ELEMENT dc:description (%cString;)> + +<!ELEMENT dc:subject (%cString;)> + +<!ELEMENT meta:keywords (meta:keyword)*> +<!ELEMENT meta:keyword (%cString;)> + +<!ELEMENT meta:initial-creator (%cString;)> + +<!ELEMENT dc:creator (%cString;)> + +<!ELEMENT meta:printed-by (%cString;)> + +<!ELEMENT meta:creation-date (%cTimeInstance;)> + +<!ELEMENT dc:date (%cTimeInstance;)> + +<!ELEMENT meta:print-date (%cTimeInstance;)> + +<!ELEMENT meta:template EMPTY> +<!ATTLIST meta:template xlink:type (simple) #FIXED "simple"> +<!ATTLIST meta:template xlink:actuate (onRequest) "onRequest"> +<!ATTLIST meta:template xlink:href %uriReference; #REQUIRED> +<!ATTLIST meta:template xlink:title %string; #IMPLIED> +<!ATTLIST meta:template meta:date %timeInstance; #IMPLIED> + +<!ELEMENT meta:auto-reload EMPTY> +<!ATTLIST meta:auto-reload xlink:type (simple) #IMPLIED> +<!ATTLIST meta:auto-reload xlink:show (replace) #IMPLIED> +<!ATTLIST meta:auto-reload xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST meta:auto-reload xlink:href %uriReference; #IMPLIED> +<!ATTLIST meta:auto-reload meta:delay %timeDuration; "P0S"> + +<!ELEMENT meta:hyperlink-behaviour EMPTY> +<!ATTLIST meta:hyperlink-behaviour office:target-frame-name %targetFrameName; #IMPLIED> +<!ATTLIST meta:hyperlink-behaviour xlink:show (new|replace) #IMPLIED> + +<!ELEMENT dc:language (%cLanguage;)> + +<!ELEMENT meta:editing-cycles (%cPositiveInteger;)> + +<!ELEMENT meta:editing-duration (%cTimeDuration;)> + +<!ELEMENT meta:user-defined (%cString;)> +<!ATTLIST meta:user-defined meta:name %string; #REQUIRED> + +<!ELEMENT meta:document-statistic EMPTY> +<!ATTLIST meta:document-statistic meta:page-count %positiveInteger; #IMPLIED + meta:table-count %nonNegativeInteger; #IMPLIED + meta:draw-count %nonNegativeInteger; #IMPLIED + meta:image-count %nonNegativeInteger; #IMPLIED + meta:ole-object-count %nonNegativeInteger; #IMPLIED + meta:paragraph-count %nonNegativeInteger; #IMPLIED + meta:word-count %nonNegativeInteger; #IMPLIED + meta:character-count %nonNegativeInteger; #IMPLIED + meta:row-count %nonNegativeInteger; #IMPLIED + meta:cell-count %nonNegativeInteger; #IMPLIED + meta:object-count %positiveInteger; #IMPLIED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/nmspace.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/nmspace.mod new file mode 100644 index 000000000000..3dd3c4177c82 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/nmspace.mod @@ -0,0 +1,54 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: nmspace.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY nFO "http://www.w3.org/1999/XSL/Format"> +<!ENTITY nXLink "http://www.w3.org/1999/xlink"> +<!ENTITY nSVG "http://www.w3.org/2000/svg"> + +<!-- StarOffice namespace names and prefixes --> + +<!ENTITY nOpenOffice "http://openoffice.org/2000"> +<!ENTITY nOpenOffice2001 "http://openoffice.org/2001"> + +<!ENTITY nOffice "&nOpenOffice;/office"> +<!ENTITY nStyle "&nOpenOffice;/style"> +<!ENTITY nText "&nOpenOffice;/text"> +<!ENTITY nTable "&nOpenOffice;/table"> +<!ENTITY nMeta "&nOpenOffice;/meta"> +<!ENTITY nScript "&nOpenOffice;/script"> +<!ENTITY nDraw "&nOpenOffice;/drawing"> +<!ENTITY nChart "&nOpenOffice;/chart"> +<!ENTITY nNumber "&nOpenOffice;/datastyle"> +<!ENTITY nConfig "&nOpenOffice2001;/config"> + + +<!-- dublin core namespace name and prefic --> +<!ENTITY nDC "http://purl.org/dc/elements/1.1/"> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/office.dtd b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/office.dtd new file mode 100644 index 000000000000..ef73319720b1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/office.dtd @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: office.dtd,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % dtypes-mod SYSTEM "dtypes.mod"> +%dtypes-mod; +<!ENTITY % nmspace-mod SYSTEM "nmspace.mod"> +%nmspace-mod; +<!ENTITY % style-mod SYSTEM "style.mod"> +%style-mod; +<!ENTITY % office-mod SYSTEM "office.mod"> +%office-mod; +<!ENTITY % meta-mod SYSTEM "meta.mod"> +%meta-mod; +<!ENTITY % script-mod SYSTEM "script.mod"> +%script-mod; +<!ENTITY % drawing-mod SYSTEM "drawing.mod"> +%drawing-mod; +<!ENTITY % text-mod SYSTEM "text.mod"> +%text-mod; +<!ENTITY % table-mod SYSTEM "table.mod"> +%table-mod; +<!ENTITY % chart-mod SYSTEM "chart.mod"> +%chart-mod; +<!ENTITY % datastyl-mod SYSTEM "datastyl.mod"> +%datastyl-mod; +<!ENTITY % form-mod SYSTEM "form.mod"> +%form-mod; +<!ENTITY % settings-mod SYSTEM "settings.mod"> +%settings-mod; diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/office.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/office.mod new file mode 100644 index 000000000000..ed543b22a520 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/office.mod @@ -0,0 +1,238 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: office.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT office:document ( office:meta?, + office:settings?, + office:script?, + office:font-decls?, + office:styles?, + office:automatic-styles?, + office:master-styles?, + office:body ) > + +<!ATTLIST office:document xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document office:class + (text|text-global| + drawing|presentation| + spreadsheet|chart) #REQUIRED> + +<!ATTLIST office:document office:version %string; #IMPLIED> + +<!-- document-styles --> +<!ELEMENT office:document-styles ( + office:font-decls?, + office:styles?, + office:automatic-styles?, + office:master-styles? ) > + +<!ATTLIST office:document-styles xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-styles xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document-styles xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document-styles xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document-styles xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document-styles xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document-styles xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document-styles xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document-styles xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document-styles xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document-styles xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-styles xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document-styles xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document-styles office:version %string; #IMPLIED> + +<!-- document-content --> + +<!ELEMENT office:document-content ( + office:script?, + office:font-decls?, + office:automatic-styles?, + office:body ) > + +<!ATTLIST office:document-content xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-content xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document-content xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document-content xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document-content xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document-content xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document-content xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document-content xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document-content xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document-content xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document-content xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-content xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document-content xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document-content office:class + (text|text-global| + drawing|presentation| + spreadsheet|chart) #REQUIRED> + +<!ATTLIST office:document-content office:version %string; #IMPLIED> + +<!-- document-content --> + +<!ELEMENT office:document-meta ( office:meta? ) > + +<!ATTLIST office:document-meta xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-meta xmlns:meta CDATA #FIXED "&nMeta;"> +<!ATTLIST office:document-meta xmlns:script CDATA #FIXED "&nScript;"> +<!ATTLIST office:document-meta xmlns:style CDATA #FIXED "&nStyle;"> +<!ATTLIST office:document-meta xmlns:text CDATA #FIXED "&nText;"> +<!ATTLIST office:document-meta xmlns:table CDATA #FIXED "&nTable;"> +<!ATTLIST office:document-meta xmlns:draw CDATA #FIXED "&nDraw;"> +<!ATTLIST office:document-meta xmlns:chart CDATA #FIXED "&nChart;"> +<!ATTLIST office:document-meta xmlns:number CDATA #FIXED "&nNumber;"> +<!ATTLIST office:document-meta xmlns:fo CDATA #FIXED "&nFO;"> +<!ATTLIST office:document-meta xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-meta xmlns:svg CDATA #FIXED "&nSVG;"> +<!ATTLIST office:document-meta xmlns:dc CDATA #FIXED "&nDC;"> + +<!ATTLIST office:document-meta office:version %string; #IMPLIED> + +<!ELEMENT office:document-settings (office:settings) > +<!ATTLIST office:document-settings xmlns:office CDATA #FIXED "&nOffice;"> +<!ATTLIST office:document-settings xmlns:xlink CDATA #FIXED "&nXLink;"> +<!ATTLIST office:document-settings xmlns:config CDATA #FIXED "&nConfig;"> + +<!ATTLIST office:document-settings office:version %string; #IMPLIED> + +<!ENTITY % meta "(meta:generator?, + dc:title?, + dc:description?, + dc:subject?, + meta:initial-creator?, + meta:creation-date?, + dc:creator?, + dc:date?, + meta:printed-by?, + meta:print-date?, + meta:keywords?, + dc:language?, + meta:editing-cycles?, + meta:editing-duration?, + meta:hyperlink-behaviour?, + meta:auto-reload?, + meta:template?, + meta:user-defined*, + meta:document-statistic?)"> +<!ELEMENT office:meta %meta;> + +<!ENTITY % script "(script:library-embedded | + script:library-linked)*"> +<!ELEMENT office:script %script;> + +<!ELEMENT office:font-decls (style:font-decl)*> + +<!ENTITY % styles "(style:default-style|style:style|text:list-style| + number:number-style|number:currency-style|number:percentage-style| + number:date-style|number:time-style|number:boolean-style| + number:text-style| + draw:gradient|draw:hatch|draw:fill-image|draw:marker|draw:stroke-dash| + style:presentation-page-layout|draw:transparency)"> + +<!-- Validity constraint: The elements + text:outline-style, + text:footnotes-configuration, + text:endnotes-configuration, + text:bibliography-configuration and + text:linenumbering-configuration + may appear only once! + Unfortunatetly, this constraint cannot be easily specified in the DTD. +--> +<!ELEMENT office:styles (%styles;|text:outline-style| + text:footnotes-configuration|text:endnotes-configuration| + text:bibliography-configuration|text:linenumbering-configuration)*> + +<!ELEMENT office:automatic-styles (%styles;|style:page-master)*> + +<!ELEMENT office:master-styles (draw:layer-set?,style:handout-master?,style:master-page*) > + +<!ENTITY % text-decls "text:variable-decls?, text:sequence-decls?, + text:user-field-decls?, text:dde-connection-decls?, + text:alphabetical-index-auto-mark-file?" > + +<!ENTITY % change-marks "text:change | text:change-start | text:change-end"> + +<!ENTITY % body "(office:forms?,(text:tracked-changes|table:tracked-changes)?,%text-decls;,table:calculation-settings?,table:content-validations?,table:label-ranges?, + (text:h|text:p|text:ordered-list| + text:unordered-list|table:table|draw:page| + draw:a|%shape;|text:section|text:table-of-content| + text:illustration-index|text:table-index|text:object-index| + text:user-index|text:alphabetical-index|text:bibliography| + %change-marks;)*, + table:named-expressions?, + table:database-ranges?,table:data-pilot-tables?, + table:consolidation?, + table:dde-links?, + presentation:settings?)"> +<!ELEMENT office:body %body;> +<!ATTLIST office:body table:structure-protected %boolean; "false" + table:protection-key CDATA #IMPLIED> + +<!ELEMENT office:events (script:event|presentation:event)*> + +<!-- DDE source: for text sections and tables --> +<!ELEMENT office:dde-source EMPTY> +<!ATTLIST office:dde-source office:dde-application CDATA #IMPLIED> +<!ATTLIST office:dde-source office:dde-topic CDATA #IMPLIED> +<!ATTLIST office:dde-source office:dde-item CDATA #IMPLIED> +<!ATTLIST office:dde-source office:automatic-update %boolean; "false"> +<!ATTLIST office:dde-source office:name CDATA #IMPLIED> +<!ATTLIST office:dde-source table:conversion-mode (into-default-style-data-style|into-english-number|let-text) "into-default-style-data-style" > + +<!-- annotations --> +<!-- limitation: in the current implementation, only plain text inside of + paragraphs is supported --> +<!ELEMENT office:annotation (text:p)*> +<!ATTLIST office:annotation office:author %string; #IMPLIED> +<!ATTLIST office:annotation office:create-date %date; #IMPLIED> +<!ATTLIST office:annotation office:create-date-string %string; #IMPLIED> +<!ATTLIST office:annotation office:display %boolean; "false"> + +<!ELEMENT office:change-info (text:p)*> +<!ATTLIST office:change-info office:chg-author %string; #REQUIRED> +<!ATTLIST office:change-info office:chg-date-time %timeInstance; #REQUIRED> + +<!ELEMENT office:binary-data (#PCDATA)> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/script.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/script.mod new file mode 100644 index 000000000000..81220e346f20 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/script.mod @@ -0,0 +1,55 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: script.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT script:library-embedded (script:module*)> +<!ATTLIST script:library-embedded script:name %string; #REQUIRED> +<!ATTLIST script:library-embedded script:password %string; #IMPLIED> + +<!ELEMENT script:library-linked EMPTY> +<!ATTLIST script:library-linked script:name %string; #REQUIRED> +<!ATTLIST script:library-linked xlink:href %string; #REQUIRED> +<!ATTLIST script:library-linked xlink:type (simple) #FIXED "simple"> + +<!ELEMENT script:module (#PCDATA)> +<!ATTLIST script:module script:name %string; #REQUIRED> +<!ATTLIST script:module script:language %string; #IMPLIED> + + +<!ENTITY % script-language "script:language %string; #REQUIRED"> +<!ENTITY % event-name "script:event-name %string; #REQUIRED"> +<!ENTITY % location "script:location (document|application) #REQUIRED"> +<!ENTITY % macro-name "script:macro-name %string; #REQUIRED"> + +<!ELEMENT script:event (#PCDATA)> +<!ATTLIST script:event %script-language; + %event-name; + %location; + %macro-name;> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/settings.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/settings.mod new file mode 100644 index 000000000000..5ba8f38f3ba6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/settings.mod @@ -0,0 +1,53 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: settings.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT office:settings (config:config-item-set+)> + +<!ENTITY % items "(config:config-item | + config:config-item-set | + config:config-item-map-named | + config:config-item-map-indexed)+"> + +<!ELEMENT config:config-item-set %items;> +<!ATTLIST config:config-item-set config:name CDATA #REQUIRED> + +<!ELEMENT config:config-item (#PCDATA)> +<!ATTLIST config:config-item config:name CDATA #REQUIRED + config:type (boolean | short | int | long | double | string | datetime | base64Binary) #REQUIRED> + +<!ELEMENT config:config-item-map-named (config:config-item-map-entry)+> +<!ATTLIST config:config-item-map-named config:name CDATA #REQUIRED> + +<!ELEMENT config:config-item-map-indexed (config:config-item-map-entry)+> +<!ATTLIST config:config-item-map-indexed config:name CDATA #REQUIRED> + +<!ELEMENT config:config-item-map-entry %items;> +<!ATTLIST config:config-item-map-entry config:name CDATA #IMPLIED> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/style.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/style.mod new file mode 100644 index 000000000000..5c5b3dca3c4b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/style.mod @@ -0,0 +1,395 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: style.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT style:font-decl EMPTY> +<!ATTLIST style:font-decl style:name %string; #REQUIRED> +<!ATTLIST style:font-decl fo:font-family %string; #REQUIRED> +<!ATTLIST style:font-decl style:font-style-name %string; #IMPLIED> +<!ENTITY % fontFamilyGeneric "(roman|swiss|modern|decorative|script|system)"> +<!ATTLIST style:font-decl style:font-family-generic %fontFamilyGeneric; + #IMPLIED> +<!ENTITY % fontPitch "(fixed|variable)"> +<!ATTLIST style:font-decl style:font-pitch %fontPitch; #IMPLIED> +<!ATTLIST style:font-decl style:font-charset %textEncoding; #IMPLIED> + +<!ELEMENT style:style ( style:properties?,office:events?,style:map*)> + +<!ATTLIST style:style style:name %styleName; #REQUIRED> + +<!ENTITY % styleFamily "(paragraph|text|section| + table|table-column|table-row|table-cell|table-page|chart|graphics|default|drawing-page|presentation|control)"> +<!ATTLIST style:style style:family %styleFamily; #REQUIRED> + +<!ATTLIST style:style style:parent-style-name %styleName; #IMPLIED> +<!ATTLIST style:style style:master-page-name %styleName; #IMPLIED> +<!ATTLIST style:style style:next-style-name %styleName; #IMPLIED> +<!ATTLIST style:style style:list-style-name %styleName; #IMPLIED> +<!ATTLIST style:style style:data-style-name %styleName; #IMPLIED> + +<!ATTLIST style:style style:auto-update %boolean; "false"> + +<!ATTLIST style:style style:class %string; #IMPLIED> + +<!ELEMENT style:default-style (style:properties?)> +<!ATTLIST style:default-style style:family %styleFamily; #REQUIRED> + +<!ELEMENT style:map EMPTY> + +<!ATTLIST style:map style:condition %string; #REQUIRED> +<!ATTLIST style:map style:apply-style-name %styleName; #REQUIRED> +<!ATTLIST style:map style:base-cell-address %cell-address; #IMPLIED> + +<!ELEMENT style:properties ANY> + +<!-- number format properties --> +<!ATTLIST style:properties style:num-prefix %string; #IMPLIED> +<!ATTLIST style:properties style:num-suffix %string; #IMPLIED> +<!ATTLIST style:properties style:num-format %string; #IMPLIED> +<!ATTLIST style:properties style:num-letter-sync %boolean; #IMPLIED> + +<!-- frame properties --> +<!ATTLIST style:properties fo:width %positiveLength; #IMPLIED> +<!ATTLIST style:properties fo:height %positiveLength; #IMPLIED> +<!ATTLIST style:properties style:vertical-pos (top|middle|bottom|from-top) #IMPLIED> +<!ATTLIST style:properties style:vertical-rel (page|page-content| + frame|frame-content| + paragraph|paragraph-content|char| + line|baseline|text) #IMPLIED> +<!ATTLIST style:properties style:horizontal-pos (left|center|right|from-left|inside|outside|from-inside) #IMPLIED> +<!ATTLIST style:properties style:horizontal-rel (page|page-content| + frame|frame-content| + paragraph|paragraph-content| + char) #IMPLIED> +<!ATTLIST style:properties svg:width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties svg:height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:min-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:min-width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:max-height %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:max-width %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties text:anchor-type %anchorType; #IMPLIED> +<!ATTLIST style:properties text:anchor-page-number %positiveInteger; #IMPLIED> +<!ATTLIST style:properties svg:x %coordinate; #IMPLIED> +<!ATTLIST style:properties svg:y %coordinate; #IMPLIED> +<!ATTLIST style:properties style:print-content %boolean; #IMPLIED> +<!ATTLIST style:properties style:protect %boolean; #IMPLIED> +<!ATTLIST style:properties style:wrap (none|left|right|parallel|dynamic|run-through) #IMPLIED> +<!ENTITY % noLimitOrPositiveInteger "CDATA"> +<!ATTLIST style:properties style:number-wrapped-paragraphs %noLimitOrPositiveInteger; #IMPLIED> +<!ATTLIST style:properties style:wrap-contour %boolean; #IMPLIED> +<!ATTLIST style:properties style:wrap-contour-mode (full|outside) #IMPLIED> +<!ATTLIST style:properties style:run-through (foreground|background) #IMPLIED> +<!ATTLIST style:properties style:editable %boolean; #IMPLIED> +<!ATTLIST style:properties style:mirror CDATA #IMPLIED> +<!ATTLIST style:properties fo:clip CDATA #IMPLIED> +<!ATTLIST style:properties text:animation (none|scroll|alternate|slide) #IMPLIED> +<!ATTLIST style:properties text:animation-direction (left|right|up|down) #IMPLIED> +<!ATTLIST style:properties text:animation-start-inside %boolean; #IMPLIED> +<!ATTLIST style:properties text:animation-stop-inside %boolean; #IMPLIED> +<!ATTLIST style:properties text:animation-repeat %integer; #IMPLIED> +<!ATTLIST style:properties text:animation-delay %timeDuration; #IMPLIED> +<!ATTLIST style:properties text:animation-steps %length; #IMPLIED> + +<!-- text properties --> +<!ATTLIST style:properties fo:font-variant (normal|small-caps) #IMPLIED> +<!ATTLIST style:properties fo:text-transform (none|lowercase| + uppercase|capitalize) #IMPLIED> +<!ATTLIST style:properties fo:color %color; #IMPLIED> +<!ATTLIST style:properties style:use-window-font-color %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-outline %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-crossing-out + (none|single-line|double-line|thick-line|slash|X) + #IMPLIED> +<!ATTLIST style:properties style:text-position CDATA #IMPLIED> +<!ATTLIST style:properties style:text-align (left|right|start|center|end|justify|justified) #IMPLIED> + +<!ATTLIST style:properties style:font-name %string; #IMPLIED> +<!ATTLIST style:properties fo:font-family %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-generic %fontFamilyGeneric; + #IMPLIED> +<!ATTLIST style:properties style:font-style-name %string; #IMPLIED> +<!ATTLIST style:properties style:font-pitch %fontPitch; #IMPLIED> +<!ATTLIST style:properties style:font-charset %textEncoding; #IMPLIED> +<!ATTLIST style:properties style:font-name-asian %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-asian %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-generic-asian %fontFamilyGeneric; + #IMPLIED> +<!ATTLIST style:properties style:font-style-name-asian %string; #IMPLIED> +<!ATTLIST style:properties style:font-pitch-asian %fontPitch; #IMPLIED> +<!ATTLIST style:properties style:font-charset-asian %textEncoding; #IMPLIED> +<!ATTLIST style:properties style:font-name-complex %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-complex %string; #IMPLIED> +<!ATTLIST style:properties style:font-family-generic-complex %fontFamilyGeneric; + #IMPLIED> +<!ATTLIST style:properties style:font-style-name-complex %string; #IMPLIED> +<!ATTLIST style:properties style:font-pitch-complex %fontPitch; #IMPLIED> +<!ATTLIST style:properties style:font-charset-complex %textEncoding; #IMPLIED> + +<!ATTLIST style:properties fo:font-size %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:font-size-rel %length; #IMPLIED> +<!ATTLIST style:properties style:font-size-asian %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:font-size-rel-asian %length; #IMPLIED> +<!ATTLIST style:properties style:font-size-complex %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:font-size-rel-complex %length; #IMPLIED> +<!ENTITY % normalOrLength "CDATA"> +<!ATTLIST style:properties fo:letter-spacing %normalOrLength; #IMPLIED> +<!ATTLIST style:properties fo:language %languageOnly; #IMPLIED> +<!ATTLIST style:properties style:language-asian %languageOnly; #IMPLIED> +<!ATTLIST style:properties style:language-complex %languageOnly; #IMPLIED> +<!ATTLIST style:properties fo:country %country; #IMPLIED> +<!ATTLIST style:properties style:country-asian %country; #IMPLIED> +<!ATTLIST style:properties style:country-complex %country; #IMPLIED> +<!ENTITY % fontStyle "(normal|italic|oblique)"> +<!ATTLIST style:properties fo:font-style %fontStyle; #IMPLIED> +<!ATTLIST style:properties style:font-style-asian %fontStyle; #IMPLIED> +<!ATTLIST style:properties style:font-style-complex %fontStyle; #IMPLIED> +<!ENTITY % fontRelief "(none|embossed|engraved)"> +<!ATTLIST style:properties style:font-relief %fontRelief; #IMPLIED> +<!ATTLIST style:properties fo:text-shadow CDATA #IMPLIED> +<!ATTLIST style:properties style:text-underline + (none|single|double|dotted|dash|long-dash|dot-dash| + dot-dot-dash|wave|bold|bold-dotted|bold-dash| + bold-long-dash|bold-dot-dash|bold-dot-dot-dash| + bold-wave|double-wave|small-wave) #IMPLIED> +<!ATTLIST style:properties style:text-autospace (none | ideograph-alpha) #IMPLIED> +<!ATTLIST style:properties style:punctuation-wrap (simple | hanging) #IMPLIED> +<!ATTLIST style:properties style:line-break (normal | strict) #IMPLIED> +<!ENTITY % fontColorOrColor "CDATA"> +<!ATTLIST style:properties style:text-underline-color %fontColorOrColor; + #IMPLIED> +<!ATTLIST style:properties fo:font-weight CDATA #IMPLIED> +<!ATTLIST style:properties style:font-weight-asian CDATA #IMPLIED> +<!ATTLIST style:properties style:font-weight-complex CDATA #IMPLIED> +<!ATTLIST style:properties fo:score-spaces %boolean; #IMPLIED> +<!ATTLIST style:properties style:letter-kerning %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-blinking %boolean; #IMPLIED> +<!ATTLIST style:properties style:text-background-color %transparentOrColor; + #IMPLIED> + +<!ATTLIST style:properties style:text-combine (none|letters|lines) #IMPLIED> +<!ATTLIST style:properties style:text-combine-start-char %character; #IMPLIED> +<!ATTLIST style:properties style:text-combine-end-char %character; #IMPLIED> +<!ATTLIST style:properties style:text-emphasize CDATA #IMPLIED> +<!ATTLIST style:properties style:text-scale %percentage; #IMPLIED> +<!ATTLIST style:properties style:text-rotation-angle %integer; #IMPLIED> +<!ATTLIST style:properties style:text-rotation-scale (fixed|line-height) #IMPLIED> + +<!-- paragraph properties --> +<!ENTITY % nonNegativeLengthOrPercentageOrNormal "CDATA"> +<!ATTLIST style:properties fo:line-height + %nonNegativeLengthOrPercentageOrNormal; #IMPLIED> +<!ATTLIST style:properties style:line-height-at-least %nonNegativeLength; + #IMPLIED> +<!ATTLIST style:properties style:line-spacing %length; #IMPLIED> +<!ATTLIST style:properties fo:text-align (start|end|center|justify) #IMPLIED> +<!ATTLIST style:properties fo:text-align-last (start|center|justify) #IMPLIED> +<!ATTLIST style:properties style:text-align-source (fix|value-type) #IMPLIED> +<!ATTLIST style:properties style:justify-single-word %boolean; #IMPLIED> +<!ATTLIST style:properties style:break-inside (auto|avoid) #IMPLIED> +<!ATTLIST style:properties fo:widows %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties fo:orphans %nonNegativeInteger; #IMPLIED> + +<!ATTLIST style:properties fo:hyphenate %boolean; #IMPLIED> +<!ATTLIST style:properties fo:hyphenate-keep (none|page) #IMPLIED> +<!ATTLIST style:properties fo:hyphenation-remain-char-count %positiveInteger; + #IMPLIED> +<!ATTLIST style:properties fo:hyphenation-push-char-count %positiveInteger; + #IMPLIED> +<!ATTLIST style:properties fo:hyphenation-ladder-count + %noLimitOrPositiveInteger; #IMPLIED> +<!ATTLIST style:properties style:page-number %positiveInteger; #IMPLIED> + +<!ELEMENT style:tab-stops (style:tab-stop)*> +<!ELEMENT style:tab-stop EMPTY> +<!ATTLIST style:tab-stop style:position %nonNegativeLength; #REQUIRED> +<!ATTLIST style:tab-stop style:type (left|center|right|char|default) "left"> +<!ATTLIST style:tab-stop style:char %character; #IMPLIED> +<!ATTLIST style:tab-stop style:leader-char %character; " "> + +<!ELEMENT style:drop-cap EMPTY> +<!ENTITY % wordOrPositiveInteger "CDATA"> +<!ATTLIST style:drop-cap style:length %wordOrPositiveInteger; "1"> +<!ATTLIST style:drop-cap style:lines %positiveInteger; "1"> +<!ATTLIST style:drop-cap style:distance %length; "0cm"> +<!ATTLIST style:drop-cap style:style-name %styleName; #IMPLIED> + +<!ATTLIST style:properties style:register-true %boolean; #IMPLIED> +<!ATTLIST style:properties style:register-truth-ref-style-name %styleName; #IMPLIED> +<!ATTLIST style:properties fo:margin-left %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:margin-right %positiveLengthOrPercentage; + #IMPLIED> +<!ATTLIST style:properties fo:text-indent %lengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties style:auto-text-indent %boolean; #IMPLIED> +<!ATTLIST style:properties fo:margin-top %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:margin-bottom %positiveLengthOrPercentage; #IMPLIED> +<!ATTLIST style:properties fo:break-before (auto|column|page) #IMPLIED> +<!ATTLIST style:properties fo:break-after (auto|column|page) #IMPLIED> +<!ATTLIST style:properties fo:background-color %transparentOrColor; #IMPLIED> + +<!ELEMENT style:background-image (office:binary-data?)> +<!ATTLIST style:background-image xlink:type (simple) #IMPLIED> +<!ATTLIST style:background-image xlink:href %uriReference; #IMPLIED> +<!ATTLIST style:background-image xlink:show (embed) #IMPLIED> +<!ATTLIST style:background-image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST style:background-image style:repeat (no-repeat|repeat|stretch) + "repeat"> +<!ATTLIST style:background-image style:position CDATA "center"> +<!ATTLIST style:background-image style:filter-name %string; #IMPLIED> + +<!ELEMENT style:symbol-image (office:binary-data?)> +<!ATTLIST style:symbol-image xlink:type (simple) #IMPLIED> +<!ATTLIST style:symbol-image xlink:href %uriReference; #IMPLIED> +<!ATTLIST style:symbol-image xlink:show (embed) #IMPLIED> +<!ATTLIST style:symbol-image xlink:actuate (onLoad) #IMPLIED> + +<!ATTLIST style:properties fo:border CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-top CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-bottom CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-left CDATA #IMPLIED> +<!ATTLIST style:properties fo:border-right CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-top CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-bottom CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-left CDATA #IMPLIED> +<!ATTLIST style:properties style:border-line-width-right CDATA #IMPLIED> +<!ATTLIST style:properties fo:padding %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-top %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-bottom %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-left %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties fo:padding-right %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties style:shadow CDATA #IMPLIED> +<!ATTLIST style:properties fo:keep-with-next %boolean; #IMPLIED> + +<!ATTLIST style:properties text:number-lines %boolean; "false"> +<!ATTLIST style:properties text:line-number %nonNegativeInteger; #IMPLIED> + +<!ATTLIST style:properties style:decimal-places %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:properties style:tab-stop-distance %nonNegativeLength; #IMPLIED> + +<!-- table properties --> +<!ATTLIST style:properties style:width %positiveLength; #IMPLIED> +<!ATTLIST style:properties style:rel-width %percentage; #IMPLIED> +<!ATTLIST style:properties style:may-break-between-rows %boolean; #IMPLIED> +<!ATTLIST style:properties table:page-style-name %styleName; #IMPLIED> +<!ATTLIST style:properties table:display %boolean; #IMPLIED> + +<!-- table column properties --> +<!ATTLIST style:properties style:column-width %positiveLength; #IMPLIED> +<!ENTITY % relWidth "CDATA"> +<!ATTLIST style:properties style:rel-column-width %relWidth; #IMPLIED> +<!ATTLIST style:properties style:use-optimal-column-width %boolean; #IMPLIED> + +<!-- table row properties --> +<!ATTLIST style:properties style:row-height %positiveLength; #IMPLIED> +<!ATTLIST style:properties style:min-row-height %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties style:use-optimal-row-height %boolean; #IMPLIED> + +<!-- table cell properties --> +<!ATTLIST style:properties + table:align (left | center | right | margins) #IMPLIED + table:border-model (collapsing | separating) #IMPLIED + fo:vertical-align (top | middle | bottom | automatic) #IMPLIED + fo:direction (ltr | ttb) #IMPLIED + style:rotation-angle %nonNegativeInteger; #IMPLIED + style:rotation-align (none | bottom | top | center) #IMPLIED + style:cell-protect CDATA #IMPLIED + fo:wrap-option (no-wrap | wrap) #IMPLIED +> +<!ELEMENT style:columns (style:column-sep?,style:column*)> +<!ATTLIST style:columns fo:column-count %nonNegativeInteger; #IMPLIED> +<!ATTLIST style:columns fo:column-gap %positiveLength; #IMPLIED> + +<!ELEMENT style:column EMPTY> +<!ATTLIST style:column style:rel-width CDATA #IMPLIED> +<!ATTLIST style:column fo:margin-left %positiveLength; #IMPLIED> +<!ATTLIST style:column fo:margin-right %positiveLength; #IMPLIED> + +<!ELEMENT style:column-sep EMPTY> +<!ATTLIST style:column-sep style:style (none|solid|dotted|dashed|dot-dashed) + "solid"> +<!ATTLIST style:column-sep style:width %length; #REQUIRED> +<!ATTLIST style:column-sep style:height %percentage; "100%"> +<!ATTLIST style:column-sep style:vertical-align (top|middle|bottom) "top"> +<!ATTLIST style:column-sep style:color %color; "#000000"> + +<!-- page master properties --> +<!ELEMENT style:page-master (style:properties?, style:header-style?, style:footer-style?)> +<!ATTLIST style:page-master style:name %styleName; #REQUIRED> +<!ATTLIST style:page-master style:page-usage (all|left|right|mirrored) "all"> + +<!ELEMENT style:header-style (style:properties?)> +<!ELEMENT style:footer-style (style:properties?)> + +<!ATTLIST style:properties fo:page-width %length; #IMPLIED> +<!ATTLIST style:properties fo:page-height %length; #IMPLIED> +<!ATTLIST style:properties style:paper-tray-number %positiveNumberOrDefault; #IMPLIED> +<!ATTLIST style:properties style:print-orientation (portrait|landscape) #IMPLIED> +<!ATTLIST style:properties style:print CDATA #IMPLIED> +<!ATTLIST style:properties style:print-page-order (ttb|ltr) #IMPLIED> +<!ATTLIST style:properties style:first-page-number %positiveInteger; #IMPLIED> +<!ATTLIST style:properties style:scale-to %percentage; #IMPLIED> +<!ATTLIST style:properties style:scale-to-pages %positiveInteger; #IMPLIED> +<!ATTLIST style:properties style:table-centering (horizontal | vertical | both | none) #IMPLIED> + +<!ATTLIST style:properties style:footnote-max-height %lengthOrNoLimit; #IMPLIED> +<!ATTLIST style:properties style:vertical-align (top|bottom|middle|basline|auto) #IMPLIED> + +<!ELEMENT style:footnote-sep EMPTY> +<!ATTLIST style:footnote-sep style:width %length; #IMPLIED> +<!ATTLIST style:footnote-sep style:rel-width %percentage; #IMPLIED> +<!ATTLIST style:footnote-sep style:color %color; #IMPLIED> +<!ATTLIST style:footnote-sep style:adjustment (left|center|right) "left"> +<!ATTLIST style:footnote-sep style:distance-before-sep %length; #IMPLIED> +<!ATTLIST style:footnote-sep style:distance-after-sep %length; #IMPLIED> + +<!-- master page --> +<!ELEMENT style:master-page ( (style:header, style:header-left?)?, (style:footer, style:footer-left?)?, + office:forms?,style:style*, (%shapes;)*, presentation:notes? )> +<!ATTLIST style:master-page style:name %styleName; #REQUIRED> +<!ATTLIST style:master-page style:page-master-name %styleName; #REQUIRED> +<!ATTLIST style:master-page style:next-style-name %styleName; #IMPLIED> +<!ATTLIST style:master-page draw:style-name %styleName; #IMPLIED> + +<!-- handout master --> +<!ELEMENT style:handout-master (%shapes;)*> +<!ATTLIST style:handout-master presentation:presentation-page-layout-name %styleName; #IMPLIED> + +<!ENTITY % hd-ft-content "( text:p | (style:region-left?, style:region-center?, style:region-right?) )"> +<!ELEMENT style:header %hd-ft-content;> +<!ELEMENT style:footer %hd-ft-content;> +<!ELEMENT style:header-left %hd-ft-content;> +<!ATTLIST style:header-left style:display %boolean; "true"> +<!ELEMENT style:footer-left %hd-ft-content;> +<!ATTLIST style:footer-left style:display %boolean; "true"> + +<!ENTITY % region-content "(text:p*)"> +<!ELEMENT style:region-left %region-content;> +<!ELEMENT style:region-center %region-content;> +<!ELEMENT style:region-right %region-content;> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/table.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/table.mod new file mode 100644 index 000000000000..f0371a6023ae --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/table.mod @@ -0,0 +1,497 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: table.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ELEMENT table:calculation-settings (table:null-date?, table:iteration?)> +<!ATTLIST table:calculation-settings + table:case-sensitive %boolean; "true" + table:precision-as-shown %boolean; "false" + table:search-criteria-must-apply-to-whole-cell %boolean; "true" + table:automatic-find-labels %boolean; "true" + table:use-regular-expressions %boolean; "true" + table:null-year %positiveInteger; "1930" +> +<!ELEMENT table:null-date EMPTY> +<!ATTLIST table:null-date + table:value-type %valueType; #FIXED "date" + table:date-value %date; "1899-12-30" +> +<!ELEMENT table:iteration EMPTY> +<!ATTLIST table:iteration + table:status (enable | disable) "disable" + table:steps %positiveInteger; "100" + table:maximum-difference %float; "0.001" +> + +<!ELEMENT table:tracked-changes (table:cell-content-change | table:insertion | table:deletion | table:movement | table:rejection)*> +<!ATTLIST table:tracked-changes table:track-changes %boolean; "true" + table:protected %boolean; "false" + table:protection-key CDATA #IMPLIED +> + +<!ELEMENT table:dependences (table:dependence)+> +<!ELEMENT table:dependence EMPTY> +<!ATTLIST table:dependence + table:id CDATA #REQUIRED +> +<!ELEMENT table:deletions (table:cell-content-deletion | table:change-deletion)+> +<!ELEMENT table:cell-content-deletion (table:cell-address?, table:change-track-table-cell?)> +<!ATTLIST table:cell-content-deletion + table:id CDATA #IMPLIED +> +<!ELEMENT table:change-deletion EMPTY> +<!ATTLIST table:change-deletion + table:id CDATA #IMPLIED +> +<!ELEMENT table:insertion (office:change-info, table:dependences?, table:deletions?)> +<!ATTLIST table:insertion + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED + table:type (row | column | table) #REQUIRED + table:position %integer; #REQUIRED + table:count %positiveInteger; "1" + table:table %integer; #IMPLIED +> +<!ELEMENT table:deletion (office:change-info, table:dependences?, table:deletions?, table:cut-offs?)> +<!ATTLIST table:deletion + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED + table:type (row | column | table) #REQUIRED + table:position %integer; #REQUIRED + table:count %positiveInteger; "1" + table:table %integer; #IMPLIED + table:multi-deletion-spanned %integer; #IMPLIED +> +<!ELEMENT table:cut-offs (table:movement-cut-off+ | (table:insertion-cut-off, table:movement-cut-off*))> +<!ELEMENT table:insertion-cut-off EMPTY> +<!ATTLIST table:insertion-cut-off + table:id CDATA #REQUIRED + table:position %integer; #REQUIRED +> +<!ELEMENT table:movement-cut-off EMPTY> +<!ATTLIST table:movement-cut-off + table:id CDATA #REQUIRED + table:start-position %integer; #IMPLIED + table:end-position %integer; #IMPLIED + table:position %integer; #IMPLIED +> +<!ELEMENT table:movement (table:source-range-address, table:target-range-address, office:change-info, table:dependences?, table:deletions?)> +<!ATTLIST table:movement + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED +> +<!ELEMENT table:target-range-address EMPTY> +<!ATTLIST table:target-range-address + table:column %integer; #IMPLIED + table:row %integer; #IMPLIED + table:table %integer; #IMPLIED + table:start-column %integer; #IMPLIED + table:start-row %integer; #IMPLIED + table:start-table %integer; #IMPLIED + table:end-column %integer; #IMPLIED + table:end-row %integer; #IMPLIED + table:end-table %integer; #IMPLIED +> +<!ELEMENT table:source-range-address EMPTY> +<!ATTLIST table:source-range-address + table:column %integer; #IMPLIED + table:row %integer; #IMPLIED + table:table %integer; #IMPLIED + table:start-column %integer; #IMPLIED + table:start-row %integer; #IMPLIED + table:start-table %integer; #IMPLIED + table:end-column %integer; #IMPLIED + table:end-row %integer; #IMPLIED + table:end-table %integer; #IMPLIED +> +<!ELEMENT table:change-track-table-cell (text:p*)> +<!ATTLIST table:change-track-table-cell + table:cell-address %cell-address; #IMPLIED + table:matrix-covered (true | false) "false" + table:formula %string; #IMPLIED + table:number-matrix-rows-spanned %positiveInteger; #IMPLIED + table:number-matrix-columns-spanned %positiveInteger; #IMPLIED + table:value-type %valueType; "string" + table:value %float; #IMPLIED + table:date-value %date; #IMPLIED + table:time-value %timeInstance; #IMPLIED + table:string-value %string; #IMPLIED +> +<!ELEMENT table:cell-content-change (table:cell-address, office:change-info, table:dependences?, table:deletions?, table:previous)> +<!ATTLIST table:cell-content-change + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED +> +<!ELEMENT table:cell-address EMPTY> +<!ATTLIST table:cell-address + table:column %integer; #IMPLIED + table:row %integer; #IMPLIED + table:table %integer; #IMPLIED +> +<!ELEMENT table:previous (table:change-track-table-cell)> +<!ATTLIST table:previous + table:id CDATA #IMPLIED +> +<!ELEMENT table:rejection (office:change-info, table:dependences?, table:deletions?)> +<!ATTLIST table:rejection + table:id CDATA #REQUIRED + table:acceptance-state (accepted | rejected | pending) "pending" + table:rejecting-change-id %positiveInteger; #IMPLIED +> + +<!ENTITY % table-columns "table:table-columns | ( table:table-column | table:table-column-group )+"> +<!ENTITY % table-header-columns "table:table-header-columns"> +<!ENTITY % table-rows "table:table-rows | ( table:table-row | table:table-row-group )+"> +<!ENTITY % table-header-rows "table:table-header-rows"> +<!ENTITY % table-column-groups "((%table-columns;),(%table-header-columns;,(%table-columns;)?)?) | (%table-header-columns;,(%table-columns;)?)"> +<!ENTITY % table-row-groups "((%table-rows;),(%table-header-rows;,(%table-rows;)?)?) | (%table-header-rows;,(%table-rows;)?)"> +<!ELEMENT table:table (table:table-source?, table:scenario?, office:forms?, table:shapes?, (%table-column-groups;), (%table-row-groups;))> +<!ATTLIST table:table + table:name %string; #IMPLIED + table:style-name %styleName; #IMPLIED + table:protected %boolean; "false" + table:protection-key CDATA #IMPLIED + table:print-ranges %cell-range-address-list; #IMPLIED +> +<!ELEMENT table:table-source EMPTY> +<!ATTLIST table:table-source + table:mode (copy-all | copy-results-only) "copy-all" + xlink:type (simple) #FIXED "simple" + xlink:actuate (onRequest) "onRequest" + xlink:href %uriReference; #REQUIRED + table:filter-name CDATA #IMPLIED + table:table-name CDATA #IMPLIED + table:filter-options CDATA #IMPLIED + table:refresh-delay %timeDuration; #IMPLIED +> +<!ELEMENT table:scenario EMPTY> +<!ATTLIST table:scenario + table:display-border %boolean; "true" + table:border-color %color; #IMPLIED + table:copy-back %boolean; "true" + table:copy-styles %boolean; "true" + table:copy-formulas %boolean; "true" + table:is-active %boolean; #REQUIRED + table:scenario-ranges %cell-range-address-list; #REQUIRED + table:comment CDATA #IMPLIED +> +<!ELEMENT table:shapes %shapes;> +<!ELEMENT table:table-column-group (table:table-header-columns | table:table-column | table:table-column-group)+> +<!ATTLIST table:table-column-group + table:display %boolean; "true" +> +<!ELEMENT table:table-header-columns (table:table-column | table:table-column-group)+> +<!ELEMENT table:table-columns (table:table-column | table:table-column-group)+> +<!ELEMENT table:table-column EMPTY> +<!ATTLIST table:table-column + table:number-columns-repeated %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:visibility (visible | collapse | filter) "visible" + table:default-cell-style-name %styleName; #IMPLIED +> +<!ELEMENT table:table-row-group (table:table-header-rows | table:table-row | table:table-row-group)+> +<!ATTLIST table:table-row-group + table:display %boolean; "true" +> +<!ELEMENT table:table-header-rows (table:table-row | table:table-row-group)+> +<!ELEMENT table:table-rows (table:table-row | table:table-row-group)+> +<!ENTITY % table-cells "(table:table-cell|table:covered-table-cell)+"> +<!ELEMENT table:table-row %table-cells;> +<!ATTLIST table:table-row + table:number-rows-repeated %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:visibility (visible | collapse | filter) "visible" + table:default-cell-style-name %styleName; #IMPLIED +> + +<!ENTITY % text-wo-table "(text:h|text:p|text:ordered-list|text:unordered-list|%shapes;)*"> +<!ENTITY % cell-content "(table:cell-range-source?,office:annotation?,table:detective?,(table:sub-table|%text-wo-table;))"> +<!ELEMENT table:table-cell %cell-content;> +<!ELEMENT table:covered-table-cell %cell-content;> +<!ATTLIST table:table-cell + table:number-columns-repeated %positiveInteger; "1" + table:number-rows-spanned %positiveInteger; "1" + table:number-columns-spanned %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:validation-name CDATA #IMPLIED + table:formula %string; #IMPLIED + table:number-matrix-rows-spanned %positiveInteger; #IMPLIED + table:number-matrix-columns-spanned %positiveInteger; #IMPLIED + table:value-type %valueType; "string" + table:value %float; #IMPLIED + table:date-value %date; #IMPLIED + table:time-value %timeInstance; #IMPLIED + table:boolean-value %boolean; #IMPLIED + table:string-value %string; #IMPLIED + table:currency %string; #IMPLIED +> +<!ATTLIST table:covered-table-cell + table:number-columns-repeated %positiveInteger; "1" + table:style-name %styleName; #IMPLIED + table:validation-name CDATA #IMPLIED + table:formula %string; #IMPLIED + table:number-matrix-rows-spanned %positiveInteger; #IMPLIED + table:number-matrix-columns-spanned %positiveInteger; #IMPLIED + table:value-type %valueType; "string" + table:value %float; #IMPLIED + table:date-value %date; #IMPLIED + table:time-value %timeInstance; #IMPLIED + table:boolean-value %boolean; #IMPLIED + table:string-value %string; #IMPLIED + table:currency %string; #IMPLIED +> +<!-- cell protection in writer: cell attribute; calc uses format --> +<!ATTLIST table:table-cell table:protected %boolean; "false"> + +<!ELEMENT table:cell-range-source EMPTY> +<!ATTLIST table:cell-range-source + table:name %string; #REQUIRED + xlink:type (simple) #FIXED "simple" + xlink:actuate (onRequest) #FIXED "onRequest" + xlink:href %uriReference; #REQUIRED + table:filter-name %string; #REQUIRED + table:filter-options %string; #IMPLIED + table:last-column-spanned %positiveInteger; #REQUIRED + table:last-row-spanned %positiveInteger; #REQUIRED + table:refresh-delay %timeDuration; #IMPLIED +> + +<!ELEMENT table:detective (table:highlighted-range*, table:operation*)> +<!ELEMENT table:highlighted-range EMPTY> +<!ATTLIST table:highlighted-range + table:cell-range-address %cell-range-address; #IMPLIED + table:direction (from-another-table | to-another-table | from-same-table | to-same-table) #REQUIRED + table:contains-error %boolean; "false" +> +<!ELEMENT table:operation EMPTY> +<!ATTLIST table:operation + table:name (trace-dependents | remove-dependents | trace-precedents | remove-precedents | trace-errors) #REQUIRED + table:index %nonNegativeInteger; #REQUIRED +> + +<!ELEMENT table:content-validations (table:content-validation)+> +<!ELEMENT table:content-validation (table:help-message?, (table:error-message | (table:error-macro, office:events?))?)> +<!ATTLIST table:content-validation + table:name CDATA #REQUIRED + table:condition CDATA #IMPLIED + table:base-cell-address %cell-address; #IMPLIED + table:allow-empty-cell %boolean; #IMPLIED +> +<!ELEMENT table:help-message (text:p*)> +<!ATTLIST table:help-message + table:title CDATA #IMPLIED + table:display %boolean; #IMPLIED +> +<!ELEMENT table:error-message (text:p*)> +<!ATTLIST table:error-message + table:title CDATA #IMPLIED + table:message-type (stop | warning | information) #IMPLIED + table:display %boolean; #IMPLIED +> +<!ELEMENT table:error-macro EMPTY> +<!ATTLIST table:error-macro + table:name CDATA #IMPLIED + table:execute %boolean; #IMPLIED +> + +<!ELEMENT table:sub-table ((%table-column-groups;) , (%table-row-groups;))> + +<!ELEMENT table:label-ranges (table:label-range)*> +<!ELEMENT table:label-range EMPTY> +<!ATTLIST table:label-range + table:label-cell-range-address %cell-range-address; #REQUIRED + table:data-cell-range-address %cell-range-address; #REQUIRED + table:orientation (column | row) #REQUIRED +> + +<!ELEMENT table:named-expressions (table:named-range | table:named-expression)*> +<!ELEMENT table:named-range EMPTY> +<!ATTLIST table:named-range + table:name CDATA #REQUIRED + table:cell-range-address %cell-range-address; #REQUIRED + table:base-cell-address %cell-address; #IMPLIED + table:range-usable-as CDATA "none" +> +<!ELEMENT table:named-expression EMPTY> +<!ATTLIST table:named-expression + table:name CDATA #REQUIRED + table:expression CDATA #REQUIRED + table:base-cell-address %cell-address; #IMPLIED +> + +<!ELEMENT table:filter (table:filter-condition | table:filter-and | table:filter-or)> +<!ATTLIST table:filter + table:target-range-address %cell-range-address; #IMPLIED + table:condition-source-range-address %cell-range-address; #IMPLIED + table:condition-source (self | cell-range) "self" + table:display-duplicates %boolean; "true" +> +<!ELEMENT table:filter-and (table:filter-or | table:filter-condition)+> +<!ELEMENT table:filter-or (table:filter-and | table:filter-condition)+> +<!ELEMENT table:filter-condition EMPTY> +<!ATTLIST table:filter-condition + table:field-number %nonNegativeInteger; #REQUIRED + table:case-sensitive %boolean; "false" + table:data-type (text | number) "text" + table:value CDATA #REQUIRED + table:operator CDATA #REQUIRED +> + +<!ELEMENT table:database-ranges (table:database-range)*> +<!ELEMENT table:database-range ((table:database-source-sql | table:database-source-table | table:database-source-query)?, table:filter?, table:sort?, table:subtotal-rules?)> +<!ATTLIST table:database-range + table:name CDATA #IMPLIED + table:is-selection %boolean; "false" + table:on-update-keep-styles %boolean; "false" + table:on-update-keep-size %boolean; "true" + table:has-persistant-data %boolean; "true" + table:orientation (row | column) "row" + table:contains-header %boolean; "true" + table:display-filter-buttons %boolean; "false" + table:target-range-address %cell-range-address; #REQUIRED + table:refresh-delay %timeDuration; #IMPLIED +> +<!ELEMENT table:database-source-sql EMPTY> +<!ATTLIST table:database-source-sql + table:database-name CDATA #REQUIRED + table:sql-statement CDATA #REQUIRED + table:parse-sql-statements %boolean; "false" +> +<!ELEMENT table:database-source-table EMPTY> +<!ATTLIST table:database-source-table + table:database-name CDATA #REQUIRED + table:table-name CDATA #REQUIRED +> +<!ELEMENT table:database-source-query EMPTY> +<!ATTLIST table:database-source-query + table:database-name CDATA #REQUIRED + table:query-name CDATA #REQUIRED +> + +<!ELEMENT table:sort (table:sort-by)+> +<!ATTLIST table:sort + table:bind-styles-to-content %boolean; "true" + table:target-range-address %cell-range-address; #IMPLIED + table:case-sensitive %boolean; "false" + table:language CDATA #IMPLIED + table:country CDATA #IMPLIED + table:algorithm CDATA #IMPLIED +> +<!ELEMENT table:sort-by EMPTY> +<!ATTLIST table:sort-by + table:field-number %nonNegativeInteger; #REQUIRED + table:data-type (text | number | automatic | qname-but-not-ncname) "automatic" + table:order (ascending | descending) "ascending" +> + +<!ELEMENT table:subtotal-rules (table:sort-groups? | table:subtotal-rule*)?> +<!ATTLIST table:subtotal-rules + table:bind-styles-to-content %boolean; "true" + table:case-sensitive %boolean; "false" + table:page-breaks-on-group-change %boolean; "false" +> +<!ELEMENT table:sort-groups EMPTY> +<!ATTLIST table:sort-groups + table:data-type (text | number | automatic | qname-but-not-ncname) "automatic" + table:order (ascending | descending) "ascending" +> +<!ELEMENT table:subtotal-rule (table:subtotal-field)*> +<!ATTLIST table:subtotal-rule + table:group-by-field-number %nonNegativeInteger; #REQUIRED +> +<!ELEMENT table:subtotal-field EMPTY> +<!ATTLIST table:subtotal-field + table:field-number %nonNegativeInteger; #REQUIRED + table:function CDATA #REQUIRED +> + +<!ELEMENT table:data-pilot-tables (table:data-pilot-table)*> +<!ELEMENT table:data-pilot-table ((table:database-source-sql | table:database-source-table | table:database-source-query | table:source-service | table:source-cell-range)?, table:data-pilot-field+)> +<!ATTLIST table:data-pilot-table + table:name CDATA #REQUIRED + table:application-data CDATA #IMPLIED + table:grand-total (none | row | column | both) "both" + table:ignore-empty-rows %boolean; "false" + table:identify-categories %boolean; "false" + table:target-range-address %cell-range-address; #REQUIRED + table:buttons %cell-range-address-list; #REQUIRED +> +<!ELEMENT table:source-service EMPTY> +<!ATTLIST table:source-service + table:name CDATA #REQUIRED + table:source-name CDATA #REQUIRED + table:object-name CDATA #REQUIRED + table:username CDATA #IMPLIED + table:password CDATA #IMPLIED +> +<!ELEMENT table:source-cell-range (table:filter)?> +<!ATTLIST table:source-cell-range + table:cell-range-address %cell-range-address; #REQUIRED +> +<!ELEMENT table:data-pilot-field (table:data-pilot-level)?> +<!ATTLIST table:data-pilot-field + table:source-field-name CDATA #REQUIRED + table:is-data-layout-field %boolean; "false" + table:function CDATA #REQUIRED + table:orientation (row | column | data | page | hidden) #REQUIRED + table:used-hierarchy %positiveInteger; "1" +> +<!ELEMENT table:data-pilot-level (table:data-pilot-subtotals?, table:data-pilot-members?)> +<!ATTLIST table:data-pilot-level + table:display-empty %boolean; #IMPLIED +> +<!ELEMENT table:data-pilot-subtotals (table:data-pilot-subtotal)*> +<!ELEMENT table:data-pilot-subtotal EMPTY> +<!ATTLIST table:data-pilot-subtotal + table:function CDATA #REQUIRED +> +<!ELEMENT table:data-pilot-members (table:data-pilot-member)*> +<!ELEMENT table:data-pilot-member EMPTY> +<!ATTLIST table:data-pilot-member + table:name CDATA #REQUIRED + table:display %boolean; #IMPLIED + table:display-details %boolean; #IMPLIED +> + +<!ELEMENT table:consolidation EMPTY> +<!ATTLIST table:consolidation + table:function CDATA #REQUIRED + table:source-cell-range-addresses %cell-range-address-list; #REQUIRED + table:target-cell-address %cell-address; #REQUIRED + table:use-label (none | column | row | both) "none" + table:link-to-source-data %boolean; "false" +> + +<!ELEMENT table:dde-links (table:dde-link)+> +<!ELEMENT table:dde-link (office:dde-source, table:table)> diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/text.mod b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/text.mod new file mode 100644 index 000000000000..fd90aff575cd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/dtd/text.mod @@ -0,0 +1,1103 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: text.mod,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<!ENTITY % fields "text:date | + text:time | + text:page-number | + text:page-continuation | + text:sender-firstname | + text:sender-lastname | + text:sender-initials | + text:sender-title | + text:sender-position | + text:sender-email | + text:sender-phone-private | + text:sender-fax | + text:sender-company | + text:sender-phone-work | + text:sender-street | + text:sender-city | + text:sender-postal-code | + text:sender-country | + text:sender-state-or-province | + text:author-name | + text:author-initials | + text:placeholder | + text:variable-set | + text:variable-get | + text:variable-input | + text:user-field-get | + text:user-field-input | + text:sequence | + text:expression | + text:text-input | + text:database-display | + text:database-next | + text:database-row-select | + text:database-row-number | + text:database-name | + text:initial-creator | + text:creation-date | + text:creation-time | + text:description | + text:user-defined | + text:print-time | + text:print-date | + text:printed-by | + text:title | + text:subject | + text:keywords | + text:editing-cycles | + text:editing-duration | + text:modification-time | + text:modification-date | + text:creator | + text:conditional-text | + text:hidden-text | + text:hidden-paragraph | + text:chapter | + text:file-name | + text:template-name | + text:set-page-variable | + text:get-page-variable | + text:execute-macro | + text:dde-connection | + text:reference-ref | + text:sequence-ref | + text:bookmark-ref | + text:footnote-ref | + text:endnote-ref | + text:sheet-name | + text:bibliography-mark | + text:page-count | + text:paragraph-count | + text:word-count | + text:character-count | + text:table-count | + text:image-count | + text:object-count | + office:annotation | + text:script | + text:measure" > + +<!ENTITY % inline-text "(#PCDATA| + text:span|text:tab-stop|text:s|text:line-break| + text:footnote|text:endnote|text:a| + text:bookmark|text:bookmark-start|text:bookmark-end| + text:reference-mark|text:reference-mark-start| + text:reference-mark-end|%fields;|%shape;| + text:toc-mark-start | text:toc-mark-end | + text:toc-mark | text:user-index-mark-start | + text:user-index-mark-end | text:user-index-mark | + text:alphabetical-index-mark-start | + text:alphabetical-index-mark-end | + text:alphabetical-index-mark | + %change-marks; | draw:a | text:ruby)*"> + +<!ELEMENT text:p %inline-text;> +<!ELEMENT text:h %inline-text;> + +<!ATTLIST text:p text:style-name %styleName; #IMPLIED> +<!ATTLIST text:p text:cond-style-name %styleName; #IMPLIED> + +<!ATTLIST text:h text:style-name %styleName; #IMPLIED> +<!ATTLIST text:h text:cond-style-name %styleName; #IMPLIED> +<!ATTLIST text:h text:level %positiveInteger; "1"> + +<!ELEMENT text:span %inline-text;> +<!ATTLIST text:span text:style-name %styleName; #REQUIRED> + +<!ELEMENT text:a %inline-text;> +<!ATTLIST text:a xlink:href %uriReference; #REQUIRED> +<!ATTLIST text:a xlink:type (simple) #FIXED "simple"> +<!ATTLIST text:a xlink:actuate (onRequest) "onRequest"> +<!ATTLIST text:a xlink:show (new|replace) "replace"> +<!ATTLIST text:a office:name %string; #IMPLIED> +<!ATTLIST text:a office:target-frame-name %string; #IMPLIED> +<!ATTLIST text:a text:style-name %styleName; #IMPLIED> +<!ATTLIST text:a text:visited-style-name %styleName; #IMPLIED> + + +<!ELEMENT text:s EMPTY> +<!ATTLIST text:s text:c %positiveInteger; "1"> + +<!ELEMENT text:tab-stop EMPTY> + +<!ELEMENT text:line-break EMPTY> + + +<!ENTITY % list-items "((text:list-header,text:list-item*)|text:list-item+)"> +<!ELEMENT text:ordered-list %list-items;> +<!ELEMENT text:unordered-list %list-items;> + + +<!ATTLIST text:ordered-list text:style-name %styleName; #IMPLIED> +<!ATTLIST text:unordered-list text:style-name %styleName; #IMPLIED> + +<!ATTLIST text:ordered-list text:continue-numbering %boolean; "false"> + +<!ELEMENT text:list-header (text:p)+> +<!ELEMENT text:list-item (text:p|text:ordered-list|text:unordered-list)+> + +<!ATTLIST text:list-item text:restart-numbering %boolean; "false"> +<!ATTLIST text:list-item text:start-value %positiveInteger; #IMPLIED> + +<!ELEMENT text:list-style (text:list-level-style-number| + text:list-level-style-bullet| + text:list-level-style-image)+> + +<!ATTLIST text:list-style style:name %styleName; #IMPLIED> + +<!ATTLIST text:list-style text:consecutive-numbering %boolean; "false"> + + +<!ELEMENT text:list-level-style-number (style:properties?)> + +<!ATTLIST text:list-level-style-number text:level %positiveInteger; + #REQUIRED> +<!ATTLIST text:list-level-style-number text:style-name %styleName; #IMPLIED> + +<!ATTLIST text:list-level-style-number style:num-format %string; #REQUIRED> +<!ATTLIST text:list-level-style-number style:num-prefix %string; #IMPLIED> +<!ATTLIST text:list-level-style-number style:num-suffix %string; #IMPLIED> +<!ATTLIST text:list-level-style-number style:num-letter-sync %boolean; + "false"> +<!ATTLIST text:list-level-style-number text:display-levels %positiveInteger; + "1"> +<!ATTLIST text:list-level-style-number text:start-value %positiveInteger; + "1"> +<!ELEMENT text:list-level-style-bullet (style:properties?)> + +<!ATTLIST text:list-level-style-bullet text:level %positiveInteger; #REQUIRED> +<!ATTLIST text:list-level-style-bullet text:style-name %styleName; #IMPLIED> +<!ATTLIST text:list-level-style-bullet text:bullet-char %character; #REQUIRED> +<!ATTLIST text:list-level-style-bullet style:num-prefix %string; #IMPLIED> +<!ATTLIST text:list-level-style-bullet style:num-suffix %string; #IMPLIED> + +<!ELEMENT text:list-level-style-image (style:properties?,office:binary-data?)> + +<!ATTLIST text:list-level-style-image text:level %positiveInteger; #REQUIRED> +<!ATTLIST text:list-level-style-image xlink:type (simple) #IMPLIED> +<!ATTLIST text:list-level-style-image xlink:href %uriReference; #IMPLIED> +<!ATTLIST text:list-level-style-image xlink:actuate (onLoad) #IMPLIED> +<!ATTLIST text:list-level-style-image xlink:show (embed) #IMPLIED> + + +<!-- list properties --> +<!ATTLIST style:properties text:space-before %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties text:min-label-width %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties text:min-label-distance %nonNegativeLength; #IMPLIED> +<!ATTLIST style:properties text:enable-numbering %boolean; #IMPLIED> +<!ATTLIST style:properties style:list-style-name %styleName; #IMPLIED> + +<!ELEMENT text:outline-style (text:outline-level-style)+> + +<!ELEMENT text:outline-level-style (style:properties?)> + +<!ATTLIST text:outline-level-style text:level %positiveInteger; + #REQUIRED> +<!ATTLIST text:outline-level-style text:style-name %styleName; #IMPLIED> + +<!ATTLIST text:outline-level-style style:num-format %string; #REQUIRED> +<!ATTLIST text:outline-level-style style:num-prefix %string; #IMPLIED> +<!ATTLIST text:outline-level-style style:num-suffix %string; #IMPLIED> +<!ATTLIST text:outline-level-style style:num-letter-sync %boolean; + "false"> +<!ATTLIST text:outline-level-style text:display-levels %positiveInteger; + "1"> +<!ATTLIST text:outline-level-style text:start-value %positiveInteger; + "1"> + +<!ENTITY % field-declarations "text:variable-decls?, + text:user-field-decls?, + text:sequence-decls?"> + +<!ENTITY % variableName "CDATA"> + +<!ENTITY % formula "CDATA"> + +<!ENTITY % valueAttr "text:value-type %valueType; #REQUIRED"> + +<!ENTITY % valueAndTypeAttr "%valueAttr; + text:value %float; #IMPLIED + text:date-value %date; #IMPLIED + text:time-value %timeInstance; #IMPLIED + text:boolean-value %boolean; #IMPLIED + text:string-value %string; #IMPLIED + text:currency CDATA #IMPLIED" > + +<!ENTITY % numFormat 'style:num-format CDATA #IMPLIED + style:num-letter-sync %boolean; "false"'> + + +<!ELEMENT text:date (#PCDATA)> +<!ATTLIST text:date text:date-value %date; #IMPLIED> +<!ATTLIST text:date text:date-adjust %dateDuration; #IMPLIED> +<!ATTLIST text:date text:fixed %boolean; "false"> +<!ATTLIST text:date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:time (#PCDATA)> +<!ATTLIST text:time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:time text:time-adjust %timeDuration; #IMPLIED> +<!ATTLIST text:time text:fixed %boolean; "false"> +<!ATTLIST text:time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:page-number (#PCDATA)> +<!ATTLIST text:page-number text:page-adjust %positiveInteger; #IMPLIED> +<!ATTLIST text:page-number text:select-page (previous|current|next) "current"> +<!ATTLIST text:page-number %numFormat;> + +<!ELEMENT text:page-continuation (#PCDATA)> +<!ATTLIST text:page-continuation text:select-page (previous|next) #REQUIRED> +<!ATTLIST text:page-continuation text:string-value %string; #IMPLIED> + +<!ELEMENT text:sender-firstname (#PCDATA)> +<!ATTLIST text:sender-firstname text:fixed %boolean; "true"> + +<!ELEMENT text:sender-lastname (#PCDATA)> +<!ATTLIST text:sender-lastname text:fixed %boolean; "true"> + +<!ELEMENT text:sender-initials (#PCDATA)> +<!ATTLIST text:sender-initials text:fixed %boolean; "true"> + +<!ELEMENT text:sender-title (#PCDATA)> +<!ATTLIST text:sender-title text:fixed %boolean; "true"> + +<!ELEMENT text:sender-position (#PCDATA)> +<!ATTLIST text:sender-position text:fixed %boolean; "true"> + +<!ELEMENT text:sender-email (#PCDATA)> +<!ATTLIST text:sender-email text:fixed %boolean; "true"> + +<!ELEMENT text:sender-phone-private (#PCDATA)> +<!ATTLIST text:sender-phone-private text:fixed %boolean; "true"> + +<!ELEMENT text:sender-fax (#PCDATA)> +<!ATTLIST text:sender-fax text:fixed %boolean; "true"> + +<!ELEMENT text:sender-company (#PCDATA)> +<!ATTLIST text:sender-company text:fixed %boolean; "true"> + +<!ELEMENT text:sender-phone-work (#PCDATA)> +<!ATTLIST text:sender-phone-work text:fixed %boolean; "true"> + +<!ELEMENT text:sender-street (#PCDATA)> +<!ATTLIST text:sender-street text:fixed %boolean; "true"> + +<!ELEMENT text:sender-city (#PCDATA)> +<!ATTLIST text:sender-city text:fixed %boolean; "true"> + +<!ELEMENT text:sender-postal-code (#PCDATA)> +<!ATTLIST text:sender-postal-code text:fixed %boolean; "true"> + +<!ELEMENT text:sender-country (#PCDATA)> +<!ATTLIST text:sender-country text:fixed %boolean; "true"> + +<!ELEMENT text:sender-state-or-province (#PCDATA)> +<!ATTLIST text:sender-state-or-province text:fixed %boolean; "true"> + +<!ELEMENT text:author-name (#PCDATA)> +<!ATTLIST text:author-name text:fixed %boolean; "true"> + +<!ELEMENT text:author-initials (#PCDATA)> +<!ATTLIST text:author-initials text:fixed %boolean; "true"> + +<!ELEMENT text:placeholder (#PCDATA)> +<!ATTLIST text:placeholder text:placeholder-type (text|table|text-box|image|object) #REQUIRED> +<!ATTLIST text:placeholder text:description %string; #IMPLIED> + +<!ELEMENT text:variable-decls (text:variable-decl)*> + +<!ELEMENT text:variable-decl EMPTY> +<!ATTLIST text:variable-decl text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-decl %valueAndTypeAttr;> + +<!ELEMENT text:variable-set (#PCDATA)> +<!ATTLIST text:variable-set text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-set text:formula %formula; #IMPLIED> +<!ATTLIST text:variable-set %valueAndTypeAttr;> +<!ATTLIST text:variable-set text:display (value|none) "value"> +<!ATTLIST text:variable-set style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:variable-get (#PCDATA)> +<!ATTLIST text:variable-get text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-get text:display (value|formula) "value"> +<!ATTLIST text:variable-get style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:variable-input (#PCDATA)> +<!ATTLIST text:variable-input text:name %variableName; #REQUIRED> +<!ATTLIST text:variable-input text:description %string; #IMPLIED> +<!ATTLIST text:variable-input %valueAndTypeAttr;> +<!ATTLIST text:variable-input text:display (value|none) "value"> +<!ATTLIST text:variable-input style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:user-field-decls (text:user-field-decl)*> + +<!ELEMENT text:user-field-decl EMPTY> +<!ATTLIST text:user-field-decl text:name %variableName; #REQUIRED> +<!ATTLIST text:user-field-decl text:formula %formula; #IMPLIED> +<!ATTLIST text:user-field-decl %valueAndTypeAttr;> + +<!ELEMENT text:user-field-get (#PCDATA)> +<!ATTLIST text:user-field-get text:name %variableName; #REQUIRED> +<!ATTLIST text:user-field-get text:display (value|formula|none) "value"> +<!ATTLIST text:user-field-get style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:user-field-input (#PCDATA)> +<!ATTLIST text:user-field-input text:name %variableName; #REQUIRED> +<!ATTLIST text:user-field-input text:description %string; #IMPLIED> +<!ATTLIST text:user-field-input style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:sequence-decls (text:sequence-decl)*> + +<!ELEMENT text:sequence-decl EMPTY> +<!ATTLIST text:sequence-decl text:name %variableName; #REQUIRED> +<!ATTLIST text:sequence-decl text:display-outline-level %positiveInteger; "0"> +<!ATTLIST text:sequence-decl text:separation-character %character; "."> + +<!ELEMENT text:sequence (#PCDATA)> +<!ATTLIST text:sequence text:name %variableName; #REQUIRED> +<!ATTLIST text:sequence text:formula %formula; #IMPLIED> +<!ATTLIST text:sequence %numFormat;> +<!ATTLIST text:sequence text:ref-name ID #IMPLIED> + +<!ELEMENT text:expression (#PCDATA)> +<!ATTLIST text:expression text:formula %formula; #IMPLIED> +<!ATTLIST text:expression text:display (value|formula ) "value"> +<!ATTLIST text:expression %valueAndTypeAttr;> +<!ATTLIST text:expression style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:text-input (#PCDATA)> +<!ATTLIST text:text-input text:description %string; #IMPLIED> + +<!ENTITY % database-table "text:database-name CDATA #REQUIRED + text:table-name CDATA #REQUIRED"> + +<!ELEMENT text:database-display (#PCDATA)> +<!ATTLIST text:database-display %database-table;> +<!ATTLIST text:database-display text:column-name %string; #REQUIRED> +<!ATTLIST text:database-display style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:database-next (#PCDATA)> +<!ATTLIST text:database-next %database-table;> +<!ATTLIST text:database-next text:condition %formula; #IMPLIED> + +<!ELEMENT text:database-row-select (#PCDATA)> +<!ATTLIST text:database-row-select %database-table;> +<!ATTLIST text:database-row-select text:condition %formula; #IMPLIED> +<!ATTLIST text:database-row-select text:row-number %integer; #REQUIRED> + +<!ELEMENT text:database-row-number (#PCDATA)> +<!ATTLIST text:database-row-number %database-table;> +<!ATTLIST text:database-row-number %numFormat;> +<!ATTLIST text:database-row-number text:value %integer; #IMPLIED> + +<!ELEMENT text:database-name (#PCDATA)> +<!ATTLIST text:database-name %database-table;> + +<!ELEMENT text:initial-creator (#PCDATA)> +<!ATTLIST text:initial-creator text:fixed %boolean; "false"> + +<!ELEMENT text:creation-date (#PCDATA)> +<!ATTLIST text:creation-date text:fixed %boolean; "false"> +<!ATTLIST text:creation-date text:date-value %date; #IMPLIED> +<!ATTLIST text:creation-date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:creation-time (#PCDATA)> +<!ATTLIST text:creation-time text:fixed %boolean; "false"> +<!ATTLIST text:creation-time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:creation-time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:description (#PCDATA)> +<!ATTLIST text:description text:fixed %boolean; "false"> + +<!ELEMENT text:user-defined (#PCDATA)> +<!ATTLIST text:user-defined text:fixed %boolean; "false"> +<!ATTLIST text:user-defined text:name %string; #REQUIRED> + +<!ELEMENT text:print-time (#PCDATA)> +<!ATTLIST text:print-time text:fixed %boolean; "false"> +<!ATTLIST text:print-time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:print-time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:print-date (#PCDATA)> +<!ATTLIST text:print-date text:fixed %boolean; "false"> +<!ATTLIST text:print-date text:date-value %date; #IMPLIED> +<!ATTLIST text:print-date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:printed-by (#PCDATA)> +<!ATTLIST text:printed-by text:fixed %boolean; "false"> + +<!ELEMENT text:title (#PCDATA)> +<!ATTLIST text:title text:fixed %boolean; "false"> + +<!ELEMENT text:subject (#PCDATA)> +<!ATTLIST text:subject text:fixed %boolean; "false"> + +<!ELEMENT text:keywords (#PCDATA)> +<!ATTLIST text:keywords text:fixed %boolean; "false"> + +<!ELEMENT text:editing-cycles (#PCDATA)> +<!ATTLIST text:editing-cycles text:fixed %boolean; "false"> + +<!ELEMENT text:editing-duration (#PCDATA)> +<!ATTLIST text:editing-duration text:fixed %boolean; "false"> +<!ATTLIST text:editing-duration text:duration %timeDuration; #IMPLIED> +<!ATTLIST text:editing-duration style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:modification-time (#PCDATA)> +<!ATTLIST text:modification-time text:fixed %boolean; "false"> +<!ATTLIST text:modification-time text:time-value %timeInstance; #IMPLIED> +<!ATTLIST text:modification-time style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:modification-date (#PCDATA)> +<!ATTLIST text:modification-date text:fixed %boolean; "false"> +<!ATTLIST text:modification-date text:date-value %date; #IMPLIED> +<!ATTLIST text:modification-date style:data-style-name %styleName; #IMPLIED> + +<!ELEMENT text:creator (#PCDATA)> +<!ATTLIST text:creator text:fixed %boolean; "false"> + +<!ELEMENT text:conditional-text (#PCDATA)> +<!ATTLIST text:conditional-text text:condition %formula; #REQUIRED> +<!ATTLIST text:conditional-text text:string-value-if-false %string; #REQUIRED> +<!ATTLIST text:conditional-text text:string-value-if-true %string; #REQUIRED> +<!ATTLIST text:conditional-text text:current-value %boolean; "false"> + +<!ELEMENT text:hidden-text (#PCDATA)> +<!ATTLIST text:hidden-text text:condition %formula; #REQUIRED> +<!ATTLIST text:hidden-text text:string-value %string; #REQUIRED> +<!ATTLIST text:hidden-text text:is-hidden %boolean; "false"> + +<!ELEMENT text:hidden-paragraph EMPTY> +<!ATTLIST text:hidden-paragraph text:condition %formula; #REQUIRED> +<!ATTLIST text:hidden-paragraph text:is-hidden %boolean; "false"> + +<!ELEMENT text:chapter (#PCDATA)> +<!ATTLIST text:chapter text:display (name|number|number-and-name| + plain-number-and-name|plain-number) + "number-and-name"> +<!ATTLIST text:chapter text:outline-level %integer; "1"> + +<!ELEMENT text:file-name (#PCDATA)> +<!ATTLIST text:file-name text:display (full|path|name|name-and-extension) + "full"> +<!ATTLIST text:file-name text:fixed %boolean; "false"> + +<!ELEMENT text:template-name (#PCDATA)> +<!ATTLIST text:template-name text:display (full|path|name|name-and-extension| + area|title) "full"> + +<!ELEMENT text:set-page-variable EMPTY> +<!ATTLIST text:set-page-variable text:active %boolean; "true"> +<!ATTLIST text:set-page-variable text:page-adjust %integer; "0"> + +<!ELEMENT text:get-page-variable (#PCDATA)> +<!ATTLIST text:get-page-variable %numFormat;> + +<!ELEMENT text:execute-macro (#PCDATA|office:events)* > +<!ATTLIST text:execute-macro text:description %string; #IMPLIED> + + +<!ELEMENT text:dde-connection-decls (text:dde-connection-decl)*> + +<!ELEMENT text:dde-connection-decl EMPTY> +<!ATTLIST text:dde-connection-decl text:name %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:dde-application %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:dde-topic %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:dde-item %string; #REQUIRED> +<!ATTLIST text:dde-connection-decl text:automatic-update %boolean; "false"> + +<!ELEMENT text:dde-connection (#PCDATA)> +<!ATTLIST text:dde-connection text:connection-name %string; #REQUIRED> + +<!ELEMENT text:reference-ref (#PCDATA)> +<!ATTLIST text:reference-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:reference-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:sequence-ref (#PCDATA)> +<!ATTLIST text:sequence-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:sequence-ref text:reference-format (page|chapter|text|direction|category-and-value|caption|value) #IMPLIED> + +<!ELEMENT text:bookmark-ref (#PCDATA)> +<!ATTLIST text:bookmark-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:bookmark-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:footnote-ref (#PCDATA)> +<!ATTLIST text:footnote-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:footnote-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:endnote-ref (#PCDATA)> +<!ATTLIST text:endnote-ref text:ref-name %string; #REQUIRED> +<!ATTLIST text:endnote-ref text:reference-format (page|chapter|text|direction) #IMPLIED> + +<!ELEMENT text:sheet-name (#PCDATA)> + +<!ELEMENT text:page-count (#PCDATA)> +<!ATTLIST text:page-count style:num-format %string; #IMPLIED> +<!ATTLIST text:page-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:paragraph-count (#PCDATA)> +<!ATTLIST text:paragraph-count style:num-format %string; #IMPLIED> +<!ATTLIST text:paragraph-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:word-count (#PCDATA)> +<!ATTLIST text:word-count style:num-format %string; #IMPLIED> +<!ATTLIST text:word-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:character-count (#PCDATA)> +<!ATTLIST text:character-count style:num-format %string; #IMPLIED> +<!ATTLIST text:character-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:table-count (#PCDATA)> +<!ATTLIST text:table-count style:num-format %string; #IMPLIED> +<!ATTLIST text:table-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:image-count (#PCDATA)> +<!ATTLIST text:image-count style:num-format %string; #IMPLIED> +<!ATTLIST text:image-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:object-count (#PCDATA)> +<!ATTLIST text:object-count style:num-format %string; #IMPLIED> +<!ATTLIST text:object-count style:num-letter-sync %boolean; "false"> + +<!ELEMENT text:bibliography-mark (#PCDATA)> +<!ATTLIST text:bibliography-mark text:bibiliographic-type + ( article | book | booklet | conference | custom1 | custom2 | custom3 | + custom4 | custom5 | email | inbook | incollection | inproceedings | + journal | manual | mastersthesis | misc | phdthesis | proceedings | + techreport | unpublished | www ) #REQUIRED > +<!ATTLIST text:bibliography-mark text:identifier CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:address CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:annote CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:author CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:booktitle CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:chapter CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:edition CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:editor CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:howpublished CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:institution CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:journal CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:month CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:note CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:number CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:organizations CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:pages CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:publisher CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:school CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:series CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:title CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:report-type CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:volume CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:year CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:url CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom1 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom2 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom3 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom4 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:custom5 CDATA #IMPLIED> +<!ATTLIST text:bibliography-mark text:isbn CDATA #IMPLIED> + + +<!ELEMENT text:bookmark EMPTY> +<!ATTLIST text:bookmark text:name CDATA #REQUIRED> + +<!ELEMENT text:bookmark-start EMPTY> +<!ATTLIST text:bookmark-start text:name CDATA #REQUIRED> + +<!ELEMENT text:bookmark-end EMPTY> +<!ATTLIST text:bookmark-end text:name CDATA #REQUIRED> + +<!ELEMENT text:reference-mark EMPTY> +<!ATTLIST text:reference-mark text:name CDATA #REQUIRED> + +<!ELEMENT text:reference-mark-start EMPTY> +<!ATTLIST text:reference-mark-start text:name CDATA #REQUIRED> + +<!ELEMENT text:reference-mark-end EMPTY> +<!ATTLIST text:reference-mark-end text:name CDATA #REQUIRED> + +<!ELEMENT text:footnotes-configuration (text:footnote-continuation-notice-forward?,text:footnote-continuation-notice-backward?)> +<!ATTLIST text:footnotes-configuration style:num-prefix %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration style:num-suffix %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration style:num-format %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration style:num-letter-sync %string; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:citation-body-style-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:citation-style-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:default-style-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:master-page-name %styleName; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:start-value %integer; #IMPLIED> +<!ATTLIST text:footnotes-configuration text:footnotes-position (document|page) "page"> +<!ATTLIST text:footnotes-configuration text:start-numbering-at (document|chapter|page) "document"> + +<!ELEMENT text:footnote-continuation-notice-forward (#PCDATA)> +<!ELEMENT text:footnote-continuation-notice-backward (#PCDATA)> + +<!ELEMENT text:endnotes-configuration EMPTY> +<!ATTLIST text:endnotes-configuration style:num-prefix %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration style:num-suffix %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration style:num-format %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration style:num-letter-sync %string; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:start-value %integer; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:citation-style-name %styleName; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:citation-body-style-name %styleName; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:default-style-name %styleName; #IMPLIED> +<!ATTLIST text:endnotes-configuration text:master-page-name %styleName; #IMPLIED> + +<!-- Validity constraint: text:footnote and text:endnote elements may not + contain other text:footnote or text:endnote elements, even though the DTD + allows this (via the %text; in the foot-/endnote-body). + Unfortunatetly, this constraint cannot be easily specified in the DTD. +--> +<!ELEMENT text:footnote (text:footnote-citation, text:footnote-body)> +<!ATTLIST text:footnote text:id ID #IMPLIED> + +<!ELEMENT text:footnote-citation (#PCDATA)> +<!ATTLIST text:footnote-citation text:label %string; #IMPLIED> + +<!ELEMENT text:footnote-body (text:h|text:p| + text:ordered-list|text:unordered-list)*> + +<!ELEMENT text:endnote (text:endnote-citation, text:endnote-body)> +<!ATTLIST text:endnote text:id ID #IMPLIED> + +<!ELEMENT text:endnote-citation (#PCDATA)> +<!ATTLIST text:endnote-citation text:label %string; #IMPLIED> + +<!ELEMENT text:endnote-body (text:h|text:p| + text:ordered-list|text:unordered-list)*> + +<!ENTITY % sectionText "(text:h|text:p|text:ordered-list| + text:unordered-list|table:table|chart:chart|draw:page| + draw:a|draw:text-box|draw:image|text:section| + text:table-of-content|text:illustration-index| + text:table-index|text:object-index|text:user-index| + text:alphabetical-index|text:bibliography| + text:index-title|%change-marks;)*"> + +<!ELEMENT text:section ((text:section-source|office:dde-source)?, + %sectionText;) > + +<!ATTLIST text:section text:name CDATA #REQUIRED> +<!ATTLIST text:section text:style-name %styleName; #IMPLIED> +<!ATTLIST text:section text:display (true|none|condition) "true"> +<!ATTLIST text:section text:condition %formula; #IMPLIED> +<!ATTLIST text:section text:protected %boolean; "false"> +<!ATTLIST text:section text:protection-key CDATA #IMPLIED> + +<!ELEMENT text:section-source EMPTY> +<!ATTLIST text:section-source xlink:href %string; #IMPLIED> +<!ATTLIST text:section-source xlink:type (simple) #FIXED "simple"> +<!ATTLIST text:section-source xlink:show (embed) #FIXED "embed"> +<!ATTLIST text:section-source text:section-name %string; #IMPLIED> +<!ATTLIST text:section-source text:filter-name %string; #IMPLIED> + +<!ELEMENT text:table-of-content (text:table-of-content-source, + text:index-body) > +<!ATTLIST text:table-of-content text:style-name %styleName; #IMPLIED> +<!ATTLIST text:table-of-content text:protected %boolean; "false"> + +<!ELEMENT text:table-of-content-source (text:index-title-template? , + text:table-of-content-entry-template*, + text:index-source-styles* ) > +<!ATTLIST text:table-of-content-source text:outline-level %integer; #IMPLIED> +<!ATTLIST text:table-of-content-source text:use-index-marks %boolean; "true"> +<!ATTLIST text:table-of-content-source text:use-index-source-styles + %boolean; "false"> +<!ATTLIST text:table-of-content-source text:index-scope (document|chapter) + "document"> +<!ATTLIST text:table-of-content-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:table-of-content-source fo:language %string; #IMPLIED> +<!ATTLIST text:table-of-content-source fo:country %string; #IMPLIED> +<!ATTLIST text:table-of-content-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:table-of-content-entry-template (text:index-entry-chapter-number | + text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop | + text:index-entry-link-start | + text:index-entry-link-end)* > +<!ATTLIST text:table-of-content-entry-template text:outline-level + %integer; #REQUIRED> +<!ATTLIST text:table-of-content-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:illustration-index + (text:illustration-index-source, text:index-body)> +<!ATTLIST text:illustration-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:illustration-index text:protected %boolean; "false"> + +<!ELEMENT text:illustration-index-source (text:index-title-template?, + text:illustration-index-entry-template?) > +<!ATTLIST text:illustration-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:illustration-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:illustration-index-source text:use-caption %boolean; "true"> +<!ATTLIST text:illustration-index-source text:caption-sequence-name + %string; #IMPLIED> +<!ATTLIST text:illustration-index-source text:caption-sequence-format + (text|category-and-value|caption) "text"> +<!ATTLIST text:illustration-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:illustration-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:illustration-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:illustration-index-entry-template + ( text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:illustration-index-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:table-index (text:table-index-source, text:index-body)> +<!ATTLIST text:table-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:table-index text:protected %boolean; "false"> + +<!ELEMENT text:table-index-source (text:index-title-template?, + text:table-index-entry-template?) > +<!ATTLIST text:table-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:table-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:table-index-source text:use-caption %boolean; "true"> +<!ATTLIST text:table-index-source text:caption-sequence-name + %string; #IMPLIED> +<!ATTLIST text:table-index-source text:caption-sequence-format + (text|category-and-value|caption) "text"> +<!ATTLIST text:table-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:table-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:table-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:table-index-entry-template ( text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:table-index-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:object-index ( text:object-index-source, text:index-body ) > +<!ATTLIST text:object-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:object-index text:protected %boolean; "false"> + +<!ELEMENT text:object-index-source ( text:index-title-template?, + text:object-index-entry-template? ) > +<!ATTLIST text:object-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:object-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:object-index-source text:use-spreadsheet-objects + %boolean; "false"> +<!ATTLIST text:object-index-source text:use-draw-objects %boolean; "false"> +<!ATTLIST text:object-index-source text:use-chart-objects %boolean; "false"> +<!ATTLIST text:object-index-source text:use-other-objects %boolean; "false"> +<!ATTLIST text:object-index-source text:use-math-objects %boolean; "false"> +<!ATTLIST text:object-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:object-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:object-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:object-index-entry-template ( text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:object-index-entry-template text:style-name + %styleName; #REQUIRED > + +<!ELEMENT text:user-index (text:user-index-source, text:index-body) > +<!ATTLIST text:user-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:user-index text:protected %boolean; "false"> + +<!ELEMENT text:user-index-source ( text:index-title-template?, + text:user-index-entry-template*, + text:index-source-styles* ) > +<!ATTLIST text:user-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:user-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:user-index-source text:use-index-marks %boolean; "false"> +<!ATTLIST text:user-index-source text:use-graphics %boolean; "false"> +<!ATTLIST text:user-index-source text:use-tables %boolean; "false"> +<!ATTLIST text:user-index-source text:use-floating-frames %boolean; "false"> +<!ATTLIST text:user-index-source text:use-objects %boolean; "false"> +<!ATTLIST text:user-index-source text:use-index-source-styles + %boolean; "false"> +<!ATTLIST text:user-index-source text:copy-outline-level %boolean; "false"> +<!ATTLIST text:user-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:user-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:user-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:user-index-entry-template ( text:index-entry-chapter | + text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:user-index-entry-template text:outline-level %integer; #REQUIRED> +<!ATTLIST text:user-index-entry-template text:style-name %styleName; #REQUIRED> + +<!ELEMENT text:alphabetical-index (text:alphabetical-index-source, + text:index-body)> +<!ATTLIST text:alphabetical-index text:style-name %styleName; #IMPLIED> +<!ATTLIST text:alphabetical-index text:protected %boolean; "false"> + +<!ELEMENT text:alphabetical-index-source ( text:index-title-template?, + text:alphabetical-index-entry-template* ) > +<!ATTLIST text:alphabetical-index-source text:index-scope + (document|chapter) "document"> +<!ATTLIST text:alphabetical-index-source text:relative-tab-stop-position + %boolean; "true"> +<!ATTLIST text:alphabetical-index-source text:ignore-case %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:main-entry-style-name + %styleName; #IMPLIED> +<!ATTLIST text:alphabetical-index-source text:alphabetical-separators + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:combine-entries + %boolean; "true"> +<!ATTLIST text:alphabetical-index-source text:combine-entries-with-dash + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:combine-entries-with-pp + %boolean; "true"> +<!ATTLIST text:alphabetical-index-source text:use-keys-as-entries + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:capitalize-entries + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source text:comma-separated + %boolean; "false"> +<!ATTLIST text:alphabetical-index-source fo:language %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-source fo:country %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-source text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:alphabetical-index-entry-template ( text:index-entry-chapter | + text:index-entry-page-number | + text:index-entry-text | + text:index-entry-span | + text:index-entry-tab-stop )* > +<!ATTLIST text:alphabetical-index-entry-template text:outline-level + (1|2|3|separator) #REQUIRED> +<!ATTLIST text:alphabetical-index-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:alphabetical-index-auto-mark-file EMPTY> +<!ATTLIST text:alphabetical-index-auto-mark-file xlink:href CDATA #IMPLIED> +<!ATTLIST text:alphabetical-index-auto-mark-file xlink:type (simple) #FIXED "simple"> + +<!ELEMENT text:bibliography (text:bibliography-source, text:index-body) > +<!ATTLIST text:bibliography text:style-name %styleName; #IMPLIED> +<!ATTLIST text:bibliography text:protected %boolean; "false"> + +<!ELEMENT text:bibliography-source ( text:index-title-template?, + text:bibliography-entry-template* ) > + +<!ELEMENT text:bibliography-entry-template ( text:index-entry-span | + text:index-entry-tab-stop | + text:index-entry-bibliography )* > +<!ATTLIST text:bibliography-entry-template text:bibliography-type + ( article | book | booklet | conference | custom1 | custom2 | + custom3 | custom4 | custom5 | email | inbook | incollection | + inproceedings | journal | manual | mastersthesis | misc | + phdthesis | proceedings | techreport | unpublished | www ) + #REQUIRED > +<!ATTLIST text:bibliography-entry-template text:style-name + %styleName; #REQUIRED> + +<!ELEMENT text:index-body %sectionText; > + +<!-- +Validity constraint: text:index-title elements may appear only in +indices, and there may be only one text:index-title element. +--> +<!ELEMENT text:index-title %sectionText; > +<!ATTLIST text:index-title text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-title text:name %string; #IMPLIED> + +<!ELEMENT text:index-title-template (#PCDATA)> +<!ATTLIST text:index-title-template text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-chapter-number EMPTY> +<!ATTLIST text:index-entry-chapter-number text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-chapter EMPTY> +<!ATTLIST text:index-entry-chapter text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-entry-chapter text:display (name|number|number-and-name) + "number-and-name" > + +<!ELEMENT text:index-entry-text EMPTY> +<!ATTLIST text:index-entry-text text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-page-number EMPTY> +<!ATTLIST text:index-entry-page-number text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-span (#PCDATA)> +<!ATTLIST text:index-entry-span text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-bibliography EMPTY> +<!ATTLIST text:index-entry-bibliography text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-entry-bibliography text:bibliography-data-field + ( address | annote | author | bibiliographic_type | + booktitle | chapter | custom1 | custom2 | + custom3 | custom4 | custom5 | edition | editor | + howpublished | identifier | institution | isbn | + journal | month | note | number | organizations | + pages | publisher | report_type | school | + series | title | url | volume | year ) #REQUIRED> + + +<!ELEMENT text:index-entry-tab-stop EMPTY> +<!ATTLIST text:index-entry-tab-stop text:style-name %styleName; #IMPLIED> +<!ATTLIST text:index-entry-tab-stop style:leader-char %character; " "> +<!ATTLIST text:index-entry-tab-stop style:type (left|right) "left"> +<!ATTLIST text:index-entry-tab-stop style:position %length; #IMPLIED> + +<!ELEMENT text:index-entry-link-start EMPTY> +<!ATTLIST text:index-entry-link-start text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-entry-link-end EMPTY> +<!ATTLIST text:index-entry-link-end text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:index-source-styles (text:index-source-style)*> +<!ATTLIST text:index-source-styles text:outline-level %integer; #REQUIRED> + +<!ELEMENT text:index-source-style EMPTY> +<!ATTLIST text:index-source-style text:style-name %styleName; #REQUIRED> + +<!ELEMENT text:toc-mark-start EMPTY> +<!ATTLIST text:toc-mark-start text:id %string; #REQUIRED> +<!ATTLIST text:toc-mark-start text:outline-level %integer; #IMPLIED> + +<!ELEMENT text:toc-mark-end EMPTY> +<!ATTLIST text:toc-mark-end text:id %string; #REQUIRED> + +<!ELEMENT text:toc-mark EMPTY> +<!ATTLIST text:toc-mark text:string-value %string; #REQUIRED> +<!ATTLIST text:toc-mark text:outline-level %integer; #IMPLIED> + +<!ELEMENT text:user-index-mark-start EMPTY> +<!ATTLIST text:user-index-mark-start text:id %string; #REQUIRED> +<!ATTLIST text:user-index-mark-start text:outline-level %integer; #IMPLIED> +<!ATTLIST text:user-index-mark-start text:index-name %string; #IMPLIED> + +<!ELEMENT text:user-index-mark-end EMPTY> +<!ATTLIST text:user-index-mark-end text:id %string; #REQUIRED> + +<!ELEMENT text:user-index-mark EMPTY> +<!ATTLIST text:user-index-mark text:string-value %string; #REQUIRED> +<!ATTLIST text:user-index-mark text:outline-level %integer; #IMPLIED> +<!ATTLIST text:user-index-mark text:index-name %string; #IMPLIED> + +<!ELEMENT text:alphabetical-index-mark-start EMPTY> +<!ATTLIST text:alphabetical-index-mark-start text:id %string; #REQUIRED> +<!ATTLIST text:alphabetical-index-mark-start text:key1 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark-start text:key2 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark-start text:main-etry %boolean; "false"> + +<!ELEMENT text:alphabetical-index-mark-end EMPTY> +<!ATTLIST text:alphabetical-index-mark-end text:id %string; #REQUIRED> + +<!ELEMENT text:alphabetical-index-mark EMPTY> +<!ATTLIST text:alphabetical-index-mark text:string-value %string; #REQUIRED> +<!ATTLIST text:alphabetical-index-mark text:key1 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark text:key2 %string; #IMPLIED> +<!ATTLIST text:alphabetical-index-mark text:main-etry %boolean; "false"> + +<!ELEMENT text:bibliography-configuration (text:sort-key)*> +<!ATTLIST text:bibliography-configuration text:prefix %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration text:suffix %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration text:sort-by-position %boolean; "true"> +<!ATTLIST text:bibliography-configuration text:numbered-entries %boolean; "false"> +<!ATTLIST text:bibliography-configuration fo:language %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration fo:country %string; #IMPLIED> +<!ATTLIST text:bibliography-configuration text:sort-algorithm %string; #IMPLIED> + +<!ELEMENT text:sort-key EMPTY> +<!ATTLIST text:sort-key text:key ( address | annote | author | + bibiliographic_type | booktitle | chapter | custom1 | custom2 | + custom3 | custom4 | custom5 | edition | editor | howpublished | + identifier | institution | isbn | journal | month | note | number | + organizations | pages | publisher | report_type | school | series | + title | url | volume | year ) #REQUIRED> +<!ATTLIST text:sort-key text:sort-ascending %boolean; "true"> + +<!ELEMENT text:linenumbering-configuration (text:linenumbering-separator?)> +<!ATTLIST text:linenumbering-configuration text:style-name %styleName; #IMPLIED> +<!ATTLIST text:linenumbering-configuration text:number-lines %boolean; "true"> +<!ATTLIST text:linenumbering-configuration text:count-empty-lines %boolean; "true"> +<!ATTLIST text:linenumbering-configuration text:count-in-floating-frames %boolean; "false"> +<!ATTLIST text:linenumbering-configuration text:restart-numbering %boolean; "false"> +<!ATTLIST text:linenumbering-configuration text:offset %nonNegativeLength; #IMPLIED> +<!ATTLIST text:linenumbering-configuration style:num-format (1|a|A|i|I) "1"> +<!ATTLIST text:linenumbering-configuration style:num-letter-sync %boolean; "false"> +<!ATTLIST text:linenumbering-configuration text:number-position (left|rigth|inner|outer) "left"> +<!ATTLIST text:linenumbering-configuration text:increment %nonNegativeInteger; #IMPLIED> + +<!ELEMENT text:linenumbering-separator (#PCDATA)> +<!ATTLIST text:linenumbering-separator text:increment %nonNegativeInteger; #IMPLIED> + +<!ELEMENT text:script (#PCDATA)> +<!ATTLIST text:script script:language CDATA #REQUIRED> +<!ATTLIST text:script xlink:href CDATA #IMPLIED> +<!ATTLIST text:script xlink:type (simple) #FIXED "simple"> + +<!ELEMENT text:measure (#PCDATA)> +<!ATTLIST text:measure text:kind (value|unit|gap) #REQUIRED> + +<!ELEMENT text:ruby (text:ruby-base, text:ruby-text)> +<!ATTLIST text:ruby text:style-name %styleName; #IMPLIED> + +<!ELEMENT text:ruby-base %inline-text;> + +<!ELEMENT text:ruby-text (#PCDATA)> +<!ATTLIST text:ruby-text text:style-name %styleName; #IMPLIED> + +<!-- elements for change tracking --> + +<!ELEMENT text:change EMPTY> +<!ATTLIST text:change text:change-id CDATA #REQUIRED> + +<!ELEMENT text:change-start EMPTY> +<!ATTLIST text:change-start text:change-id CDATA #REQUIRED> + +<!ELEMENT text:change-end EMPTY> +<!ATTLIST text:change-end text:change-id CDATA #REQUIRED> + +<!ELEMENT text:tracked-changes (text:changed-region)*> +<!ATTLIST text:tracked-changes text:track-changes %boolean; "true"> +<!ATTLIST text:tracked-changes text:protection-key CDATA #IMPLIED> + +<!ELEMENT text:changed-region (text:insertion | + (text:deletion, text:insertion?) | + text:format-change) > +<!ATTLIST text:changed-region text:id ID #REQUIRED> + +<!ELEMENT text:insertion (office:change-info, %sectionText;)> +<!ELEMENT text:deletion (office:change-info, %sectionText;)> +<!ELEMENT text:format-change (office:change-info)> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/pdbcomparison.java b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/pdbcomparison.java new file mode 100644 index 000000000000..b5afcf3ae9fa --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/pdbcomparison.java @@ -0,0 +1,545 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: pdbcomparison.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +import java.io.*; +import java.util.*; + +public class pdbcomparison +{ + + private String LOGTAG ="LOGFILE"; + private String OUTTAG ="OUTFILE"; + private String LISTTAG ="LISTFILE"; + private String PDBTAG1 ="PDBNAME1"; + private String PDBTAG2 ="PDBNAME2"; + + private String OUTFILE="pdbcomparison.out"; + private String LOGFILE="pdbcomparison.log"; + + private String pdbarr1[]; + private String pdbarr2[]; + + + /** + * Default Constructor + * + * @param + * @return + * + */ + public void pdbcomparison() + { + } + + /** + * Prints the command line arguments for this class + * + * @param + * + * @return void + * + */ + public void usage() + { + String str = new String(); + str += "********************************************************\n"; + str += " java pdbcomparison.java <propFile> \n"; + str += " where propFile is name of Property File...\n"; + str += "********************************************************\n"; + + System.out.println(str); + + } + + /** + * This method, read the Property file and validates the + * entries in that file, and accordingly sets the log file + * output file and updates the array pdbarr1 and pdbarr2 with + * list of pdb's to be compared. + * + * @param propFile Property filename which list the log/outputfile/list/pdb + * names + * @return + * + */ + public void parsePropertyFile(String propFile) + { + Properties defaultProps = new Properties(); + + try { + FileInputStream in = new FileInputStream(propFile); + defaultProps.load(in); + in.close(); + } catch (IOException e) { + System.out.println("Could not open Property File " + propFile); + return; + } + + + String logFile = defaultProps.getProperty(this.LOGTAG); + String outFile = defaultProps.getProperty(this.OUTTAG); + String listFile = defaultProps.getProperty(this.LISTTAG); + String pdbname1 = defaultProps.getProperty(this.PDBTAG1); + String pdbname2 = defaultProps.getProperty(this.PDBTAG2); + + // validate all command line arguments + if ((listFile == null) && ((pdbname1 == null) || (pdbname2 == null))) + { + System.out.println("Missing listFile or missing pdb filenames in Property file " + propFile); + return; + } + + if (logFile == null || logFile.length() == 0) + logFile = this.LOGFILE; + + if (outFile == null || outFile.length() == 0) + outFile = this.LOGFILE; + + + // validate log and output files + if (! validateAndCreateFile(logFile)) return; + if (! validateAndCreateFile(outFile)) return; + LOGFILE = logFile; + OUTFILE = outFile; + + System.out.println("Output is written to log file... " + LOGFILE); + if (listFile != null) + { + if (! checkFile(listFile)) return; + populatePDBArray(listFile); + } else { + if (! checkFile(pdbname1)) return; + if (! checkFile(pdbname2)) return; + populatePDBArray(pdbname1, pdbname2); + } + } + + /** + * This method validates if the file passed exists. + * If it does , then it is moved to <filename>.bak and then creates a newFile. + * Also validates permissions to create. + * + * @param filename name of file to be created + * @return true, if file could be created + * false, if could not. + * + */ + private boolean validateAndCreateFile (String filename) + { + if (filename == null) return false; + + File f = null; + try { + f = new File(filename); + } catch (NullPointerException e) { + System.out.println("Could not create a File object for file " + filename); + return false; + } + + if (f.exists()) + { + String newFile = filename + ".bak"; + File newF=null; + try { + newF = new File(newFile); + } catch (Exception ex) { + System.out.println("Could not get File Object instance for " + newFile); + return false; + } + + if (newF.exists()) + { + try { + newF.delete(); + } catch ( SecurityException se) { + System.out.println("Could not get delete " + newFile); + return false; + } + } + + try { + if (! f.renameTo(newF)) + { + System.out.println("Could not rename " + filename + " to " + newFile ); + return false; + } + } catch (SecurityException s) { + System.out.println("SecurityException: " + s.toString()); + return false; + } catch (NullPointerException n) { + System.out.println("NullPointerException: " + n.toString()); + return false; + } + } else { + try { + if (! f.createNewFile()) + { + System.out.println("Could not create " + filename + " Check permissions.."); + return false; + } + } catch (IOException e) { + System.out.println("IOException: " + e.toString()); + return false; + } catch (SecurityException s) { + System.out.println("SecuriityException: " + s.toString() ); + return false; + } + + } + + return true; + + } + + /** + * This method validates if the file exists and is readable + * + * @param filename name of file to be created + * @return true, if file exists and is readable + * false, if not. + * + */ + private boolean checkFile(String filename) + { + if (filename == null) return false; + + File f = null; + try { + f = new File(filename); + } catch (NullPointerException e) { + System.out.println("Could not create a File object for file " + filename); + return false; + } + + if (! f.exists()) + { + System.out.println("File " + filename + " does not exist... "); + return false; + } + + if (! f.canRead()) + { + System.out.println("Cannot read file " + filename); + return false; + } + + return true; + + } + + /** + * This method populates the pdb arrays with the names of the pdbs to + * compare. Ths listFile lists a series of entries, wherein each + * line indicates the PDB names to be compared. + * <pdbname1>=<pdbname2> + * + * @param listFile name of the listfile + * @return + * + */ + private void populatePDBArray(String listFile) + { + // open ListFile and populate the PDB list to be compared + if (listFile != null) + { + Properties listProps = new Properties(); + try { + FileInputStream in = new FileInputStream(listFile); + listProps.load(in); + in.close(); + } catch (IOException ex) { + System.out.println("Could not open List File " + listFile); + return; + } + + pdbarr1 = new String[listProps.size()]; + pdbarr2 = new String[listProps.size()]; + Enumeration e = listProps.keys(); + int j=0; + while (e.hasMoreElements()) + { + pdbarr1[j] = (String)e.nextElement(); + pdbarr2[j] = listProps.getProperty(pdbarr1[j]); + j++; + } + + } + } + + /** + * This method populates the pdb arrays with the names of the pdbs to + * compare. + * + * @param pdbname1 Name of 2nd PDB file to be compared + * @param pdbname2 Name of 2nd PDB file to be compared + * @return + * + */ + private void populatePDBArray(String pdbname1, String pdbname2) + { + if (pdbname1 == null) return; + if (pdbname2 == null) return; + + if ((pdbname1 != null) && (pdbname2 != null)) + { + pdbarr1 = new String[1]; + pdbarr2 = new String[1]; + + pdbarr1[0] = pdbname1; + pdbarr2[0] = pdbname2; + } + } + + /** + * This method populates the pdb arrays with the names of the pdbs to + * compare. + * + * @param arrayno Array number which corresponds to the pdb array + * containing list of pdbs + * If 1 then send pdbarr1, if 2 send pdbarr2 else null + * + * @return PDB string array containing list of PDB's + * + */ + private String[] getPDBArray(int arrayno) + { + if (arrayno == 1) return pdbarr1; + if (arrayno == 2) return pdbarr2; + + return null; + } + + /** + * This method comares 2 PDB's and returns true if comparison is equal. + * It uses the PDB Decoder class to decode to a PDB structure and then + * does record comparison + * + * @param pdbname1 Name of one PDB file to be compared + * @param pdbname2 Name of other PDB file to be compared + * + * @return returns true if both PDB's are equal else returns false + * + */ + private boolean comparePDB(String pdbname1, String pdbname2) + { + PalmDB pdb1=null, pdb2=null; + PDBDecoder decoder = new PDBDecoder(); + try { + pdb1 = decoder.parse(pdbname1); + } catch (Exception e) { + System.out.println("Could not parse PDB " + pdbname1); + return false; + } + + try { + pdb2 = decoder.parse(pdbname2); + } catch (Exception e) { + System.out.println("Could not parse PDB " + pdbname2); + return false; + } + + if (pdb1.equals(pdb2)) { + writeToLog("PDB " + pdbname1 + " and PDB " + pdbname2 + " are equal"); + + return true; + } else { + writeToLog("PDB " + pdbname1 + " and PDB " + pdbname2 + " are not equal"); + return false; + } + } + + + + /** + * Write message to LOGFILE + * + * @param msg Message to be written to log file + * @return + * + */ + private void writeToLog(String msg) + { + if (msg == null) return; + + // Get Output Stream from Log file + RandomAccessFile raf=null; + try { + raf = new RandomAccessFile(LOGFILE, "rw"); + } catch (Exception e) { + System.out.println ("Could not open file " + LOGFILE); + return; + } + + try { + long len = raf.length(); + raf.seek(len); + raf.write(msg.getBytes()); + raf.write("\n".getBytes()); + } catch (IOException e) { + System.out.println("ERROR: Could not write to File " + LOGFILE); + return; + } + } + + /** + * Write status of comparison to OUTFILE + * + * @param status Indicates whether comparsion of PDB's PASSED or FAILED + * @param pdbname1 file name of pdb which was compared. + * @param pdbname2 file name of pdb which was compared. + * + * @return + * + */ + private void writeToOutputFile(String status, String pdbname1, String pdbname2) + { + if (status == null) return; + if (pdbname1 == null) return; + if (pdbname2 == null) return; + + String msg = pdbname1 + "=" + pdbname2 + ":" + status; + + // Get Output Stream from Log file + RandomAccessFile raf=null; + try { + raf = new RandomAccessFile(OUTFILE, "rw"); + } catch (Exception e) { + System.out.println ("Could not open file " + OUTFILE); + return; + } + + try { + long len = raf.length(); + raf.seek(len); + + raf.write(msg.getBytes()); + raf.write("\n".getBytes()); + } catch (IOException e) { + System.out.println("ERROR: Could not write to File " + OUTFILE); + return; + } + + try { + raf.close(); + } catch (Exception e) { + System.out.println("ERROR: Could not close File " + OUTFILE); + return; + } + + } + + + + /** + * Main starting block of execution + * + * @param command line args captured in an array of Strings + * @return + * + */ + public static void main(String args[]) + { + + Date startTime = new Date(); + pdbcomparison pdbcmp = new pdbcomparison(); + int nargs = args.length; + int status=0; + + if (nargs != 1) + { + System.out.println("Incorrect no. of arguments passed..."); + pdbcmp.usage(); + System.exit(-1); + + } + + String propFile = args[0]; + + File f=null; + try { + f = new File(propFile); + } catch (Exception e) { + System.out.println("Exception: Could not open file " + propFile); + System.exit(-1); + } + + if (! f.canRead()) { + System.out.println("Exception: " + propFile + " is not a file "); + System.exit(-1); + } + + if (! f.canRead()) { + System.out.println("Exception: Cannot open file for reading. Please check permissions "); + System.exit(-1); + } + + // parse Property file + pdbcmp.parsePropertyFile(propFile); + + String pdbarr1[] = pdbcmp.getPDBArray(1); + String pdbarr2[] = pdbcmp.getPDBArray(2); + if ( (pdbarr1 == null) || + (pdbarr2 == null) || + (pdbarr1.length == 0) || + (pdbarr1.length == 0)) + { + System.out.println("pdbArray is empty. No PDBS to compare... \n"); + System.exit(-1); + } + + + pdbcmp.writeToLog("************** Start *****************"); + pdbcmp.writeToLog("PDB Comparison: start time " + startTime); + for (int i=0; i<pdbarr1.length; i++) + { + Date pdb_startTime = new Date(); + pdbcmp.writeToLog("\n"); + pdbcmp.writeToLog("start time " + pdb_startTime); + boolean val = pdbcmp.comparePDB(pdbarr1[i], pdbarr2[i]); + Date pdb_endTime = new Date(); + pdbcmp.writeToLog("end time " + pdb_endTime); + + if (val) { + pdbcmp.writeToOutputFile("PASSED", pdbarr1[i], pdbarr2[i]); + status=0; + } else { + pdbcmp.writeToOutputFile("FAILED", pdbarr1[i], pdbarr2[i]); + status=-1; + } + } + + Date endTime = new Date(); + pdbcmp.writeToLog("PDB Comparison: end time " + endTime); + pdbcmp.writeToLog("************** End *****************n"); + pdbcmp.writeToLog("\n"); + + System.exit(status); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Doc_descriptions.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Doc_descriptions.sxc Binary files differnew file mode 100644 index 000000000000..ba6817d889ac --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Doc_descriptions.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Spreadsheet_descriptions.csv b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Spreadsheet_descriptions.csv new file mode 100644 index 000000000000..c798a553e78f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Spreadsheet_descriptions.csv @@ -0,0 +1,39 @@ +File|Test Name|Description +c_addition.sxc|| +c_alignment.sxc|| +c_backwardrange.sxc|| +c_boolean.sxc|| +c_cellcurrencyalue.sxc|| +c_cellfloatvalue.sxc|| +c_cellpercentvalue.sxc|| +c_cellstringvalue.sxc|| +c_cellvalue.sxc|| +c_changetracking.sxc|| +c_character.sxc|| +c_chart.sxc|| +c_check.sxc|| +c_columnswidth.sxc|| +c_cyclic.sxc|| +c_dividebyzero.sxc|| +c_dividefloating.sxc|| +c_emptysheet.sxc|| +c_filter.sxc|| +c_forwardrange.sxc|| +c_hiddenrow.sxc|| +c_insertimage.sxc|| +c_invalidcellref.sxc|| +c_largerange.sxc|| +c_listrange.sxc|| +c_mathematical.sxc|| +c_null.sxc|| +c_protection.sxc|| +c_renamedsheets.sxc|| +c_rowheight.sxc|| +c_rowstyles.sxc|| +c_sheetreference.sxc|| +c_simpleformula.sxc|| +c_smallrange.sxc|| +c_styles.sxc|| +c_sumbackward.sxc|| +c_sumforward.sxc|| +c_threeemptysheet.sxc|| diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Spreadsheet_descriptions.sxc b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Spreadsheet_descriptions.sxc Binary files differnew file mode 100644 index 000000000000..7e9d37d3fa50 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/docs/Spreadsheet_descriptions.sxc diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/lib/converterlib.pm b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/lib/converterlib.pm new file mode 100755 index 000000000000..a504dca86bb9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/lib/converterlib.pm @@ -0,0 +1,1176 @@ +#!/usr/bin/perl +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: converterlib.pm,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#################################################################### +# File Name: converterlib.pm +# Version : 1.0 +# Project : XMerge +# Author : Brian Cameron +# Date : 5th Sept. 2001 +# +# This script enters text at position x,y on screen. +# +# Parameter +# x-coordinate +# y-coordinate +# Text to enter +# +########################################################################## + +use EmRPC; # EmRPC::OpenConnection, CloseConnection +use EmFunctions; +use EmUtils; + +# Set global_debug flag +# +$global_debug = $ENV{'ZENDEBUG'}; +#$em_script_home = "/export/home/test/qadir/bin"; +$em_script_home = $ENV{'EM_SCRIPT_HOME'}; +#$qa_script_home = "/export/home/test/qadir/qa-new/bin"; + $qa_script_home = $ENV{'QA_SCRIPT_HOME'}; +# +# CONVERT FUNCTIONS +# + +# convert_to_pdb +# directory - directory containing the xml-orig and pdb-orig +# subdirectories. +# file - file to convert +# extension - extension of file to convert (sxw or sxc) +# convert_to - what PDB format to convert into. +# +# Returns 0 if success, -1 otherwise. +# +# Converts file from XML to PDB +# +sub convert_to_pdb +{ + my $directory = $_[0]; + my $file = $_[1]; + my $extension = $_[2]; + my $convert_to = $_[3]; + my $pdb_directory = $_[4]; + my $rc = 0; + my $xmlfile = "$directory/$file.$extension"; + my $pdbdir = "$pdb_directory"; + + &enter_func("convert_to_pdb"); + + if (! -f "$xmlfile") + { + print "\nERROR, file $xmlfile does not exist\n"; + $rc = -1; + } + if (! -d "$pdbdir") + { + print "\nERROR, directory $directory/pdb-orig does not exist\n"; + $rc = -1; + } + + if ($rc != -1) + { + if ("$convert_to" eq "application/x-minicalc") + { + # Move all files over. + # + my $i = 1; + + while (-f "$pdbdir/$file-Sheet$i.pdb") + { + my $pdbfile = "$pdbdir/$file-Sheet$i.pdb"; + + print "\n"; + + if (-f "$pdbfile.old") + { + print "Removing $pdbfile.old\n"; + `/bin/rm -f $pdbfile.old`; + } + + print "Moving $pdbfile file to $pdbfile.old\n"; + `mv "$pdbfile" "$pdbfile.old"`; + + $i++; + } + } + else + { + if (-f "$pdbdir/$file.pdb") + { + print "\n"; + + if (-f "$pdbdir/$file.pdb.old") + { + print "Removing $pdbdir/$file.pdb.old\n"; + `/bin/rm -f $pdbdir/$file.pdb.old`; + } + + print "Moving $pdbdir/$file.pdb file to $pdbdir/$file.pdb.old\n"; + `mv "$pdbdir/$file.pdb" "$pdbdir/$file.pdb.old"` + } + } + + &start_rd($extension, $convert_to, $xmlfile, ""); + + if ("$convert_to" eq "application/x-minicalc") + { + # Must handle minicalc separately since it can + # convert to multiple files with this file name + # convention. + # + print "Moving $file-Sheet*.pdb files to $pdbdir\n"; + `mv $file-Sheet*.pdb $pdbdir`; + `chmod 666 $pdbdir/$file-*.pdb`; + } + else + { + print "Moving $file.pdb file to $pdbdir\n"; + `mv $file.pdb $pdbdir`; + `chmod 666 $pdbdir/$file.pdb`; + } + } + + &leave_func("convert_to_pdb"); + + return $rc; +} + +# convert_to_xml +# xmldir - directory to contain the xml output. +# xmlorigdir - directory to contain the xml input (used for merge) +# pdbfile - file to convert +# convert_from - what PDB format to convert from. +# extension - extension of file to convert (sxw or sxc) +# output - output filename to create +# merge_opt - 1 if convert and merge, 0 if convert only +# +# Returns 0 if success, -1 otherwise. +# +# Converts file from PDB to XML +# +sub convert_to_xml +{ + my $xmldir = $_[0]; + my $xmlorigdir = $_[1]; + my $pdbfile = $_[2]; + my $convert_from = $_[3]; + my $extension = $_[4]; + my $output = $_[5]; + my $merge_opt = $_[6]; + my $rc = 0; + + &enter_func("convert_to_xml"); + + my @args = split(/ /,$pdbfile); + + for ($i=0;$i <= $#args; $i++) + { + if (! -f "@args[$i]") + { + print "\nERROR, file $pdbfile does not exist\n"; + $rc = -1; + } + } + + if (! -f "$xmlorigdir/$output.$extension") + { + print "\nERROR, file $xmlorigdir/$output.$extension does not exist\n"; + $rc = -1; + } + if (! -d "$xmldir") + { + print "\nERROR, directory $xmlorigdir does not exist\n"; + $rc = -1; + } + if (! -d "$xmlorigdir") + { + print "\nERROR, directory $xmldir does not exist\n"; + $rc = -1; + } + + if ($rc != -1) + { + if ($merge_opt == 1) + { + print "Copying <$xmlorigdir/$output.$extension> to <$xmldir>\n"; + `cp $xmlorigdir/$output.$extension $xmldir/`; + + my $check_stamp = (stat("$xmldir/$output.$extension"))[9]; + + &start_rd($convert_from, $extension, $pdbfile, + "$xmldir/$output.$extension"); + + + # No need to move the file to the $xmldir since the merge + # argument specifies the output file. + + my $check_stamp_update = (stat("$xmldir/$output.$extension"))[9]; + if ($check_stamp eq $check_stamp_update) + { + print "\nERROR, Problem while merging <$xmldir/$output.$extension>\n"; + `mv $xmldir/$output.$extension $xmldir/$output.$extension.err`; + } + } + else + { + &start_rd($convert_from, $extension, $pdbfile, ""); + + print "Moving $output.$extension to $xmldir\n"; + `mv $output.$extension $xmldir`; + `chmod 666 $xmldir/$output.$extension`; + } + } + + &leave_func("convert_to_xml"); + + return $rc; +} + +# start_rd +# from - format to convert from +# to - format to convert to +# file - file to convert +# merge - merge filename ("" indicates convert-only with no merge) +# +# converts file from/to the specified formats. +# +sub start_rd +{ + my $from = $_[0]; + my $to = $_[1]; + my $file = $_[2]; + my $merge = $_[3]; + + print "\nConverting from $from to $to.\n"; + if ($global_debug) + { + &print_debug ("rd command is:\n"); + } + + if ($merge eq "") + { + &print_debug (" $em_script_home/rd -from $from -to $to $file\n"); + print "\nConverting from $from to $to with no merge.\n"; + `$em_script_home/rd -from $from -to $to $file`; + } + else + { + &print_debug (" $em_script_home/rd -from $from -to $to -merge $merge $file\n"); + print "\nConverting from $from to $to with merge.\n"; + `$em_script_home/rd -from $from -to $to -merge $merge $file`; + } + + print "Done converting.\n\n"; +} + +# +# POSE INTERACTION FUNCTIONS +# + +# open_connection +# display_debug - debug will be displayed if not 0 +# +# Opens the connection to pose. +# +sub open_connection +{ + my $display_debug = $_[0]; + my $rc; + + EmRPC::OpenConnection(6415, "localhost"); + + if ($display_debug && $global_debug) + { + print "\nPose Connection Opened\n"; + } +} + +# close_connection +# display_debug - debug will be displayed if not 0 +# +# Closes the connection to pose. +# +sub close_connection +{ + my $display_debug = $_[0]; + + EmRPC::CloseConnection(); + + if ($display_debug && $global_debug) + { + print "\nPose Connection Closed\n"; + } +} + +# start_pose +# pose_exe - name of pose executable. +# apps_load - The PRC files to load into pose, can be a comma +# separated list. +# run_prog - Program to run at startup. +# timeout - Timeout value to use when starting pose. +# +# Starts the Palm OS Emulator, loads PRC files, and starts +# a program. +# +sub start_pose +{ + my $pose_exe = $_[0]; + my $sessionfile = $ENV{'EM_SESSION_FILE'}; + my $romfile = $ENV{'EM_ROM_FILE'}; + my $apps_load = $_[1]; + my $run_prog = $_[2]; + my $timeout = $_[3]; + my $stay_in_loop = 1; + my $address; + my $title; + my $form; + my $label_id; + my $num_objects; + my $i; + my $ii; + my $rc = 1; + + my $pose_cmd = "$pose_exe "; + $pose_cmd .= " -psf $sessionfile "; + $pose_cmd .= "-load_apps $apps_load "; + $pose_cmd .= "-run_app $run_prog"; + +# It is more effective to use the -psf argument to +# set these values. +# +# $pose_cmd .= -rom $romfile "; +# $pose_cmd .= "-ram_size 8192 "; +# $pose_cmd .= "-device PalmVx "; + + &enter_func("start_pose"); + + if ($global_debug) + { + &print_debug("\n"); + &print_debug("pose command is:\n"); + &print_debug(" $pose_cmd\n"); + } + + print "\nLaunching pose...\n"; + system ("$pose_cmd &"); + + # Give time for pose to get started... + # + for ($i=0; $i < $timeout; $i++) + { + $tmp = $i + 1; + print "$tmp\n"; + + # Do not use pose_sleep here + # + sleep(1); + } + + # Verify pose started successfully, and fail otherwise... + # + $rc = &verify_pose(5); + if ($rc != 0) + { + $stay_in_loop = 0; + } + else + { + # Sleep before opening the connection again, after testing in + # the verify_pose function. + # + pose_sleep(2); + &open_connection(1); + print "\nChecking if the appropriate window is on screen...\n"; + } + + # Stop looping when the specified window has started. + # + for ($i=0; $i < $timeout && $stay_in_loop == 1; $i++) + { + $form = FrmGetActiveForm(); + $num_objects = FrmGetNumberOfObjects($form); + + for $ii (0..$num_objects - 1) + { + my ($object_type) = FrmGetObjectType($form, $ii); + + if ("$run_prog" eq "Quickword") + { + if ($object_type == frmTitleObj) + { + ($address, $title) = FrmGetTitle($form,); + + # Display count and title. + # + $tmp = $i + 1; + print "$tmp - title is $title\n"; + + if ("$title" eq "Quickword") + { + $stay_in_loop = 0; + $rc = 0; + last; + } + } + } + elsif ("$run_prog" eq "MiniCalc") + { + if ($object_type == frmLabelObj) + { + $label_id = FrmGetObjectId ($form, $ii); + ($address, $label) = FrmGetLabel($form, $label_id); + + # Display count and label. + # + $tmp = $i + 1; + print "$tmp - label is $label\n"; + if ("$label" =~ "Solutions In Hand") + { + $stay_in_loop = 0; + $rc = 0; + last; + } + } + } + } + + # Do not use pose_sleep here + # + sleep(1); + } + + # Do not use pose_sleep here + # + sleep(1); + + &leave_func("start_pose"); + return($rc); +} + +# kill_pose +# +# Kills all pose processes +# +sub kill_pose +{ + if ($global_debug) + { + print "Stopping pose process...\n"; + } + + `pkill pose`; +} + +# verify_pose +# timeout - timeout to wait for pose +# +# Tries to do a connect/close to Pose to see if +# it is working okay. +# +sub verify_pose +{ + my $timeout = $_[0]; + my $rc = 0; + + $rc = system("$em_script_home/verify_sane.pl $timeout"); + return $rc; +} + +# db_export +# dbname - Name of database to export +# +# Exports a palmdb file to /tmp +# +sub db_export +{ + my $dbname = $_[0]; + + &enter_func("db_export"); + print "\nExporting PDB file <$dbname> from pose\n"; + &pose_tap_pen(22, 20, 2); + &pose_tap_pen (15, 85, 2); + &enter_string($dbname, 1); + &pose_tap_pen (15, 126, 1); + &enter_string("/tmp/", 1); + &pose_tap_button("OK", 4); + &tap_applications(3); + print "Export of PDB file <$dbname> completed.\n"; + &leave_func("db_export"); +} + +# +# QUICKWORD SPECIFIC +# + +# start_quickword +# +# Assuming pose was launched with the -run_app flag to launch +# QuickWord on startup, this starts up QuickWord with the first +# file in the list and turns off write-protect. +# +sub start_quickword +{ + &enter_func("start_quickword"); + + # This will open the first file in the list. + # Assuming this will always be the case. + # + &pose_tap_pen(20, 18, 1); + &quickword_press_write_protect(); + + &leave_func("start_quickword"); +} + +# quickword_press_write_protect +# +# Useful function for pressing the write protect button +# to allow changes to be made. +# +sub quickword_press_write_protect +{ + &enter_func("quickword_press_write_protect"); + + my ($form) = FrmGetActiveForm(); + my ($num_objects) = FrmGetNumberOfObjects($form); + + for $ii (0..$num_objects - 1) + { + my ($object_type) = FrmGetObjectType($form, $ii); + + # The write protect button is the only frmGadgetObj + # on the QuickWord screen. + # + if ($object_type == frmGadgetObj) + { + my (%bounds) = FrmGetObjectBounds($form, $ii); + + if ($global_debug) + { + &print_debug(" Found QuickWord WriteProtect button\n"); + &print_debug(" left = $bounds{left}\n"); + &print_debug(" right = $bounds{right}\n"); + &print_debug(" top = $bounds{top}\n"); + &print_debug(" bottom = $bounds{bottom}\n"); + } + + # For some reason, the tapping of the write-protect button + # doesn't work unless you tap somewhere else first. + # + &pose_sleep(1); + &pose_tap_pen($bounds{left} + 2, $bounds{top} + 2, 1); + last; + } + } + + &leave_func("quickword_press_write_protect"); +} + +# quickword_find_replace +# from_string - string to replace +# to_string - string to replace with +# +# Uses QuickWord's find/replace utility to replace +# one string with another. +# +sub quickword_find_replace +{ + my $from_string = $_[0]; + my $to_string = $_[1]; + + &enter_func("quickword_find_replace"); + + # Move cursor to beginning... + # + &quickword_tap_at_top(1); + + # Move to "Find" field: + # Triple-click to highlight all the text in the field, + # so it is removed when the string is entered... + # + &pose_tap_button("Find", 2); + &pose_tap_pen(50, 100, 0); + &pose_tap_pen(50, 100, 0); + &pose_tap_pen(50, 100, 1); + + # sleep for 2 seconds to avoid double click after moving + # to replace field + # + &enter_string("$from_string", 2); + + # Move to "Replace" field: + # Triple-click to highlight all the text in the field, + # so it is removed when the string is entered... + # + &pose_tap_pen(50, 120, 0); + &pose_tap_pen(50, 120, 0); + &pose_tap_pen(50, 120, 1); + &enter_string("$to_string", 1); + + # Do find, then replace... + # + &pose_tap_button("Find", 1); + &pose_tap_button("Replace", 1); + &pose_tap_button("Cancel", 1); + + &leave_func("quickword_find_replace"); +} + +# quickword_tap_at_top +# secs - seconds to sleep after the tap +# +# Tap's at the top of the QuickWord document. +# +sub quickword_tap_at_top +{ + my $secs = $_[0]; + + &enter_func("quickword_tap_at_top"); + + # Sleep for a second to avoid any double-clicks + # from happening. + # + &pose_sleep(1); + + &pose_tap_pen(0, 15, $secs); + &leave_func("quickword_tap_at_top"); +} + +# Saves file and returns to the Application list. +# +sub close_quickword +{ + &enter_func("close_quickword"); + + &pose_tap_button("Done", 2); + &tap_applications(2); + + &leave_func("close_quickword"); +} + +# +# MINICALC SPECIFIC +# + +# start_minicalc +# +# Assuming pose was launched with the -run_app flag to launch +# Minicalc on startup, this starts up Minicalc with the first +# file in the list. +# +sub start_minicalc +{ + &enter_func("start_minicalc"); + &pose_tap_button("OK", 1); + + # For now just tap on the first spreadsheet. Add support + # for multiple sheets later. + # + &pose_tap_pen(10, 40, 5); + + &leave_func("start_minicalc"); +} + +# close_minicalc +# +# Returns to the Application list (no need to save). +# +sub close_minicalc +{ + &enter_func("close_minicalc"); + &tap_applications(3); + &leave_func("close_minicalc"); +} + +# minicalc_enter_cell +# row - row to enter value, starting with 1 +# col - column to enter value, starting with 1 +# val - value to enter +# +# Only valid for minicalc. +# +# This only works if the val passed in has a '\n' at the +# end. +# +sub minicalc_enter_cell +{ + my $row = $_[0]; + my $col = $_[1]; + my $val = $_[2]; + my $i; + my $j; + + &enter_func("minicalc_enter_cell"); + + if ($global_debug) + { + &print_debug (" tapping to cell row=<$row> col=<$col>\n"); + } + + # Tap pen on home button to start with row=1, col=A + # at top left. + # + pose_tap_pen(1, 1, 3); + + # Now the cell should be in the top-left corner, + # so click there. However we must first click + # in another cell or pose doesn't acknowledge the + # click. + # + # pose_tap_pen(120, 95, 1); + # pose_tap_pen(21, 9, 1); + + # Click the down button once for each row. + # Must pause 3 seconds each time, otherwise MiniCalc + # will not keep up. + # + for ($i=0; $i < $row; $i++) + { + if ($global_debug) + { + &print_debug (" Typing carrage return to go down\n"); + } + enter_string("\n", 1); + } + + # Click the right button once for each col. + # Must pause 3 seconds each time, otherwise MiniCalc + # will not keep up. + # + for ($i=0; $i < $col; $i++) + { + if ($global_debug) + { + &print_debug (" Typing tab to go right\n"); + } + + enter_string("\t", 1); + } + + # enter string + # + &enter_string($val, 1); + + &leave_func("minicalc_enter_cell"); +} + +# +# GENERIC UTILIIES (pose) +# + +# tap_applications +# secs - seconds to sleep after the tap +# +# taps pen on the Applications button. +# +sub tap_applications +{ + my $secs = $_[0]; + + &enter_func("tap_applications"); + + &pose_tap_pen(15, 170, 1); + &pose_tap_pen(155, 10, 1); + &pose_tap_pen(155, 10, $secs); + + &leave_func("tap_applications"); +} + +# enter_string_at_location +# x - x-location to enter string +# y - y-location to enter string +# in_string - string to enter +# application - appliation (QUICKWORD or MINICALC) +# +# Enters a string at the specified x,y position. +# +sub enter_string_at_location +{ + my $x_val = $_[0]; + my $y_val = $_[1]; + my $in_string = $_[2]; + my $application = $_[3]; + my $x; + my $y; + + &enter_func("enter_string_at_location"); + + $x = $x_val; + $y = $y_val; + + if ($application eq "QUICKWORD") + { + # Allow users to specify TOP/BOTTOM/LEFT/RIGHT + # for QuickWord. + # + if ($y_val eq "TOP") + { + if ($global_debug) + { + &print_debug(" Converting TOP to 15\n"); + } + + $y = 15; + } + if ($y_val eq "BOTTOM") + { + if ($global_debug) + { + &print_debug(" Converting BOTTOM to 144\n"); + } + + $y = 144; + } + if ($x_val eq "LEFT") + { + if ($global_debug) + { + &print_debug(" Converting LEFT to 0\n"); + } + + $x = 0; + } + if ($x_val eq "RIGHT") + { + if ($global_debug) + { + &print_debug(" Converting RIGHT to 152\n"); + } + + $x = 152; + } + } + + # Just to make sure the offset isn't outside the + # proper area. + # + if ($x >= 100) + { + $offset = -2; + } + else + { + $offset = 2; + } + + &off_tap_pen($x, $y, $offset); + &enter_string($in_string, 1); + + &leave_func("enter_string_at_location"); +} + +# off_tap_pen +# x - x-location to tap +# y - y-location to tap +# offset - x-offset to use for first tap. +# +# For some reason, pose does not register a single +# pen tap if the last single pen tap was also +# at the same x,y coordinate (even if the last tap +# was a while ago). So this function does two +# slightly different pen taps to ensure then pen +# tap happens. +# +sub off_tap_pen +{ + my $x = $_[0]; + my $y = $_[1]; + my $offset = $_[2]; + + &enter_func("off_tap_pen"); + + # sleep for 2 seconds to avoid double-click. + # + &pose_tap_pen_hard($x + $offset, $y, 2); + &pose_tap_pen_hard($x, $y, 1); + + &leave_func("off_tap_pen"); +} + +# enter_string +# in_string - string to enter +# secs - seconds to sleep after entering the string +# +# Enters a string +# +sub enter_string +{ + my $in_string = $_[0]; + my $secs = $_[1]; + my $j; + + &enter_func("enter_string"); + + if ($global_debug) + { + # Display in_string so \n and \t values + # show up as normal ASCII. + # + if ($in_string eq "\n") + { + &print_debug(" Entering string : <\\n>\n"); + } + elsif ($in_string eq "\t") + { + &print_debug(" Entering string : <\\t>\n"); + } + else + { + &print_debug(" Entering string : <$in_string>\n"); + } + } + + # Replace "\n" with real carrage returns. + # + my $string_val = $in_string; + $string_val =~ s#\\n#\n#g; + + # Replace "\t" with a real tab. + # + $string_val =~ s#\\t#\t#g; + + # Convert string to ASCII numeric values + # + my @array = unpack("C*", $string_val); + + # Enter string one key at a time. + # + for ($j=0; $j <= $#array; $j++) + { + $queue_size = EnterKey($array[$j], 0, 0); + } + + if ($secs > 0) + { + pose_sleep($secs); + } + + &leave_func("enter_string"); +} + +# +# GENERIC UTILIIES (non pose) +# + +# get_date_string +# +# Returns a timestampe string in yyyymmddHHMM format, where: +# yyyy = year +# mm = month +# dd = day +# HH = hour +# MM = minute +# +# This sort of datestamp is used to create the output directory +# names, so it used in various places. +# +sub get_date_string +{ + my $cur_secs = time; + my @lu = localtime $cur_secs; + my $lu_secs = $lu[1]; + my $lu_hours = $lu[2]; + my $lu_day = $lu[3]; + my $lu_mon = $lu[4] + 1; + my $lu_year = $lu[5] + 1900; + my $lu_str = $lu_year; + + if ($lu_mon < 10) + { + $lu_str .= "0"; + } + $lu_str .= $lu_mon; + + if ($lu_day < 10) + { + $lu_str .= "0"; + } + $lu_str .= $lu_day; + + if ($lu_hours < 10) + { + $lu_str .= "0"; + } + $lu_str .= $lu_hours; + + if ($lu_secs < 10) + { + $lu_str .= "0"; + } + $lu_str .= $lu_secs; + + return $lu_str; +} + +# +# DEBUG FUNCTIONS - Wrapper functions +# + +# pose_tap_pen +# x - x-position of pen tap +# y - y-position of pen tap +# secs - seconds to sleep after the tap +# +# Taps pen at specified position and displays debug info +# +sub pose_tap_pen +{ + my $x = $_[0]; + my $y = $_[1]; + my $secs = $_[2]; + + if ($global_debug) + { + &print_debug(" Tapping pen at : $x,$y\n"); + } + + TapPen($x, $y); + + if ($secs > 0) + { + pose_sleep($secs); + } +} + +# pose_tap_pen_hard +# x - x-position of pen tap +# y - y-position of pen tap +# secs - seconds to sleep after the tap +# +# Taps pen at specified position and displays debug info +# This function works more effectively in situations where +# pose_tap_pen is flakey. This function is not good for +# double/triple click situations since it is slow. +# +sub pose_tap_pen_hard +{ + my $x = $_[0]; + my $y = $_[1]; + my $secs = $_[2]; + + if ($global_debug) + { + &print_debug(" Tapping pen hard at : $x,$y\n"); + } + + `$qa_script_home/tappen.pl $x $y`; + + if ($secs > 0) + { + pose_sleep($secs); + } +} + +# pose_tap_button +# button - button to press +# secs - seconds to sleep after the button press +# +# Presses specified button and displays debug info +# +sub pose_tap_button +{ + my $button = $_[0]; + my $secs = $_[1]; + + if ($global_debug) + { + &print_debug(" Tapping button : $button\n"); + } + + TapButton($button); + + if ($secs > 0) + { + pose_sleep($secs); + } +} + +# pose_sleep +# secs - seconds to sleep +# +# Sleeps the specified amount of time and displays debug info +# +sub pose_sleep +{ + my $secs = $_[0]; + + if ($global_debug) + { + &print_debug(" Sleeping : $secs seconds\n"); + } + + sleep($secs); +} + +# enter_func +# func - function name +# +# Displays debug info about entering specified function. +# +sub enter_func +{ + my $func = $_[0]; + + if ($global_debug) + { + &print_debug("Function enter : $func\n"); + } +} + +# leave_func +# func - function name +# +# Displays debug info about leaving specified function. +# +sub leave_func +{ + my $func = $_[0]; + + if ($global_debug) + { + &print_debug("Function exit : $func\n"); + } +} + +# print_debug +# string - string to print +# +# Displays debug message with a # at the beginning of the line. +# +sub print_debug +{ + my $string = $_[0]; + + print "# $string"; +} + +1; + diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/palm-session/session b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/palm-session/session new file mode 100644 index 000000000000..900c4981cc0c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/palm-session/session @@ -0,0 +1,8 @@ +DStrÇ£¾š{07¯lÙ;¢;¯l=8¯¬È+ÛfDœñݼr‹#.É+G’WŽz8¯Œc`å6E<’Wn»8¯|ÁOå•ÛŸžWn·>¯Üᣑ¬ã'ç•/šWîëüƒs÷ïß—»ß17w¿óÎÜ=ç¹û´ûs÷ûî‰x:wŸº{îüô;"îÌ=ÎŽønîým[îùð¹¹çïψ¸?÷|äšÜýòs÷¤›"çžíÑ‘Wï0;âò¼zä§óêQ£óêí‰ñ yõèk#äÕ[‘W¿ð®jX½cÊ«_tMÄ=yõ„ÏD,Ϋ_|XDÔ³ó¤ˆCòê]åÕ/‰:_uLønÄS¹{—Žˆër÷®÷åîÝÆä•SžÌ+_ú‹¼r÷Ïä•{>‘W¾,Ö{RkD¸LZšW¾<ÖïÈ7ùŒÈ®ûœ±.¯Üw—ˆEy嫯Ê+_»{Ä11Ž¯kÏ«—IJ,‰åZó_ãÝyõé÷åÕŒå;-Öåc±|Kß“W¿Û¼úoÇäÕgÄ:0–ïƒD¾é_Ï«—õçÕg]±2¯>'ò}W^}þ~yõߎ|WæÕç.Ï«Ï›•W(æó÷³#ΈºÏ¿9¯þÀyõ‘öá7Gz¤ïiOE¹ù‘viÄ7c™.É«Oåß»(ÒbÚ…£"®ÍÝ;Ä6Ýa}î~ᕹ{üG#b{m5þ‰Ü½ãŒˆ˜¾ãN¹;ì»_ü¾¼º3êï¼!¯îíÏ«¿ÛìGQï:"fåÕß?&â܈/çÕ7wä5m±>7¯‹ü±N·Äòݲ ¯¾5åÕ?h‹þž±ì?8/¯þak^}{äûÅ”¼ú—»æÕwñÕ¼úÇs#îΫû–×÷ƒŸ‡Å¯¢®ûc>ä¼úÁ½òêßÆúývD^ýh¬ÓãQþ–X¶'bú®‹<çÕOžózr}^ýŸÓbÚ²ˆå1|W^½îM1Ÿ°úɉUýk>~n^sI{^óŠœ×ìÇöÞWE¼&bAÄíŽi±œ_Šy}þ¾¼úò¾¼úŠö¼úª¥yõŠ‹"=œ¯80Ưϫ¿õ_ù¾²&¦×lmÄMyÍøè¿ðyMû˜¼f‡ûb¸-w¿ ŽíFGL‰8!â“ýyÍ7#ß7¯‰ˆ|ß¾$¯ùÎWóšÎˆ®)yÍÊX¦ïŒÈkºwÏk¾wD^ssL_}XDôo¾3¯¹e‡H_–×Ü´oÄü¼fM¤¯y2¯é]±"¦ÅôÞ‡òšµëóšžî˜Çyyͪû£Ü1Qî–Oç5ß¿!òõFù»büÖ˜ç®QwG™ïoõEÝ=“">ãq¬õƾ²öŒÜý½cs÷MGDÜi=1Üóù˜ûQϺèG»ÒmBïù‘ç–Er÷÷cßûþ#¹ûæ›s÷í³s÷Wäî[ŠØ!wÿ Æ°gDoî¾mLDÌç¶þÜýÓ¥¹ûÞ£¿2úí¹ûgQÏ}³".ËÝ¿úzî~à®Üýà“QöÁ˜ß-1»b?¿;œïþfîþX–ÿˆ´ŸLÊÝÏÌÝ¿¹$æwTî¾?êúñ^yåÉц¾÷ƒÑ¾M^¹lq^uÝWóª¯E|}nÄSyÕõÇF[ðá¼ò
Ñ^mÊ~—敯ÿz^¹ÿ yå´sÏÛžÎ=_œ{þbÛÜsÌÔÜóöèÿÕò¾<¦}=÷Ì{NŒ6ôƒŸÎ=³¿š{>Й{Î</ò7b]î9áìÜsòÌH‹rgÎÊ=ïz*÷|â£÷æžONŠx_Äc¹çŒ:ŽˆØ5ÚäØ7NýáüÛòš×î•×Lýe¹{¯X×W,ˆØ;w¿2¶Í+[s÷ÞWFÿôÜ=ùúÜýª]cÚõyÍ¡Kóš×ÇþwÀéyÍþ;÷œó?û„ÜsnÜ×~è°ÜsÁ‚hëGÅpIõ9ûž¼æ½Ûå5Kâzãq]òÎ箿ž™»f‡å9SóÊúòÊŒóÎ?öç•—^㟚qQD´ÍŸž™W^íïeqûç8ýsGÄyågâ¼ô™Ë"¢Ýþl”½l×¼òÃ7å•Ÿ¼?wÍk‘“—æ®S¾œWž¹<¯<+ç•'Fÿëyõ·ÞÑq^ÄŠˆ‡rÏ_ÆùiÖ‡sÏ[¦çž£bø¨"V䞣WäUÛÞœW;$¯Úæ31×açĵÈýïÉ«VMÏ«þí¦¼æÞÉyÕÜòª.Ï]÷žŸWóî>=¯¾òâ¼æGoÎkîzW^óã;óÚm®ÏkÇœ×nû®¼6›×n× ÿqiÄʈ÷åÞßǵȺ«òê¶ýâØç¿Î¼zÛ‡âZêþÜûë¸~‰k²Þ_¿+÷ÞûùÇÅù*Öï-oŽež×¼»¼rqì—KÃhÙµyåiÑN®‹ëYq=ø¢8¦o~sîÞ9Ú¤í;ùrî|ô˜¼jû¸n{ǹëmoŽ}:Žé¾uyÍ_GÝí»äî—ìÇôµyÍkb¢]ýÈQ¹sÕ®±ß…íÕýÑ,Ï]omx"¯¹?Úü§¦åU<‘»n‰}ýM±MœWûÓKçÇuJlû#ã:äôÎhÛöΫ—GÛ»Ý]yÕŸÌ«>þ_<6Ž¯óãœyœçŽÍ«ï‹cû¡¯æî×ıþšûóÊ£â8{ÛNqL½-ö·Å6>vTÄaŸÌ+ŽcêkªXóÛh{×<ðp^ó`XÌyW^ù®ØŸæ½#¯<aLDìïÞ+¯|ψˆåÑ~ź¬ŠvíÑ{ã|ç¦1q÷h\ߊk¾Çb9~眧>\º¿çÒ?Ä9í¿NŒëŠ{Â$Îÿvk^“å5-">˜W]ûÄò7åUŸ‹}âsçU_øf^uåùyÕÏ‹èÏ«®ú`^ÓûÏÝ—DÜ»×ߦq|wÄõãnÊ«î¸0¯º§;üÊ«Ÿ~ºšoußQî="zf÷Å5åcyÍ“qõpÛ)Öá‚ѹûG·EÛûêOc¿¼÷Œ¼êgÍ«úÆçU¿qc^õ˱qýº8wwOîú›¸æþ›xRZêûl´Ÿ½5÷|æ‘è·Eìñš¼rúÞ¹kÞü¼æ·GåUÿqsîyßî¹ëËÑŒ;&â©Ü½ÍuqŽŠmÞé[Źm|\‡—úÞ=6÷,üfî9å¹;Ú±îïD;ÿŽhCþzJî~W´#§ï•;/‹ëä8Ž;Wïín¤ßÕíl´?LÎÝqvÄws÷ãÑÞ>~^Ä͹û‰Ò†G{ýÀŠj>ÃMži¸û‰C¢Ü
¹ûwã#fDÄ9áwwEÛ~nĹûÉXžu÷åîßOÏÝÝoÊÝ«ŸŒsÉ¥yÍ'¦G¬Œˆsã'÷Ž8#â±¼ú¥ÑþuÅðFÛV‹}ðµ—æî}?˜»¾*w]÷*ÿžóš¥ïÊ=F[}ðìˆhƒßñ©h?ÕŸ{>mÊeÓrÏ?ÇqtÙ×sÏ_±(÷wql×ãrÏ'&äžÎ=—¬§Ðwæ5ã.ÉkÎ:,¯Ù-å5»_”×ìíë±qyYÌ{b,û«>™×|,öó|&Žï¶8^ßçï8¾Žc²µ5¯Ù)öË¢
Ú)Ú¼ŸÄuÒħóêö‡#fǺÄþ~ÃòÜýí/G¬‹ítYDì±M:ß“»¿mëëÎ+ÿ&î_¾}ã3ß¹ÿoNi¯?L[¤Þ2ߎ”â)狦FÌŠ8#"ž1Lˆ§™&§41žÿ¿ä¨èÏŒXñΔv»7ž›ÃçÇðÓ1<&â¢xDO&w»®ñL}^ã¹óÑ1‹“"æD¼7â¯#N8-âgEü]ĉø‡ˆOD|*âŸ#>qEÄ—"þ%â_#¾ñˆoGtE¬ŽXñýˆDÜñ㈟Fü<âWFü&âшßEü>âñô·%b‹ˆ-#¶ŽØ&bûˆ#^ñ’ˆÝ"^ñŠˆWE¼:âuoˆ8 â‡FñÖˆ£#Þñ×s"æEœqJÄ{#N8-âgEü]ĉø‡ˆOD|*âŸ#>qEÄ—"þ%â_#¾ñˆoGtE¬ŽXñýˆDÜñ㈟Fü<âWFü&âшßEü>âñÀº%b‹ˆ-#¶ŽØ&bûˆ#^ñ’ˆÝ"^ñŠˆWE¼:âuoˆ8 â‡FñÖˆ£#Þñ×s"æEœqJÄ{#N8-âgEü]ĉø‡ˆOD|*âŸ#>qEÄ—"þ%â_#¾ñˆoGtE¬ŽXñýˆDÜñ㈟Fü<âWFü&âшßEü>âq(´Dl±eÄÖÛDl±cÄ‹c‰éi|N-ñ7šè"g9JêÉi¯H¿´ŒÕŸó·§ÜyNü]äEñÄ¢ôÓNñ8¦âì–Z®ÉçF«}Qœ}nX—»¿!w
<”Wþm\EŒ½2¯ú§¹{븒~ÛvyuËÍyõ?ÅÃ+§å5—>‘{F̈8&"®^G¬Ì=#£g”Ñï,ùÉ=ÛŸŸ{^g½×çž7\ó+Ëü‹X–©e™ËÑë[>Ê2ÇñkQÖ,Å2÷|îÀÈÑ^ï§Uñ8ökÛå(“{¾WÖ_ëÈ=_þ×ãªû†ÈÛuOîY9!÷ô^›{n_–{îˆþërÏ]3rÏcüîY¹ç§{åžû.Í=¿Ú.br7÷üæÉÜ[;&÷¶íœ{·xOÄ#¹wdkÄ؈x²4rJÄ'F|>÷ŽŠi£fFqFÄùWF\Ñq[îOžF?–{·Š:·zSD\ne·Šic¢ü˜IQ~ÌÅk"žÊ½[ïñ®ˆOF|7➈X¶±3rï¶QǶ7åÞ¼9âÖܻݷG<‘{·ß.÷î0¿ü•(â’ˆ/GÜ™{Çï1=âôˆ¨kÇx:¶Óå¹÷EQÇ‹nνŽˆ´ËöâGrïÎ7FÄ<'N‰¸,÷¶Çz¾ä¨ˆoF¬Ï½»¼'"–y—¯G<–{_ºoÄÒÜ»kÌc×HÛu]îÝmjÄ¢ˆXŽÝʽ»Žˆ§s»ÇñîO”¿iEÜ–{÷üLî}Y¬×Ëbž“&D\’{÷™ë²ï/"â‰Ù«£Î×|7âΈH{mÔ¿ßÊÜûúŹ÷
±|ÓcY¦_iÓoˆ23âªú€0: òÛïÀY¹÷ 0žùÎÜûÆÎÜ{H,áïȽoº7÷þe¬Ãá#rï¬X–£ŽË½o‹ùüÕu¹wvļÏGÄ:Ì‹uŸåOˆe<áéÜûî¨ç¤¨óü˜~Á“¹÷Ãνÿù?~Qî]Ëô/;äÞ½/÷^ãÿ¶kD,ßW÷Šˆyíˆ{roì³½_ïϽÿëúïŸÎ½×/ν߈º¾¹_DäÿÖv1ŸoÅôo…Û·®Ì½7ܘ{o<8"Öë;×äÞ®‡sïÊû〉ãªvn?§‘õ³azA9ŽÊqU»°:ÒZâo£fÇß[þ©£åÓ©m›bzu´•ŒÑ•:.‹Ò3Kj9cÆäOÇǤ8æ®ýãÿ,y#÷‡#ç÷êÃ>ÿWZÒèø“ì`×’bÛ~26òqMsÓ!ñ_J[Æ)ÆRËk¢½][©lÓÆeÆÿÛ]Ê«Rg^Õ÷fqÏZ»/¯jëÿ_ÙnfBàÿ^8«Œøbuž‰³Ê3ãjúæÍn77¾3¢1wd©=ò~/ÆoÍk_ÏÅ®¿/¯ýF[ÄÁGÄô±ñ•¦;â„ÓÖò…›¹Ë·œê]ù&Óóëâ'ÀrUÖ¿EÕÚ e‰ãž0ÎjƒKühwˆ~zm½_îÓ}QÇNyí·~‘×~'¾#öÈóXêÎÛóÚ•æµÝ3óÚÕq¿ö3yíwcnzG^ûý‘ïûñðæí"âI`<¡_{óÝym<]_{ËwóÚøÈÚ[¯Ék°_ÄUyímñ´ÛN8?ââˆÏG\qCÄšˆ'òÚ†Ô·Ø5"ÊýðˆwDÌx8¯½ý›‘÷öxy{,ï;E‘×ÞÒwÆ2ÜõT^ûã]"ÌkîîÌkò¦XÇþXÇ8[ï:ÚZŽñúA|Öâû>›~jx±jø€ùó7IÛ4aBHO˜]¿ +ÿñ²æv¿*¶ÃòˆËÓÕ<wŠ}b§´åÈ4¾¡UU4·%¾·TûܨMkÝLÊo;.‰ÔŽ¸ò©wµÏo›F>•–ǵ¯<±S=±Œ•î³ñ_ý›qõï¶}´öÀç« )åµ—Uÿ^b|•*v¬=¯*'Ò=oS>(K»çúrÿò²íÊ—É^¶oùœtgÜ°¥——«²F·ç½Sö›òšöE§Äxí?:SÚ7Ö}—ræ®wµ‡Óy1´SŠ‚{ÜØWvý&9Ë<º—í[ï}Ö‰ámËxg¹ÜN/û`äŽU˜´{™öœºÃ"Wcƒ7òoš’s¨ç«Ïíø9ΟK¦ÚocI¶§FíŒM_}¯Z´—·ÇrLDÙîÏÛ§ì[yí•Õö®Š<—””^Zò–çIÑ=ëpsˆ~ÙË.ÑÖèhôËPÒ«íýr(”ñÜèÇ“Šj|»F?žZ”ñúQq ¦ký%¹tUýµ9ŸŽ‡AñÝÂx‚WV´tJK#ýìH<ÒK+çšåL±G\åîžÚÆ^i;DT]ä£åÁŸÎ;~éITIåËŽ¥[ßÈ’NY8÷”EsÌO[ä[OŽ3Oéfžôî“–žtú¼Åéø»£üê©CŸsczU¦%ßšÛëé/\|Êœ¥K†2•¡ý;ÇOX|ÊÒf™ÞÛêÉ1oÁ¼ÅsæG»´™KÌH{÷‚Åó›evê®—yó¼¥ï_¸øär…?¸Õ”FbzUfD¾ýér?Ý[Þó©¦tf_sh°¿ðý7çsÏåõä#O\¸xéA§n¼Fƒe–œxüàúüf¯zrGíoî¯Ýâ¬zïà6‹é7Gz<©ÚýüÈÛlvÙfŠmv^j;¦ìñÕ¾Uj‰¼Ÿ¼µÜû½{sïMq×üòæq}KUoìXõ®õÞؾ—¥–~3To\wôþðÖø6pÜ—~jmô£Þ9‹"ïrïíÓ"Ê~4;ÆoÉw|dVÄì|ÇE÷Fôç;þaDĤˆioŠ8.bQDGÄ%+"nˆ¸3âá|ÇÅm{EÌŒxgIJˆ‹#®‰¸=ßñ‰{òÿøšˆ§óŸšqs¾ãÓí'FÜ”ï¸ìîˆ'óŸ‰:¾óýÂ…ùŽ+®Íw\y¿eW\˺s,ëiÍ5ÿïö;j³ïŒzŽ.åÏì(ŸvÃv×Á “û&/˜<yöÎiƆ'ãH³Ù´Î ƒåÊÀäöþ1©o£´Ù›Ië¼vLꟶAÙמui¤5vÀÆ”É-ãǤuq\
ë&×&ŒIw6,%æ[[?¦åž›7Lk;¦å¦n˜6bĘ–”Ýt¨›Ü6rLˇF%ÄÐä1µ±Ûl”¶lç‘Ÿ}|å¸
ò
ô
6‡Zrsh¨ßúÀÐps¨µ·>4r]3%öö«êÃ;JkÖ7uÔÛÚößù
O/;kU_}úäQ«ÚÚv¼pÇ)“;Ïk™ÝrÖycÆß4~òä¾››sv-Ý<¶J뿬Ys¤Ý²s•vý¥ÃÓvØñÂ({Ù`Ú¢Zúþ×'Ž‰´^ÚÜt“kéÇ__Ò>tYs¾ã·<ëÒ_Viç\ØL;~Uü7vêäÉg}¨™6rݧtÃÈþe§užÓßœñÿx¿|§}ãîøŽSâ¯E›K»¡uâ¯û×ïß8ÅV…æ\Úú‚—nsÞŽg
6_QöÒ‘µèÆw3Tïñã·¨ÕF´\ºêœ¡ŠŒßúœÚý‘Ö3”6»¤íÞò©sVOuN”ýlí”áiWEÚ§Î;±35»Ùãǯ*ó]3uxÚµÇ×ZÎÂä¡´þý×ýç‡:ÖOû`îkÕ'@€aôF_ù¾É¿,šÐOÅöhsÒÑ?ˆ´/zÈ}—§´d׋¢ìÅÌýp¤}åÐC䧻`f¤m¹g#ýÜH›uÁÌèm¹Ç¡“ωúœpiP}ôÝ3gƤ»Q'ÄxÞLÚ3'•,4‡g¨ße7LÆWj}ñÒÛ¹4TѪUÛ¨F7µÖŸã¦¯+#î]Uó6qçõÍ„°8»j‹'ŽžÖÚÕ9öQßÚUæ–Vµo˜vvuUºaZçäE›”íŠm¶q}¿8orIÛaø<~^n7šoÿŒiG[¾Ô¿¼ä›Ø1<mÝŒ¾H×3|}—Uë;ò×ý1¥ÙM׃µÿìk&DBÕ’nè<¶¾`ná•+ÿìƒ#;§–[Ý]Ï–µ%íÚûȆicv™³åõiÒ§öyýøfÖ–mwù‡Ñ9Mºbæå±·Ö»’¶e|ãü
3/¿a(m×uQÚæ%3/_>˜6fêœÿ•¶yñ>»^ÖLÓ'@€næãÙòl®})íçGÌŠË9±qgó‹¶êÙfWÚ³?šççw~™ß’÷/^Ô¸SŠïTÕ¿ý+¸™õj&=[žgœß¥½~×Ò¥òûuGmq>?ðÔ¥K.l>›³Ø ÿlyžq~O”ùÍ=éÝ'å[s{}~3cléI§Ï«_>l0›Á‘gËóLó1©Ìï„ŧ,Í·öÞVŸßÁŸ2§\ý‘îÙò<ãüf—ù•+™Æ¿øž1oÁ¼ÅÏrúy¶<››_Ëì–4â†rÍqØœSãŠ'Ž½ú%ÞŸéÄÔrîÅçuÄõDóûŠë‰ï¤¶Ö¿(WCÕ5ËÔ´C…±CLyùÌr½×ÖòÊè—+}¢_‹þk£_þ¯×G?þ}Æ–ý£?"ú05.ÐÚZþ"ú£¢ÿ—Ñß2úo‰~Üùµù¶ŠþÛâ:rLôÿ*ú[Gÿo¢wW-ÇG\ôßýý“£¿MôFÛè/‰þ¢ÿþèoý¿þöÑ?3ú;l°ªÿ£#áÇÿÈËö\øþ‹ó÷\i±=ßòþØždß)“ž-Ïæ¶g5¿ee~KN<>ö×ß”'f1¿#‡.äŸq®Ï–g³ó‹wÇüòà·ÏŸ±î2!noZfÍ™Jû[Žlã)îöãÚsä×˵gu<ícß +¸ÅÇo¹h\ôÞ9¥ðe>³_|üVéÀhºÓáG87’GD´´\tøQÕµáŽé¢ùgŽ›ŸÎÙux/
¼2uÔÿ¶ÏÄwnÆΪ_L—ýó—3Ê؉1µ\×~¬ºÌ.SßµMµõ_ÄUÊ Ñª´ƒ¾{tÄ}ÚuÇ÷±awA/ˆ²UwÊœã¿;ʧï,¯'´””=ʾùÙêéÕ±iÔNe}ƤæÏY|ÊæWhïtÑ»Î|S4ÚsæÙ{þM:k»g+k‹~LÔ;³Yï¼ÅK7_ïËÓE³Ïœ6;M«>Ï™ýL#¥ÒžŽºÎýƒgêjiÔgÊ_ªóšüä’ãckD×¹¹†c8ןÁpì+ñÐaËtô‚%sÞ7onu»Ùû§€,[5âñúæ«_<”áò/œUíÝ^³ê“FUc¥uûx5TÚ·sÊÖÀbèßÊýe5ô便¬†¾Uî3«¡V%¢åkYýËi±O¶îŸo½nB¾ãüËòîšoÿ·CòÚ¾±¹wÕ/Ê·ÄòÚ߯þUôœoïïÏ?8½³ü;º¹÷‡·–³o9#–³T9s”»µrUZª%ˆ9±#¥öPxC¾ãš åÛ˹gù¥±”ºk™Þš¶¼ v¥Þ½_9'¿jò”ÉõnêÑ{O‰¼‘²ïPÊ>©Öº÷¾ñY‹Û¹¶ZÛÞñT«¶ÅÞ¯Ï{Gk_¹w<ûŠR¯zu”šRʶî}R=åµC)Kª”ƒß8˜ò®ò´oñ¼9'Ÿ0gÉÒæF‰™'Å=ç⹑sÆÌ#GͳG9ÿÔxâVN];œ2/ž»Í›·ô¤ïÞ:&¶Í8êÈQ¥õ3Ũ87mvŠZ¶5þƽãsJÚ7>§Æ“òÖøgÄçÌtp|¾)9g¥ãâó]ñšìÓÒtvlýóÒEÑØ\’âûXé3éóQë•iEœÃ¾œ¾g®ëc÷¯¥îðšÐšFO7¾Ÿ<ò´%KçRßaÊç_Ì9%îÙ‡º£—ž4?ššÁ´xâóGÊýÙmrÝßQ=•Ùé¼rß²ßÒè}lÇ´s¹+ô–É©<a(MXj)×Ê‘ÖGÛÂ%óêëX)-µY“ëOHâ¶=¦–ïP–oMÖÓÚ‡â©Zza5µœ êùFN{ˆomUM[‚–íª¡ò¬^ËV1T«ÒÆÄP½l<K#«´r×Rϧ³ÆPiõëiÛ-Šó[•/žã5Êî°äÔS.9åÝ‹ëë¶tÉ)eÝfMþo´—Qe_KÚjj}oj?üЙ‡¶¹ðÔqL4çV-iìï-Ñv=V¢L‰®~mKN9aqµ„cg‘òËæy°å×q>,×kÿýÒ¢ý6ú¥={<úåzí?£_®×þ+ú#óÍÆ¿=ù£uùÖ}‹;›ø7ž¿17ßòãóò÷žúßkÃbÞÔš¶úð¢E‹þ¦Z¶ÆGã[Qï5ò€“N‰cø´ôº½Ò«^õÚÉ{¥½¢Kƒ÷“çEM¿Jã6>ŸíÉÎ[O=éø“7sã¹Á<ÿoÙäHŒ…ß`à°hVÛD3ÔX—ƒOZ¼AÂAO‰ËÈ¡›á·môøíxZ:œáà9ßÅÕëÒ7¸Â}ã+ª§ÐƒEÏ0Ç:iéÐÌ"õÈ¥q✚Ò;NZÔ~йƒIÅ~¿tØÍúQ'-?81Êtê’¥OisX½kŒOÙh|ŸÆ÷mŽ¿yá³O·È³æ¼{ƒõ;|á»â)W³tós[D3µõ{Ê¿ŒZ®žñùýP±æЉmûn,ÔœÔìo|=ÍßÄrWQiYKwf_JŸ]·ëSËȧSË⟸ßj £6r cäg:G~(bUÄÏ#úÝ9rÝ‘#×ÐY{º£6ÐÚÑ2ЕâßÙ3ù‡=ãßj¹3‹úÊ<¢©½Ë,âß@YqUÕ_µbEGÔÚZ±¼ôGíWM¨¥±+VÄøVé£U†:ö«ú“V=´¢dœÔã¥}ä+ý/×®~¨ô¯îxx¿Ò_Ñ7elÕ¿~r-ú£W|9µw–þÕËGE¿uÅŠ§¾¢[±â+ëK“=iÅŠ/”þè˜ÍãÓÊ„jùÊr··§QqÞ(7ñ·5»Û¦×»fJéN1b 1}úô¡Íé#®Øl†¡éñoel¦†aÓ7[Ccúô˜ýˆÈ0´eœµ¯¿¹Œõé±àQÁ”a¥#¥Z‰¡é¥‚
2l8}úÀÆ6š>”a ^ÍÆÓ›bIª›Lodh:l:½Ê0eĈX’¨aØôæ–«×P FT“›ÛopËUk&n8}°‚飛ҘÜ,ÛP†È]Ô>ÿ
M–¡ØƤ¦ÏPJ—Éñ°¸¾˜õÏÆRO*+·,×8q,W.gÇ0ûS_\’þmzCÇÄŽêä]òÄñÇb9鱗³ß1Qþp²Ä+#a«Ç;Së@gŒDB)3zè8ˆ{Ö祃Ño]185–¹ž1ݶcŒÿcÊ`d/kS›ëÅbNѵſ½6îÒþ•¿«=ãßûꙇžX;¶üMpxÒÆÛiÿvˆëœzû·S•;ZÖu¤‘}iÜù3ÒøÍH³/mONNšÑŸ.}éøÔ¹WDoúåF¥‡óÜÔè¹é±óÛÒ{»§¦e—÷§×싦3‰’id¬UËú¨¹Ì'®,Ã}·j>uêÖ«;;£ù¹!Åçw:;ãDûOŽrNç˜Hk36uîß·«:G®u\›F-/Ÿ+Rç5£[Ç¥Îk–·¦i“¯N“Ïéœ|õ˜ÎŽÔÿòZû¸4©ó¦ö§ÒèUiÿ«RëµãJëxíS¥±}eÕ²¶®ˆ„j™vÚ®Ãw¦Ám×L,;ÜÀÀŽ;îØØö%½™U
¥V;ýŽ;V{Ô`r½dä+;J#µ¤•„’V¦TÉõ´zr5-
ÄÑ[M¯JVK%õÔfÉR Z¸é·M¯WVUÑœÅPj”¬fQ +–V¼d®—,ýR{=µY²¤TJ;4´Àƒ™KjŒTk[O;î8e¨âªú”"© +õÌõÜ%Þ25ª¨JV
bݼJ®JçzVÐ%7H,ÉUK9<gUM•m¨tu,k#ÎLåWØ]è8³¬ïFmĤ8—óo‰åöZÑ—†2ÃÚˆÛbO)Ým±Vnƒ¡² +gsbÚ4mJcò”tÛ”zWÎÃÑFìÕš¶YWÚˆò¬$ïE7Eb<³œcÍ/8T7þ8±6íÙòl¦Ø~Ãk¤–Xß‘ˆö¡¿#MŒãwÿÚìtƘEiÑ«&§¾h~?ÈybÛñiÝù‡¤þ¿ŸúÏ]–ÿ»uiÑÈþ*¦Æ5Ñ„‰iÜðö¡ÌcDÕ>ìZ-t늯DÒŠÇã3£5^Ñ?º/þų´|jšÔ?ºu¿hš—·MѤv\ý•õ£jWO®¥—v¬èì\™:¯N“kÕçôŽ«ÇuîóPÇËã•[‘âs¿itgz¨´µÒ|åéÒ2ÄEPÌ«Þ2ÄÂã¿MÛ†ÆÞ4Ø®—]l0í=ÍÖ~0q`à=ÑUÉ¥½¯r6Òª#¸œJb3-æ_ìT)õ²eߊÃ+öàHž/ÒKæ¥Ë<êùš™#µj‡Ê.U¥U™©1EKzUsI·UBu(ÇG#±9ZåÞLj9ìyëó*uV‡bY‹j&¥h#Z‹á©eÞÕº
ËÜ8ëWÍ:‹YQ«Ž–FñH¨R‹[³+¹©ƒÛ¨J‹Ô趎£|X;0q]µÿº™£V\uñ¨³¯šÃ<qnl^+Äesg‰qqÐOžœ:oºéüÎUqšês~5ÿ¶pgUïØ
Î)óš]uÎoŽÌ+c±ñÜPÕf)Œñß”ø¯ôÿÈ2XõëÓ6,WÕYÑ4¶F|-·5m7¦´ó–-Z’oþ« Q8ÚŠ7.[4oAóQQUãFÑV<[žçÐVĹ¿\Œ{<ÚŠ®h+vìKgÄ;M‹+³.K}ï[–˜:5=pÏÔôÄúñé‰eãÓS“ïJ§ï39} þm¾7ìÓ—v¾¥3ÝصĦmÅòXöI+ʯAW|elGi+jË£¨º*ÚŠZçCqÔë(]“ö_¿_G|N‹ÏŽqcãóñþ±W·ôGëѾgcEï¸ô…ŽI½ãFM“®KËã*âºÑ㢸fùS1›kÆ•¶âåO=綢¹ÏUýÆÎYj¼±/—är@6’Kj•³~6’#µ™/ÝpC•y¨ˆ5ØH-™78Ênˆ®™Ú<˜"çPr½õ=ª¤Ö\¥^Ѩ¶Ô[Õ1˜Z嬒c~õã?27«2¦VÉU
±p%5æWj®7]qEI-«6”i‘XZ¼Áä’¯jDÊ1ÝLm¦UÍäF¾J¸á[Ö¯Þ(UìUjT‡H™ÁðmÑ”o¤ÕÛŠ‘q'^o+F—ÕÿMOŒûŠ©ñЮOëÒäø/ºF¾h/ª|µÎZç¸õû¯ß?ë¬Å?N=Ð9.þäÚÈ7jƒ6â†êmU£_ß:·58K?–+–º(K_Ú~cz3_éׯvUŽýò$)ß²ÝüHŒc?žÌ”¡gîâض<ÏáØö‘ñÍê:aeû#ã:ad\'´Fãvãã>böøÔuá¨Ô7y|êë\–úã_n-× Ë&ö§©ñ,æÅѤ>ïë„1ÕuÂôr^Y®RÜGôÇÚŽíèL±UâbZŠÏZgÜAÄ6©ÅgŠë„xÓ¸Nè˜ÔY{¨\'Lg!ÿöP¹N¸±\þŸ_'4®ÿûfÙÿâR0–nãë„H‹»±rAÐØçùÒ?ýSœ†ŽýR6º)ÿôO‘Z5õúêÉŸ¨×‘⺹ž0øY¹C©'ï_ŸRŽÑfêÉÓ›¹«#·j'ª| ;–+‚2—Ùú±e›ù"ÑN.EÉWV¾qìW3j¦5ŽýªæÁ´jÝêÇþ°´Ác Q_©³aVš„jUZI,’ÑÕÇ«Ïj¼ž:˜^¥UGÐÆ× ë:FuœØqâÇFuŒ*1°™ë„qБRÄžõ(Ã~4;›\'ޔƣÈJ$ZÊA±ØÀÃÇF6ÆNŽ®ä6mpì§]1¬«fÔ¶gk?¡j+âoù¦õgGri+b¬}Öœ¹U¦Í}”¶âYò<‡¶b}ìì}iÜo—§‰ÿØž¦ÿÅìtZë¢4·µ?ݺïºÔ·z]úåŽëRÿ{Ö¥G/^–Öíqû²êZâŒÄ±÷;ïÿ¬mÅòXIW?{úŠïì÷o©õêþ›W¥Ñß3ö¦ôòþÎÚØôÊ1ñÓ§k:k7íÁ´1u\]ë¼ö©Ž¸êÛg¿øì_5¶cŵ7•Ïiñ9)ŽýR|®z(¾:M¶âêÚC1›Ï÷ž¢¹ÏUýjϬŸžâ³±×–Ä+ùô]©´rY8}à´Ò†Ä¾\ÏW](–ÔF[QÊViP²VÇÓ°´’ZêŽ{ŠæEæŽWLIWTY«£·:þKZ3ë`jIÛqJÉZoƒÇɵVËܼOH7Fæ’5j‰Ù5®¢Î¸Ùo,ó°ÔRÁPjuäV‹s*‹Q-ïðÔH«a°ÍŒ\Í´Á¶¢ºâ©çÞV]ü·ÚŠâ¼?ìžâ¨40û¬åg͸±ãïÒ·ÒGâµ\,ÏôãÛYÕ=Åز\q™›¾õÍ=SGëùíécë:RÇ.ñÅš§Ôñùˆ¨oRy_ÊvÍP=·]±]«î¶]*¨ju—47aXÏÒÛ¢+ƒe¸ä(ƒõôl§ê44XOÉSnS¢+3‹‚ms[ÓN{—v¢|ÿ"¯ýÉõ‘íDùõCó›!e›t'Öæ–<Õ^7™XOØL;ñÂ
Ÿ=ÄãšxÌŒ4ò÷q¬ßßž&^:9Mkˆ×ui:aĘ´lü˜ôÞÎx9cn:ëì´lDk:cј4mÑÔ4}Ѻ´s?‹¶bd´µ¨+=s.óQm“]ë˱âêÎòǯ-ÅCñ¹âÆ«ÆÄ‘ýPÇØ4úÆ«âè[=ÔQ[Õ±÷Uq!Ñ·wG3õ½¼µ/¥É/¯ÅÓËÉ“VöÕ:ÇLꌩc&]»wJý£¯}}×1úš½ÓSqɱ"¥«ÓS±a_>®\YŒ®žM6þìR-ÏøaÛºÈG»zég²¡Ô“ß^m¢Fz3ïÛO~ûÉÃÒ5Db9eÔ·i£êH}{¤FzãüYÍm0µ1¡´/¥Þ*ou6[˜F½%gã _Ï[•ŠÍçSJ{ÒìÊ3òXÇÜës¨ÒË„fþæ†_?ηlµL.>e½bÍÕÔzËPtbB#Õ>”ý°@YÈFëROoÖÔHÝ ÕˆŠ†µ0ü¥ªfj•{0½šIY€²©KWÞô´Á}Gì^éô—}ÑdÄвô·ÕPŒ”|õ6e\YÂÒ•öŽˆ¯†›i¯Œ´WK«ÊoWêón|^qÅàhÜU
ŽTÃÕõCL–g0shî¦eðoï‚ÍáfÙayJ‘Fm̉iÂq¥Y2ïøÅyí¯¢E,mÌ‘óŽ?uñFõ.k6ØX»þÙòl¦Ùq£6æÌø›Å@i¢x2î?~Ÿ&ü<⬴ÿÓmû¯»·cÚKoéxÝÇI¯ÿÙÓU¼î³OÇß<ÖGžõ‘]”ë¯Ê—zRÔqý
¸<UŽ.(-/ýøÓkiæËÝÅŠiÑÞÕ«ªÉ+â˃%ÛÕÑl7¤k;ãÙÆ|üáè_;æ•×þ6ÒWu>uÍÑ¿ùßV|¥Ñ/Ž^õ½ªâÖk÷®fÔú•§ê3ŒúËÍL5¿è
ο¹<1¡$W˽ӦmQul
ÛY«£¤l¿²7ºææ¬÷›©U¿žTŽ¬
J”iÕŽSMÙ D9læ—3Ù&%Jú’Ó7R¥/YR/3¬®FúéQ(j+SÊéªÿô8Þ8=>êSæGÝQ¤Gâé%S}JY–RyuùËq[•©†«FÍÏ0¥Z¢f™ÓKmQýPWobÑN/+7”^š‡†AµÔ›N¾ êS‹r)³©uI«OÙ°TIœ2|R}B³LŒ5æßH2ÑmgÓ¸n‰¿Ãƽg|§+žülÝÏÖ‹/)UÓêmUi¢ªŸÍ¹#¾{ãußy¨sEç¤ølœ1Kc‡íwa=4%K.MK.¸-¦6ºúØÑE©¤^P +F?–:’«Z¢|u-÷<;_Tog–.Êwô¿&©jg–žº¨,Þ3uqÏó¶yóßè=äÞL;³ñßQª{žT=ߘ—Óþ+žþm:ãõýiý‹ÖmUO;ãEýéƒq³ÿľ4ñ³qô³Žhog}¦g£åh®ùÖ«žZ‡{Ú/ž®ˆo–ÄçòøŒfb¿ÏüyþàÔI%g”º:‚F{ÍL4¥«ê e^Ïéï(-ºÉ¾Y¥W©Ãvïú™±¤FâwËÎ]™)‘Z†¾ûÝê¯dõÃ¥¤–ÄH’Ñ°Ô’<˜Ze-yKîFjýÞ¤ªáO•šž}nƒk1lškQ-pÃ!$Õ×W¨ÑúÔëˆÜÔºYóðm¤öJ½‘»Ê[©ÍìÍK”²¿o¹á5Ê@GGǃÿut¬ˆñr™]åvR”ÿnY¿i”ô›nªO/ùª²£‡Ú‚j×æ]Ju©X¥>¯¡XªèJ-Cÿ
¦5gR%´ÅW<Û?_µñûæüƒ-/Žäøí!— õB›û<±vî³åÙL;1~£ïdD;QëëKãÎêû—uiÚÈõiê+oH‹öß9-š>6õM‹˜>2ÅÕJ=Î_‰8clZ¶~lzÃÒþ}ÓÒÄx¾Zê9²3U_t)ó©ß÷ìV_øêRdôUñL;ˆ¯³¥Ö«¢qê½<þÄÝ?ºcÌÀ-ý“"¡¶>>קõ11ªø\_¾eÝàç¤(1)•r“R¯ŸÔ±">G~E{t´ãúKó°g}.qØ¿?Š‹6,ïÆmëjï‹ÏU]s¬Ù¯ËœS<çj&ÖóV©%ypBÉ\O'7&lš\ŸÐÌ}r=wõY_aU—[ ú,šÙ¹Kž2ëÁä*}°äFé;©(0”¿ž·ú|.éQpøê
ÍàÒ‡å/ËY¡Å̪äS•^ŸPÏ]O¯'WéÃ*i0Ô…Jzcù#wsËË]R›ÉÕ¼›ë9,µ±=«¬ƒyãffƒ¿Û¾4½¥ã¦ÎÎè˜qÙŒ›:Ï訾¼ZòÔÛšK½£ÆÅ}P´#ËûûSG¼¤¨#îžÎ^>9-_Þ{gg×ÕU½ÃÚ˜Ûn;;«¥‰5©/nY§rÛ[©šV›«Y
Õ×:¶aq,ùêH1T±D¡yÑ”FW¾ãµKoiOʯoó÷Oút$ÆuÇ3þ†·*]|ÇëÙòl¦=‰o2¸«ÇkL?‘ÒÈUqÌÕ:Ò„–Îôª–¾Ô—=kvê‰{Ë®ñ·Ùx‰~_ÇÔôèAñŽãûí£Ò²YãÓí‹Ò´È¿óÈø»ìĸöˆû›ê;^e>´'ñG•¸øJ¹aÔ_žw}%íHñH·¶<æœjW¥þZùëlgmZz(]»|5£ãÚÒžåo´ñ×ÙÖ¾(pumrë9W·öííŒkÃÎIûÄßlÊ“•éqTÞöÏT¦/¿ÎÆŸoâ™J|Í#šÌ‡"!îºâ›g›¶'eç¼û¬Ÿóª³ÛÀ@óëCgÂ8ÑŒHñ5Êj‡¬ò–;†HŠÿâB¡$—ÔH«’†’#µÊ÷¹zÞ껜‘·‘ïsiDüÅ"&•‹ò$®Êõ¹ñÇ›F‘#FÄÎôoÃk.Ÿ)9Ú«z£Žzå/1U1©ü(†£æ’Zã©ÉàÄúÓÕ’\N|#RUE¬JõÔ¶™w°ŠúóÙH®êhTRºRÕu4ë©ÕËSš’—hE'V±™+«R«Ì“«K¹†dä®×\d}K%±uª´aÛ"ÊO+ØFmÄ@êè<§ãßÓ—uœß¼Ù¨(׬ñåÁÔ1®3},öÃïHçÄ÷›::#â¿êf¹”ÖFÔ/®¸bJýûy±³}v9…•þÙ‘vöÙñÿÇËÔ?ûãñü$¦–úPŠxW/Q
5¯9ª6"ßšv=»úõç1í‡Ç×øO©ªn|tDÿçõ#º%®74eJ¤pÔî»o#ËÿD/ê®–£sæI‹ãå%í›ü“ ‘!–£\Fý)»–˜Ï¤he.8gZ¾ãú›¿Å‹ßÕülãßãŲ,mM»½¬ü¢s\Š7ª¿é\¸ùuœ.:ø̳98My{ôÞž¦üÕ™Sþ*žÖGÞvæÜ·•‘¹o&’þªd+#Í ç#ñ{Ï£ã=3bžsê¿"uâÂó6;ÖíÓE‡Ÿ9þðxóÊ™ãß?==3Þ†•þ‡RÎûŸªhÓzþ„UW~±ë,¿â·u:òø“^qÂI›L‡§‹N8sçR:åÌã€Øtxþ™Óæ§çœ¹óœ8[ž¹ó‰)=Ópý׿ïiM»¿®ÌwlzÛœ“çµÇ}ÿf(ý†tÑñg.‹KýãÎ\v\JÕð9³ŸKRcIGÄœŽ}æßi½qÎâ¥'Î?iÁÉ釽ù•§.™·xØOʱµá¯¶¢Mª~ý‘qX´.Ž½~nÔa³þ›Î<«å¦3—·”&%Ê–ßµûQíñ“¤ùsã-©YÿŒxGÐü¹ñ±½ç,]º÷F?ÛpŽ½1«b74çõVÝÐ<Ê/ JÍï›×œ¶¤ý¸ÃSõñþöøåÔ~1|СG6SYv=úÈ7qèÌzå»îµ_UR3W,âÜ*߬Ž<òmo9¢äŒZßß>kÖ¬j>.g[GÕVÔ>ûìmE”Ž¶b}ÊÓªªk´¤mñ›¾x]íŠF“ºÇ;ƒù5ƒéQ0÷Þ·I©£JK1½vÅ%e<¥=âßf(Óöˆk+â7Å_Þ=†ßYÒRѲïqrùuXüY½ýø}6lÝ£‚ÿ–½/ÞÐõµh!讀¹ù7YŒª~Ù=ü—‘ÕUu,fýÍbå7¨yk[OñËÇÖÚŒ¿¼µü*{«è‡bë¸èÇ/#[_ý¶ÿ½Ÿ´ÇÒ„óž/:ôˆö¥Ûç´Ï:蕇ÌY0÷ÄyóçƤêß‘Š?*öé?ñ™+ö›[Òž?*<Ñ|µµ\±*â{áòÂèÿ¨üÎüÖ£|—»|G3¯ÝgZù¾VùFùkùHy>Yž=”û…Üó†sïâé·Ÿ[ÞÉ“ð›ùŽÞØ+ïžYÞ™S½Ç¦e¨ûŸòíÿ¹"ß~À%ùöo¶æï>ïœyëò|óvûæ›þí°|ëgýÏÿ*õ¹ý²>–í¹ó9¥±§îùt´[Ñœ»é3ï©_Ýk {Øox㸮wåMGѺ½?=Zo2Êbë‹fÄƉþÄè—=õ¥Ñ/{êÑ/{òË£¿ám}eôã7¼ûD¿¼yàµÑw®´¾>ú[þŸïѱ֚^6÷™ÛÕXóxÖœ^ÚlµÓP·aÛW"ifÔuþ3×5ëÈC£º¡ +bhÓ:GW=sG/8iY³†÷·/|÷I6lÇ«ÖùšíªÜ¦sŒ·•¼ìgdŽGo´Ð›ÖpHÔðô3×ð¶“Ì]øþ%íGpdsÑK£zÊÉ´%M:ãÈ?ú¶‹xŸã–)5Þïó»Fu[5«Ýä
…Õ¯ÇcŸjùûúo÷cß9èÿ|¿ùÓÔÐñ·W‘Þpûô?Míj%@€ @€ @€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€0`À€¿™L»×çØ´YÅ B —òámÅ˼û¼'·¶¾7ÖÚ¯¯ÕïÉ#p4Ö3ÑŠ×úoåFÜ‘žF`ÜßÁ¸Nóâi”d|®eÔX½Q O‘Þ#÷z6øE'-ŸV¼lm™·œ•¹¯ùZÞÚõW¥iêɯË8ÏÚ;«NFOŸ¬ÑëЛÿNo±×å#òßÙók[óøë<Î~ @€ @€ @€@€€UIAppShellÀ‚" ðr
\ No newline at end of file diff --git a/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/test_spec/convertor_test_spec.html b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/test_spec/convertor_test_spec.html new file mode 100644 index 000000000000..5b77f3263654 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/test_spec/convertor_test_spec.html @@ -0,0 +1,2274 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="StarOffice 6.0 (Solaris Sparc)"> + <META NAME="AUTHOR" CONTENT="dermot mccluskey"> + <META NAME="CREATED" CONTENT="20011001;14124200"> + <META NAME="CHANGED" CONTENT="20020103;15592900"> + <STYLE> + <!-- + P.text-body-indent { margin-left: 0.5cm } + --> + </STYLE> +</HEAD> +<BODY> +<H1 ALIGN=CENTER>Xmerge Test Spec</H1> +<H2>1.0 Intorduction</H2> +<BLOCKQUOTE>This document outlines the tests to be performed on +Xmerge, the XML-to-PDB converter for the SunONE Webtop.</BLOCKQUOTE> +<H2>1.1 Authors</H2> +<UL> + <LI><P STYLE="margin-bottom: 0cm">Dermot McCluskey + (dermot.mccluskey@sun.com) + </P> + <LI><P>Keelin Boyle (keelin.boyle@sun.com) + </P> +</UL> +<H2>1.2 Project/Product Identifier</H2> +<BLOCKQUOTE>XMerge</BLOCKQUOTE> +<H2>1.3 Reision History</H2> +<P STYLE="margin-bottom: 0cm"> +</P> +<TABLE COLS=4 WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <TR> + <TD> + <P><B>Date</B></P> + </TD> + <TD> + <P><B>Revision</B></P> + </TD> + <TD> + <P><B>Comments</B></P> + </TD> + <TD> + <P><B>Approval</B></P> + </TD> + </TR> + <TR> + <TD> + <P>28-Sep-2001</P> + </TD> + <TD> + <P>0.3</P> + </TD> + <TD> + <P>Draft 3.</P> + </TD> + <TD></TD> + </TR> + <TR> + <TD></TD> + <TD></TD> + <TD></TD> + <TD></TD> + </TR> +</TABLE> +<H2>1.4 Document Customers</H2> +<UL> + <LI><P STYLE="margin-bottom: 0cm">XMerge Development team + </P> + <LI><P STYLE="margin-bottom: 0cm">Ireland Desktop Test team + </P> + <LI><P>SunONE Webtop C-team + </P> +</UL> +<H2>1.5 References</H2> +<H2>2.0 Requirements & Dependencies</H2> +<BLOCKQUOTE>Successful automation of the tests outlined in this +specification is dependent on the stability and reliability of the +POSE emulator and the EmRPC Perl module that allows test +automation. There is a risk associated with this in that +the emulator software may not accurately emulate every aspect of the +PalmOS and so the automated tests may not discover bugs which occur +in "real world" scenarios. Also, if the automation +software we use proves not to be reliable enough to consistently +return the same test results, then the effort spent creating the test +automation scripts will not be worthwhile. +</BLOCKQUOTE> +<BLOCKQUOTE>Verification of test results will depend on the usability +of the Java-based Comparator applications, developed by the US Webtop +QA team, which will be used to compare the output XML and +PDB files with the expected results. +</BLOCKQUOTE> +<BLOCKQUOTE>Many of the tests described in this specification are +very time consuming and it would not be practical to execute them +manually on a regular basis.</BLOCKQUOTE> +<H2>2.1Required Tools & Technologies</H2> +<UL> + <LI><P STYLE="margin-bottom: 0cm">PalmOS Emulator (POSE) + </P> + <LI><P STYLE="margin-bottom: 0cm">EmRPC Perl module and Test Driver + harness + </P> + <LI><P STYLE="margin-bottom: 0cm">Comparator applications (XML and + PDB comparison utilities) + </P> + <LI><P STYLE="margin-bottom: 0cm">Palm V device ??? + </P> + <LI><P>StarOffice 6.X. + </P> +</UL> +<H2>2.2 Test Framework Used</H2> +<BLOCKQUOTE>These tests are to be automated using the POSE emulator +and the Test Driver developed by the XMerge team, which interacts +with the EmRPC module and allows test engineers to write test scripts +to control the conversion of documents and the interaction with the +POSE emulator. Using this software, it is possible to automate +the process of loading documents into the appropriate Palm +application, apply edits to the document within the Palm emulator and +export the document.</BLOCKQUOTE> +<H2>3.0 Scope of Work</H2> +<H2>4.0 Test Strategy</H2> +<H2>4.1Test Suite Location</H2> +<H2>4.2 Strategy overview</H2> +<H2>4.3 Test Cases and Assertions</H2> +<H2>4.4 Testing Not Performed</H2> +<UL> + <LI><P STYLE="margin-bottom: 0cm">Performance Testing + </P> + <LI><P>Internationalization (I18N) related testing. + </P> +</UL> +<H2>5.0 Test Cases</H2> +<BLOCKQUOTE>The test cases are divided into seperate sections for +each PDB format supported by XMerge, and further divided into +Convert and Merge tests within each format. The Convert tests +validate that XMerge can perform the round trip conversion from +StarOffice XML-based file format to PalmOS PDB format and back to +StarOffice XML format again, without any loss of content. The +Merge tests validate that XMerge can merge edits made on the Palm +device with the original StarOffice XML file, while retaining any +information in the original document which could not to translated +into PDB format, eg embedded tables. +</BLOCKQUOTE> +<BLOCKQUOTE>Each section is further divided into Content and Style +tests. The Content tests deal with the ability of XMerge to +retain all the meaningful content, eg text, after the conversion and +merging process. The Style tests deal with the ability of +XMerge to retain the stylistic details, eg bold face; justification; +line breaks, from the same round-trip conversion. The +Content-retaining functionality is considered of much higher priority +than the Style-retaining functionality in version 1.1. <BR> </BLOCKQUOTE> +<H2>5.1 AportisDoc Tests</H2> +<H2>5.1.1 AportisDoc Convert Tests</H2> +<H2>5.1.1.1 AportisDoc Convert Content Tests</H2> +<TABLE WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><BR> + </P> + </TD> + <TD> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD> + <P><BR> + </P> + </TD> + <TD> + <P><BR> + </P> + </TD> + </TR> +</TABLE> +<H2>5.1.1.2 AportisDoc Convert Style Tests</H2> +<P><BR> +</P> +<H2>5.1.2 Aportis Merge Tests</H2> +<H2>5.1.2.1 AportisDoc Merge Content Tests</H2> +<TABLE WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <COL WIDTH=77*> + <COL WIDTH=179*> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><BR> + </P> + </TD> + <TD WIDTH=70%> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><BR> + </P> + </TD> + <TD WIDTH=70%> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><BR> + </P> + </TD> + <TD WIDTH=70%> + <P><BR> + </P> + </TD> + </TR> +</TABLE> +<H2>5.1.2.2 AportisDoc Merge Style Tests</H2> +<TABLE WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <COL WIDTH=72*> + <COL WIDTH=184*> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/animatedgif</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with an embedded image – + straight forward convert and merge</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_animatedgif.sxw</B>. + </P> + <P>Convert a_animatedgif.sxw to a_animatedgif.pdb, in AportisDoc + PDB format. <BR>Start POSE with AportisDoc application and import + a_animatedgif.pdb. <BR>Export the doc back to a_animatedgif.pdb. + <BR>Merge a_animatedgif.pdb and the original document to + a_animatedgif.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <BLOCKQUOTE>This document has a animated gif embedded in it.</BLOCKQUOTE> + <BLOCKQUOTE>Start of animated gif.</BLOCKQUOTE> + <BLOCKQUOTE><Image of spinning globe></BLOCKQUOTE> + <BLOCKQUOTE>End of animated gif. + </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/bolddoc</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with bold type and varying font – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_bolddoc.sxw</B>. + </P> + <P>Convert a_bolddoc.sxw to a_bolddoc.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_bolddoc.pdb. <BR>Export the doc back to a_bolddoc.pdb. <BR>Merge + a_bolddoc.pdb and the original document to a_bolddoc.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <BLOCKQUOTE><STRONG>This complete line is in <FONT SIZE=6 STYLE="font-size: 22pt">bold</FONT> + with font set to Times New Roman. The word bold is of size 22, + while rest of the words are of size 12. </STRONG> + </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/bookmarks</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with inserted bookmarks – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_bookmarks.sxw</B>. + </P> + <P>Convert a_bookmarks.sxw to a_bookmarks.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_bookmarks.pdb. <BR>Export the doc back to a_bookmarks.pdb. + <BR>Merge a_bookmarks.pdb and the original document to + a_bookmarks.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <BLOCKQUOTE>Two paragraphes of text with 2 bookmarks set. To + identify bookmarks, select Edit -> Navigator and bookmarks, + user should see BK1 and BK2 and clicking on these labels in the + navigator popup places the cursor in the position of the original + bookmark, .i.e. + </BLOCKQUOTE> + <BLOCKQUOTE>BK1 = Bookmark|</BLOCKQUOTE> + <BLOCKQUOTE>BK2 = Silicon + </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/bulletorderedlist</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with bulletorderedlist – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_bulletorderedlist.sxw</B>. + </P> + <P>Convert a_bulletorderedlist.sxw to a_bulletorderedlist.pdb, in + AportisDoc PDB format. <BR>Start POSE with AportisDoc application + and import a_bulletorderedlist.pdb. <BR>Export the doc back to + a_bulletorderedlist.pdb. <BR>Merge a_bulletorderedlist.pdb and the + original document to a_bulletorderedlist.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm; font-style: normal">This document is + an example of a simple bullet ordered list.</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <UL> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Bullet 1</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Bullet 2</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Bullet 3</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Bullet 4</P> + </UL> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <BLOCKQUOTE STYLE="font-style: normal">End of bullet Ordered list.</BLOCKQUOTE> + <BLOCKQUOTE><BR> + </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/emptydoc</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: empty document – straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_emptydoc.sxw</B>. + </P> + <P>Convert a_emptydoc.sxw to a_emptydoc.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_emptydoc.pdb. <BR>Export the doc back to a_emptydoc.pdb. <BR>Merge + a_emptydoc.pdb and the original document to a_emptydoc.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <BLOCKQUOTE><STRONG><empty document>. </STRONG> + </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/firstlineindent</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with line indent – straight + forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_firstlineindent.sxw</B>. + </P> + <P>Convert a_firstlineindent.sxw to a_firstlineindent.pdb, in + AportisDoc PDB format. <BR>Start POSE with AportisDoc application + and import a_firstlineindent.pdb. <BR>Export the doc back to + a_firstlineindent.pdb. <BR>Merge a_firstlineindent.pdb and the + original document to a_firstlineindent.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <BLOCKQUOTE>This line is using First Line indent style. Now isnt + that Kool... Also Im running short of words to say here, to wrap + this particular sentence.</BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/fontsize</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with varying font size – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_fontsize.sxw</B>. + </P> + <P>Convert a_fontsize.sxw to a_fontsize.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_fontsize.pdb. <BR>Export the doc back to a_fontsize.pdb. <BR>Merge + a_fontsize.pdb and the original document to a_fontsize.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <BLOCKQUOTE>Text with font size 10, 16, 20, 40, 96.</BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/heading</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with heading type style – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_heading.sxw</B>. + </P> + <P>Convert a_heading.sxw to a_heading.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_heading.pdb. <BR>Export the doc back to a_heading.pdb. <BR>Merge + a_heading.pdb and the original document to a_heading.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-top: 0.42cm; page-break-after: avoid"><FONT FACE="Times New Roman, serif"><FONT SIZE=4>This + piece of text is in Heading paragraph style.</FONT></FONT></P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/heading1</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with heading1 type style – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_heading1.sxw</B>. + </P> + <P>Convert a_heading1.sxw to a_heading1.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_heading1.pdb. <BR>Export the doc back to a_heading1.pdb. <BR>Merge + a_heading1.pdb and the original document to a_heading1.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <H1 STYLE="font-weight: medium">This piece of text is in Heading1 + paragraph style</H1> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/heading2</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with heading2 type style – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_heading2.sxw</B>. + </P> + <P>Convert a_heading2.sxw to a_heading2.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_heading2.pdb. <BR>Export the doc back to a_heading2.pdb. <BR>Merge + a_heading2.pdb and the original document to a_heading2.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <H2>This document is set in Heading2 style.</H2> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/hyperlink</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with embedded hyperlink – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_hyperlink.sxw</B>. + </P> + <P>Convert a_hyperlink.sxw to a_hyperlink.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_hyperlink.pdb. <BR>Export the doc back to a_hyperlink.pdb. + <BR>Merge a_hyperlink.pdb and the original document to + a_hyperlink.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm">This line is bookmarked to BK1 + (Insert-Bookmark)</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm">The line <A HREF="http://sunweb.central/allhome.html">SunWeb + Home Page</A> has a hyperlink to sunweb.central.</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm">This line is a hyperlink to <A HREF="#BK1">BK1</A>. + Click here will take cursor to top of page.</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P><Check hyperlink has the correct address.></P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/justified</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with justified styling – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_justified.sxw</B>. + </P> + <P>Convert a_justified.sxw to a_justified.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_justified.pdb. <BR>Export the doc back to a_justified.pdb. + <BR>Merge a_justified.pdb and the original document to + a_justified.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm; font-style: normal"><SUP><FONT SIZE=5 STYLE="font-size: 20pt">Left + aligned text</FONT></SUP></P> + <P ALIGN=CENTER STYLE="margin-bottom: 0cm; font-style: normal"><SUP><FONT SIZE=5 STYLE="font-size: 20pt">Centre + aligned</FONT></SUP></P> + <P ALIGN=RIGHT STYLE="margin-bottom: 0cm; font-style: normal"><SUP><FONT SIZE=5 STYLE="font-size: 20pt">Right + aligned </FONT></SUP> + </P> + <P ALIGN=JUSTIFY STYLE="font-style: normal"><SUP><FONT SIZE=5 STYLE="font-size: 20pt">Justified</FONT></SUP></P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/linebreaks</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with linebreaks – straight + forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_linebreaks.sxw</B>. + </P> + <P>Convert a_linebreaks.sxw to a_linebreaks.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_linebreaks.pdb. <BR>Export the doc back to a_linebreaks.pdb. + <BR>Merge a_linebreaks.pdb and the original document to + a_linebreaks.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm">This page has a line breaks inserted + at end of this line.<BR>When coverted to doc format it should + accordingly be broken up at the same point.</P> + <P ALIGN=LEFT STYLE="text-indent: 0.2cm; margin-top: 0.4cm; margin-bottom: 0.41cm"> + A simple list</P> + <OL> + <LI><P ALIGN=LEFT>second entry. A line break follows<BR>the above + line has been broken with a line break</P> + </OL> + <P STYLE="font-style: normal"><SUP><FONT SIZE=5 STYLE="font-size: 20pt">Third + entry</FONT></SUP></P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/linespacing</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with varied linespacing – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_linespacing.sxw</B>. + </P> + <P>Convert a_linespacing.sxw to a_linespacing.pdb, in AportisDoc + PDB format. <BR>Start POSE with AportisDoc application and import + a_linespacing.pdb. <BR>Export the doc back to a_linespacing.pdb. + <BR>Merge a_linespacing.pdb and the original document to + a_linespacing.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm"><I>First: This line and thenext line + is spaced by double-line spacing</I></P> + <P STYLE="margin-bottom: 0cm"><I>Second: Note the line-distance + spacing</I></P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm"><B>First: This line and the next + line is spaced by single-line spacing</B></P> + <P STYLE="margin-bottom: 0cm"><B>Second: Note the line-distance + spacing</B></P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm; font-weight: medium">First: This + line and the next line is spaced by 1.5 line spacing</P> + <P STYLE="font-weight: medium">Second: Not the line-distance + spacing.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/numberorderedlist</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with numberorderedlist – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_numberorderedlist.sxw</B>. + </P> + <P>Convert a_numberorderedlist.sxw to a_numberorderedlist.pdb, in + AportisDoc PDB format. <BR>Start POSE with AportisDoc application + and import a_numberorderedlist.pdb. <BR>Export the doc back to + a_numberorderedlist.pdb. <BR>Merge a_numberorderedlist.pdb and the + original document to a_numberorderedlist.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm; font-style: normal">This document is + an example of a simple numbered ordered list.</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <OL> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">First</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Second</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Third</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Fourth</P> + </OL> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm; font-style: normal">End of numbered + Ordered list</P> + <BLOCKQUOTE><BR> + </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/pagebreak</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with pagebreaks – straight + forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_pagebreak.sxw</B>. + </P> + <P>Convert a_pagebreak.sxw to a_pagebreak.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_pagebreak.pdb. <BR>Export the doc back to a_pagebreak.pdb. + <BR>Merge a_pagebreak.pdb and the original document to + a_pagebreak.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm">The document has page breaks</P> + <P STYLE="margin-bottom: 0cm">Page 1 + </P> + <P>-now a page break-</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/paragraph</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with set paragraph styling– + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_paragraph.sxw</B>. + </P> + <P>Convert a_paragraph.sxw to a_paragraph.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_paragraph.pdb. <BR>Export the doc back to a_paragraph.pdb. + <BR>Merge a_paragraph.pdb and the original document to + a_paragraph.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm">This line is a paragraph. It is + indented from left hand side by 1.0 inch and from right and side + by 1.0 inch (paragraph + </P> + <P>settings).</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/standard</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with standard text and default + settings – straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_standard.sxw</B>. + </P> + <P>Convert a_standard.sxw to a_standard.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_standard.pdb. <BR>Export the doc back to a_standard.pdb. <BR>Merge + a_standard.pdb and the original document to a_standard.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P><FONT FACE="Times New Roman">This line of text is listed in + standard style.</FONT></P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/subscript</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with subscript text setting – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_subscript.sxw</B>. + </P> + <P>Convert a_subscript.sxw to a_subscript.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_subscript.pdb. <BR>Export the doc back to a_subscript.pdb. + <BR>Merge a_subscript.pdb and the original document to + a_subscript.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman"><FONT SIZE=4>The + last word on this line is in subscript. <SPAN STYLE="font-style: normal"><SUB>Dude</SUB></SPAN></FONT></FONT></P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/superscript</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with superscript text setting – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_subscript.sxw</B>. + </P> + <P>Convert a_superscript.sxw to a_superscript.pdb, in AportisDoc + PDB format. <BR>Start POSE with AportisDoc application and import + a_superscript.pdb. <BR>Export the doc back to a_superscript.pdb. + <BR>Merge a_superscript.pdb and the original document to + a_superscript.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman"><FONT SIZE=4>The + last word on this line is in superscript. <SPAN STYLE="font-style: normal"><SUP>Dude + </SUP></SPAN></FONT></FONT> + </P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/symbols</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with various symbol types – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_symbols.sxw</B>. + </P> + <P>Convert a_symbols.sxw to a_symbols.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_symbols.pdb. <BR>Export the doc back to a_symbols.pdb. <BR>Merge + a_symbols.pdb and the original document to a_symbols.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm">'-'-'-'->->->->. + '''''''. -------. >>>>>>></P> + <P STYLE="margin-bottom: 0cm; font-style: normal"><SUP><FONT FACE="Times New Roman"><FONT SIZE=4>!”£$%^&*()_+}{~@:?><,./;'#][=-??? + </FONT></FONT></SUP> + </P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/tab</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with tab styling – straight + forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_tab.sxw</B>. + </P> + <P>Convert a_tab.sxw to a_tab.pdb, in AportisDoc PDB format. + <BR>Start POSE with AportisDoc application and import a_tab.pdb. + <BR>Export the doc back to a_tab.pdb. <BR>Merge a_tab.pdb and the + original document to a_tab.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant document should + contain: + </P> + <P STYLE="margin-bottom: 0cm">This is a tabbed document</P> + <P STYLE="margin-bottom: 0cm">1 Tab line</P> + <P STYLE="margin-bottom: 0cm">2 tabbed line</P> + <P STYLE="margin-bottom: 0cm">3 tabbed line</P> + <P STYLE="margin-bottom: 0cm">2 tabbed line</P> + <P STYLE="margin-bottom: 0cm">1 Tab line</P> + <P STYLE="margin-bottom: 0cm">4 tab line</P> + <P STYLE="margin-bottom: 0cm">2 tab line</P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/table</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with table – straight forward + convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_table.sxw</B>. + </P> + <P>Convert a_table.sxw to a_table.pdb, in AportisDoc PDB format. + <BR>Start POSE with AportisDoc application and import a_table.pdb. + <BR>Export the doc back to a_table.pdb. <BR>Merge a_table.pdb and + the original document to a_table.sxw. + </P> + <P><B>Expected result:</B> + </P> + <P>The resultant document should contain: + </P> + <P STYLE="margin-bottom: 0cm"><Check table & contents are + identical to original.> + </P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm">This document has a table with 3 + rows and 3 columns:</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P><BR><BR> + </P> + <P STYLE="margin-bottom: 0cm"><TABLE & CONTENTS></P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/textspan</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document testing textspan + italics,bolds,underline together– straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_textspan.sxw</B>. + </P> + <P>Convert a_textspan.sxw to a_textspan.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_textspan.pdb. <BR>Export the doc back to a_textspan.pdb. <BR>Merge + a_textspan.pdb and the original document to a_textspan.sxw. + </P> + <P><B>Expected result:</B> + </P> + <P>The resultant document should contain: + </P> + <P STYLE="margin-bottom: 0cm">Document indicating Text Span</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm; font-weight: medium"><I>This is a + simple line with some amount of text. The whole line is in italic + except the next 3 words which is also <B>SET TO BOLD</B>. Also the + next word is <U>UNDERLINED</U>. The essence is differnet styles + within the same text span.</I></P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/style/unorderedlist</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document with unorderedlist – straight + forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_unorderedlist.sxw</B>. + </P> + <P>Convert a_unorderedlist.sxw to a_unorderedlist.pdb, in + AportisDoc PDB format. <BR>Start POSE with AportisDoc application + and import a_unorderedlist.pdb. <BR>Export the doc back to + a_unorderedlist.pdb. <BR>Merge a_unorderedlist.pdb and the + original document to a_unorderedlist.sxw. + </P> + <P><B>Expected result:</B> + </P> + <P>The resultant document should contain: + </P> + <P STYLE="margin-bottom: 0cm; font-style: normal">This document is + an example of a simple un- ordered list</P> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <OL> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Wag the Dog</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Gladiator</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Insider</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Usual + Suspects</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Glengarry + Glen Ross</P> + </OL> + <OL> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Host Shots</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Airplane</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Monty + Python</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">History of + the World</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Sacry Movie</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Austin + Powers</P> + </OL> + <UL> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Scarlet and + the Black</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Operation + Day Break</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Life is + Beautiful</P> + <LI><P STYLE="margin-bottom: 0cm; font-style: normal">Nephew + (beutfiul soundtrack)</P> + </UL> + <P STYLE="margin-bottom: 0cm"><BR> + </P> + <P STYLE="margin-bottom: 0cm; font-style: normal; font-weight: medium"> + End of un-ordered list.</P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/content/style/wordwrap</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: document which tests wordwrapping – + straight forward convert</P> + <P><B>Procedure:</B> <BR>Use test file <B>a_wordwrap.sxw</B>. + </P> + <P>Convert a_wordwrap.sxw to a_wordwrap.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_wordwrap.pdb. <BR>Export the doc back to a_wordwrap.pdb. <BR>Merge + a_wordwrap.pdb and the original document to a_wordwrap.sxw. + </P> + <P><B>Expected result:</B> + </P> + <P>The resultant document should contain:</P> + <P STYLE="margin-bottom: 0cm; font-weight: medium"><I>This line is + a long line just to check if the word wrap feature works fine, + when it is synched onto the PDA..</I></P> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/content/simple01</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: simple document - insert text at beginning + </P> + <P><B>Procedure:</B> <BR>Use test file <B>a_standard.sxw</B>. + </P> + <P>Convert a_standard.sxw to a_standard.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_standard.pdb. <BR>Insert the following text, including the + terminating line-feed, at the beginning of the first line: + </P> + <BLOCKQUOTE>New text added to simple file.</BLOCKQUOTE> + <P>Export the doc back to a_standard.pdb. <BR>Merge a_standard.pdb + and the original document to a_standard.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <BLOCKQUOTE>New text added to simple file. <BR>This line of + text is listed in standard style </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/content/simple02</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: simple document - insert text in middle + </P> + <P><B>Procedure:</B> <BR>Use test file <B>a_standard.sxw</B>. + </P> + <P>Convert a_standard.sxw to a_standard.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_standard.pdb. <BR>Insert the following text immediately after + the word "text": + </P> + <BLOCKQUOTE>, including this inserted phrase, </BLOCKQUOTE> + <P>Export the doc back to a_standard.pdb. <BR>Merge a_standard.pdb + and the original document to a_standard.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <BLOCKQUOTE>This line of text, including this inserted + phrase, is listed in standard style </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=28%> + <P><B>aportis/merge/content/simple03</B></P> + </TD> + <TD WIDTH=72%> + <P><B>Summary</B>: simple document - append text + </P> + <P><B>Procedure:</B> <BR>Use test file <B>a_standard.sxw</B>. + </P> + <P>Convert a_standard.sxw to a_standard.pdb, in AportisDoc PDB + format. <BR>Start POSE with AportisDoc application and import + a_standard.pdb. <BR>Append a new-line at the end of the line and + add the following line: + </P> + <BLOCKQUOTE>This is also in standard style</BLOCKQUOTE> + <P>Export the doc back to a_standard.pdb. <BR>Merge a_standard.pdb + and the original document to a_standard.sxw. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <BLOCKQUOTE>This line of text is listed in standard + style <BR>This is also in standard style</BLOCKQUOTE> + </TD> + </TR> +</TABLE> +<H2>5.2 MiniCalc Tests</H2> +<H2>5.2.1 MiniCalc Convert Tests</H2> +<H2>5.2.1.1 MiniCalc Merge Style Tests</H2> +<TABLE WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <COL WIDTH=77*> + <COL WIDTH=179*> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><B>minicalc/merge/style/columnswidth</B> <BR> </P> + </TD> + <TD WIDTH=70%> + <P><B>Summary</B>: Spreadsheet with 5 columns 10 entries - + Spreadsheet columnwidth variation. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_columnswidth.sxc</B>. + </P> + <P>Convert c_columnswidth.sxc to c_columnswidth.pdb, in MiniCalc + PDB format. <BR>Start POSE with MiniCalc application and + import c_columnswidth.pdb. </P> + <P>Choose Cell Reference "B1" & alter column width + to 1.55 by selecting, Format -> Column -> Width... < make + width change via spin button> -> OK, also decrease "E1" + similarly to have a column width of 1.68.<BR><BR><BR> + </P> + <P>Export the doc back to c_columnswidth.pdb. <BR>Merge + c_columnswidth.pdb to c_columnswidth.sxw. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + column B with a width increase of 1.0 , and column E with a width + decrease of 1.0, as compared with the original file, reflecting + the changes stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><B>minicalc/merge/style/rowheight</B></P> + </TD> + <TD WIDTH=70%> + <P><B>Summary</B>: Spreadsheet with 4 columns 3 rows 12 entries - + Spreadsheet rowheight variation. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_rowheight.sxc</B>. + </P> + <P>Convert c_rowheight.sxc to c_rowheight.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_rowheight.pdb. </P> + <P><BR>Choose Cell Reference "A1" & alter row height + to 1.17 by selecting Format -> Row -> Height... <make + height change via spin button> -> OK., also decrease "A3” + similarly to have a row height of 0.30. + </P> + <P>Export the doc back to c_rowheight.pdb. <BR>Merge + c_rowheight.pdb to c_rowheight.sxw. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + row “Row 1” with a height increase of 1.0 and "Row + 3" with a height decrease of 0.41, as compared with the + original file, reflecting the changes stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><B>minicalc/merge/style/rowstyles</B></P> + </TD> + <TD WIDTH=70%> + <P><B>Summary</B>: Spreadsheet with 5 columns 6 rows 18 entries - + Spreadsheet rowstyle variation. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_rowstyle.sxc</B>. + </P> + <P>Convert c_rowstyles.sxc to c_rowstyles.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_rowstyles.pdb. </P> + <P>Choose Cell Reference "B3" and change Heading style + to default, by selecting, Format -> Style Catelog -> <choose + heading type from listbox>, also choose cellreference "D5" + and change Heading style to Heading1, also change "C5" + to remove bold, underline & italic. + </P> + <P><BR>Export the doc back to c_rowstyles.pdb. <BR>Merge + c_rowstyles.pdb to c_rowstyles.sxw. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + value's and style types as in original file, except cells "B3, + & D5" which should display heading types default & + Heading 1 resp. and "C5" which should be plain text, + reflecting the changes stated above.</P> + </TD> + </TR> +</TABLE> +<H2>5.2.1.2 MiniCalc Convert Style Tests</H2> +<TABLE WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <COL WIDTH=77*> + <COL WIDTH=179*> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><B>minicalc/convert/style/styles</B> <BR> </P> + </TD> + <TD WIDTH=70%> + <P><B>Summary</B>: Spreadsheet with 3 columns 10 rows 13 entries - + Spreadsheet styles test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_styles.sxc</B>. + </P> + <P>Convert c_styles.sxc to c_styles.pdb, in MiniCalc PDB format. + <BR>Start POSE with MiniCalc application and import c_styles.pdb. + <BR>Export the doc back to c_styles.pdb. <BR>Merge + c_styles.pdb to c_styles.sxw. </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values with style features, .i.e Bold, Italics, + .</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=30%> + <P><B>minicalc/convert/style/alignment</B><BR> </P> + </TD> + <TD WIDTH=70%> + <P><B>Summary</B>: Spreadsheet with 4 columns 8 rows 24 entries - + Spreadsheet alignment test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_alignment.sxc</B>. + </P> + <P>Convert c_alignment.sxc to c_alignment.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_alignment.pdb. <BR>Export the doc back to + c_alignment.pdb. <BR>Merge c_alignment.pdb to + c_alignment.sxw. </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values with identical alignment to original + file.</P> + </TD> + </TR> +</TABLE> +<H2><BR><BR> +</H2> +<H2>5.2.2.1 MiniCalc Merge Content Tests</H2> +<TABLE WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=0> + <COL WIDTH=77*> + <COL WIDTH=179*> + <TR> + <TD WIDTH=30% VALIGN=TOP> + <P><B>minicalc/merge/content/insertimage</B><BR> </P> + </TD> + <TD WIDTH=70% VALIGN=BOTTOM> + <P><B>Summary</B>: Spreadsheet with 6 columns 2 image inserts - + Spreadsheet image insert. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_insertimage.sxc</B>. + </P> + <P>Convert c_insertimage.sxc to c_insertimage.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_insertimage.pdb. <BR>Export the doc back to + c_insertimage.pdb. <BR>Merge c_insertimage.pdb to + c_insertimage.sxw. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + original file with both original images.</P> + </TD> + </TR> + <TR> + <TD WIDTH=30% VALIGN=TOP> + <P><B>minicalc/merge/content/textimage</B><BR> </P> + </TD> + <TD WIDTH=70% VALIGN=BOTTOM> + <P><B>Summary</B>: Spreadsheet with 6 columns 2 image inserts - + Spreadsheet image text insert. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_textimage.sxc</B>. + </P> + <P>Convert c_textimage.sxc to c_textimage.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_textimage.pdb. </P> + <P>Insert text immediately before and directly after the inserted + image.</P> + <P>Export the doc back to c_textimage.pdb. <BR>Merge + c_textimage.pdb to c_textimage.sxw. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + original image surrounded by text .i.e text before & after the + insert.</P> + </TD> + </TR> +</TABLE> +<H2>5.2.2.2 MiniCalc Convert Contents Tests</H2> +<TABLE WIDTH=1025 BORDER=1 CELLPADDING=2 CELLSPACING=0> + <COL WIDTH=431> + <COL WIDTH=584> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><BR> + </P> + </TD> + <TD WIDTH=584> + <P><BR> + </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/basic</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary: </B>simple spreadsheet - round-trip conversion + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_standard.sxc</B>. + </P> + <P>Convert c_standard.sxc to c_standard.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_standard.pdb. Export the doc back to c_standard.pdb, without + making and changes to the spreadsheet. <BR>Merge + c_standard.pdb to c_standard.sxc. + </P> + <P><B>Expected result:</B> <BR>The resultant file should be + equivalent to the original spreadsheet. <BR> </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/simple01</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: simple spreadsheet - insert text & column + of numeric values at beginning of empty sheet. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_standard.sxc</B>. + </P> + <P>Convert c_standard.sxc to c_standard.pdb, in Minicalc PDB + format. <BR>Start POSE with Minicalc application and import + c_standard.pdb. <BR>Insert the following text & values + at the beginning of the the spreadsheet, .i.e in Column 1: + </P> + <BLOCKQUOTE>Col 1</BLOCKQUOTE> + <BLOCKQUOTE>1</BLOCKQUOTE> + <BLOCKQUOTE>1</BLOCKQUOTE> + <BLOCKQUOTE>1</BLOCKQUOTE> + <P>Export the doc back to c_standard.pdb. <BR>Merge + c_standard.pdb to c_standard.sxc. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <BLOCKQUOTE STYLE="margin-left: 6.05cm">New column of values as + shown above. </BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/simple02</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: simple spreadsheet - append a new column to + end + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_standard.sxc</B>. + </P> + <P>Convert c_standard.sxc to c_standard.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_standard.pdb. <BR>Insert the following column immediately + after the first: + </P> + <BLOCKQUOTE>Col 3</BLOCKQUOTE> + <BLOCKQUOTE>3</BLOCKQUOTE> + <BLOCKQUOTE>3</BLOCKQUOTE> + <BLOCKQUOTE>3</BLOCKQUOTE> + <P>Export the doc back to c_standard.pdb. <BR>Merge + c_standard.pdb to c_standard.sxc. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <P CLASS="text-body-indent">Col 1 Col 3</P> + <BLOCKQUOTE>1 3 + </BLOCKQUOTE> + <BLOCKQUOTE>1 3</BLOCKQUOTE> + <BLOCKQUOTE>1 3</BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/simple03</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: simple spreadsheet - insert a new column in + middle + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_standard.sxc</B>. + </P> + <P>Convert c_standard.sxc to c_standard.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_standard.pdb. <BR>Insert the following column immediately + after the first and before the second: + </P> + <BLOCKQUOTE>Col 2</BLOCKQUOTE> + <BLOCKQUOTE>2</BLOCKQUOTE> + <BLOCKQUOTE>2</BLOCKQUOTE> + <BLOCKQUOTE>2</BLOCKQUOTE> + <P>Export the doc back to c_standard.pdb. <BR>Merge + c_standard.pdb to c_standard.sxc. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <BLOCKQUOTE>Col 1 Col 2 Col 3</BLOCKQUOTE> + <BLOCKQUOTE>1 2 3</BLOCKQUOTE> + <BLOCKQUOTE>1 2 3</BLOCKQUOTE> + <BLOCKQUOTE>1 2 3</BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/simple04</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: simple spreadsheet - delete text + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_standard.sxc</B>. + </P> + <P>Convert c_standard.sxc to c_standard.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_standard.pdb. <BR>Delete “Column 3”, so that + it reads: + </P> + <BLOCKQUOTE>Col 1 Col 2</BLOCKQUOTE> + <BLOCKQUOTE>1 2</BLOCKQUOTE> + <BLOCKQUOTE>1 2</BLOCKQUOTE> + <P>Export the doc back to c_standard.pdb. <BR>Merge + c_standard.pdb to c_standard.sxc. + </P> + <P><B>Expected result:</B> <BR>The resultant file should contain: + </P> + <BLOCKQUOTE>Col 1 Col 2</BLOCKQUOTE> + <BLOCKQUOTE>1 2</BLOCKQUOTE> + <BLOCKQUOTE>1 2</BLOCKQUOTE> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/addition</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 4 columns 10 entries - + Spreadsheet Simple Addition using various formulae. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_addition.sxc</B>. + </P> + <P>Convert c_addition.sxc to c_addition.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_addition.pdb. <BR>Change Cell Reference "A1" = 3 + in formula bar. <BR>Export the doc back to c_addition.pdb. + <BR>Merge c_addition.pdb to c_addition.sxc. + </P> + <P>A1 =3 ; B1 = 3 ; C1 =4 ;D1 =5; + </P> + <P>Addition types: + </P> + <P>Cell reference + Integer = A1+2 =5 + </P> + <P>Integer + Decimal = 3+0.1 =3.1 + </P> + <P>Cell Reference + Cell Reference = A1+B1 = 6 + </P> + <P>(Bracketed Cell Reference) + (Integer + Integer) = + (A1+B1)+(2+45) = 53 + </P> + <P>Integer + (Integer) + (Integer+Integer) = 2+(0)+(3+0) = 5 + </P> + <P>(SUM(Cell Ref;Cell Ref) +SUM(Cell Ref;Cell Ref) = + (SUM(A1;B1)+SUM(B1;C1) = 13 + </P> + <P><B>Expected result:</B> <BR> All spreadsheet entered + values & the standard formula SUM of each cell should be + displayed as above, formulae as stated above should be visible in + the Formula Bar. </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/backwardrange</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 7 entries - + Spreadsheet backwardranging using various formulae. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_backwardrange.sxc</B>. + </P> + <P>Convert c_alignment.sxc to c_alignment.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_alignment.pdb. <BR>Change Cell Reference "B2" = + AVERAGE(2;5;5) in formula bar. <BR>Export the doc back to + c_alignment.pdb. <BR>Merge c_alignment.pdb to + c_alignment.sxc. + </P> + <P>Logical Funtion test B4: + </P> + <P>IF(Logical Test; Then Value;Else Value) + </P> + <P>.e.g. IF(23;45.45;54.54) = 45.45 + </P> + <P>read as if logical test TRUE then place THEN VALUE in cell else + place ELSE VALUE. <BR> <BR> <BR> + </P> + <P>Statistical Functional tests B2 , B3 resp.: + </P> + <P>AVERAGE(2;5;5) - Returns sum of arguments divided by number of + arguments =4 . + </P> + <P>MAX(10;3;3) - Returns the maximum value in a list of arguments + =10. <BR> <BR> <BR> + </P> + <P>Negative addition test B1: + </P> + <P>=B2-B3 = 4 - 10 = -6 <BR> <BR> <BR> + </P> + <P>Range Addition tests A1, A5, B5: + </P> + <P>SUM(B2;B4) = B2 + B3 + B4 = 4 + 10 + 45.45 = 59.45. + </P> + <P>SUM(A1:B2) -B4 = (59.45 + (-6) +4) - 45.45 = 12</P> + <P>SUM(A1;B1)-A2 = (59.45 + (-6)) - 0 = 53.45 + </P> + <P><B>Expected result:</B> <BR> All spreadsheet entered + values & the standard formula SUM of each cell should be + displayed on sheet as detailed above, formulae as stated above + should be visible in the Formula Bar.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/boolean</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 column 2 entries - + Spreadsheet boolean entry. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_boolean.sxc</B>. + </P> + <P>Convert c_boolean.sxc to c_boolean.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_boolean.pdb. <BR>Change Cell Reference "A2" = + TRUE in formula bar. <BR>Export the doc back to + c_boolean.pdb. <BR>Merge c_boolean.pdb to c_boolean.sxc. + </P> + <P>Logical Funtion test : cells A1, A2: + </P> + <P>A1=TRUE + </P> + <P>A2=TRUE + </P> + <P>Returns the logical values TRUE to the cells resp. + </P> + <P><B>Expected result:</B> <BR> The logical entry of each + cell should be displayed on the sheet as stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cellcurrencyvalue</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 10 entries - + Spreadsheet Currency number Format conversion test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cellcurrencyvalue.sxc</B>. + </P> + <P>Convert c_cellcurrencyvalue.sxc to c_cellcurrencyvalue.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_cellcurrencyvalue.pdb. <BR>Export + the doc back to c_cellcurrencyvalue.pdb. <BR>Merge + c_cellcurrencyvalue.pdb to c_cellcurrencyvalue.sxc. + </P> + <P>Display Sheet : 12 DM. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet entered values or + the sum of each cell should be displayed with specified Currency + symbol, formulae should be visible in the Formula Bar but not the + currency symbol.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cellcurrencychange</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 10 entries - + Spreadsheet Currency number Format modification test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cellcurrencychange.sxc</B>. + </P> + <P>Convert c_cellcurrencychange.sxc to c_cellcurrencychange.pdb, + in MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_cellcurrencychange.pdb. <BR>Change + Cell Reference "A1" to have currency format in Danish + Marks (DM). <BR>Export the doc back to + c_cellcurrencychange.pdb. <BR>Merge c_cellcurrencychange.pdb + to c_cellcurrencychange.sxc. + </P> + <P>Select cell A1 = 12 ; then tap pen icon option on palm, choose + Currency from palm listbox, tap on the down arrow to the right of + the flashing cursor, tap on the intended currency type .e.g DM + (Danish Mark) and tap apply & OK. + </P> + <P>Display Sheet : 12 DM. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet entered values or + the sum of each cell should be displayed with specified Currency + symbol, formulae should be visible in the Formula Bar but not the + currency symbol.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cellfloatvalue</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 6 entries - + Spreadsheet float values. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cellfloatvalue.sxc</B>. + </P> + <P>Convert c_cellfloatvalue.sxc to c_cellfloatvalue.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_cellfloatvalue.pdb. <BR>Change Cell + Reference "A1" = 11 & "A2" = 2.38 & B3 + 100.02450 in formula bar. <BR>Export the doc back to + c_cellfloatvalue.pdb. <BR>Merge c_cellfloatvalue.pdb to + c_cellfloatvalue.sxc. + </P> + <P>The original sheet has selected Format -> Cells... -> + Numbers Tab -> & Numbers from the list box, choosen + -1234.12, tho set the Format Code to 0.00 preventing the sheet + display rounding values to two decimal places. It also has + fraction display enabled in certain cells.</P> + <P>Formula Bar : Display Sheet: + </P> + <P>A1 = 11 -> 11.00 + </P> + <P>A2 = 2.38 -> 2 19/50 + </P> + <P>A3 = 0.45 -> 0.45 + </P> + <P>B2 = 0.23 -> 2/9 + </P> + <P>B3 = 100.02450 -> 100.02 + </P> + <P><B>Expected result:</B> <BR> Spreadsheet fractional & + decimal values should be displayed with specified precision as + stated above, formulae should be visible in the Formula Bar.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cellpercentvalue</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 3 entries - + Spreadsheet percentage value precision. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cellpercentvalue.sxc</B>. + </P> + <P>Convert c_cellpercentvalue.sxc to c_cellpercentvalue.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_cellpercentvalue.pdb. <BR>Change + Cell Reference "A1" = 120% & "B1" = 10% in + formula bar. <BR>Export the doc back to + c_cellpercentvalue.pdb. <BR>Merge c_cellpercentvalue.pdb to + c_cellpercentvalue.sxc. + </P> + <P>For cell A1 enter 120% in the Formula Bar. Sheet Display = + 120.00% + </P> + <P>For cell B1 enter 10% in the Formula Bar. Sheet Display = 10% + </P> + <P><B>Expected result:</B> <BR> Spreadsheet percentage values + should be displayed with specified precision as stated above, + formulae should be visible in the Formula Bar.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cellstringvalue</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 4 columns 11 entries - + Spreadsheet String values. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cellstringvalue.sxc</B>. + </P> + <P>Convert c_cellstringvalue.sxc to c_cellstringvalue.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_cellstringvalue.pdb. <BR>Change + Cell Reference "C2" = Testing & DELETE contents of + "D2" & insert a ';' in "B3" in formula + bar. <BR>Export the doc back to c_cellstringvalue.pdb. + <BR>Merge c_cellstringvalue.pdb to c_cellstringvalue.sxc. + </P> + <P>A1 = This A2 = With A3 = For + </P> + <P>B1 = Cell B2 = Strings B3 = ; + </P> + <P>C1 = Is C2 = Testing C3 = string values + </P> + <P>D1 = Filled D2 = "blank" + </P> + <P><B>Expected result:</B> <BR> Spreadsheet strings values + should be displayed as stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/character</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 4 columns 23 entries - + Spreadsheet character values. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_character.sxc</B>. + </P> + <P>Convert c_character.sxc to c_character.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_character.pdb. <BR>Change Cell Reference "C7" = + -??%, .i.e appending a % sign. <BR>Export the doc back to + c_character.pdb. <BR>Merge c_character.pdb to + c_character.sxc. + </P> + <P>C7 = -??% + </P> + <P><B>Expected result:</B> <BR> Spreadsheet character values + should be displayed as in original file including minor change + stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cyclic</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 8 entries - + Spreadsheet error messages. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cyclic.sxc</B>. + </P> + <P>Convert c_cyclic.sxc to c_cyclic.pdb, in MiniCalc PDB format. + <BR>Start POSE with MiniCalc application and import c_cyclic.pdb. + <BR>Change Cell Reference "A4" & "A5" = 0 + & "B4" = A1/A4, "B5"= A4/A5 in formula + bar. <BR>Export the doc back to c_cyclic.pdb. <BR>Merge + c_cyclic.pdb to c_cyclic.sxc. + </P> + <P>Changes should generate 2 extra errors shown below. + </P> + <P>B4 = Err.503</P> + <P>B5 = #VALUE! + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values including 2 extra errors generated by + the changes detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/dividefloating</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 7 entries - + Spreadsheet dividing floating points. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_dividefloating.sxc</B>. + </P> + <P>Convert c_dividefloating.sxc to c_dividefloating.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_dividefloating.pdb. <BR>Change Cell + Reference "A4" = -(12.2)/(5-1) & "B2" = to + be positive, in formula bar. <BR>Export the doc back to + c_dividefloating.pdb. <BR>Merge c_dividefloating.pdb to + c_dividefloating.sxc. + </P> + <P>B2 = 03.050000 + </P> + <P>A4 = -03.05</P> + <P>Spreadsheet setting : Format -> Cells... -> Decimal + Places=6, Negative numbers red= TRUE, Leading zero's =2 -> OK. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values and newly entered floating point + division with specified precision & colour, as stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/forwardrange</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 2 columns 4 rows 5 entries - + Spreadsheet tests forwardranging. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_forwardrange.sxc</B>. + </P> + <P>Convert c_forwardrange.sxc to c_forwardrange.pdb, in MiniCalc + PDB format. <BR>Start POSE with MiniCalc application and + import c_forwardrange.pdb. <BR>Change Cell Reference "B4" + = IF(0;45.45;54.54), in formula bar. <BR>Export the doc back + to c_forwardrange.pdb. <BR>Merge c_forwardrange.pdb to + c_forwardrange.sxc. + </P> + <P>Changes IF statement to False so ELSE VALUE now valid. + </P> + <P>B4 = 54.54 + </P> + <P>A1 = SUM(B2;B4) = B2+B3+B4 =56.23 + 560 + 54.54 = 670.77 + </P> + <P><B>Expected result:</B> <BR>Spreadsheet values & the + modified standard formula SUM'sl should be displayed in each cell + on sheet to reflect the changes as stated above, formulae should + be visible in the Formula Bar. </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/hiddenrow</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 5 columns 2 rows 9 entries - + Spreadsheet tests hidden row. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_hiddenrow.sxc</B>. + </P> + <P>Convert c_hiddenrow.sxc to c_hiddenrow.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_hiddenrow.pdb. <BR>Select Format -> Row -> Show. + <BR>Export the doc back to c_hiddenrow.pdb. <BR>Merge + c_hiddenrow.pdb to c_hiddenrow.sxc. + </P> + <P>A previously hidden row 2 appears. + </P> + <P><B>Expected result:</B> <BR>Spreadsheet values & standard + formula SUM's should be displayed in each cell on sheet as before + including a new row #2 which reflects the change stated above. </P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/invalidcellref</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 3 columns 3 rows 8 entries - + Spreadsheet invalid cell references. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_invalidcellref.sxc</B>. + </P> + <P>Convert c_invalidcellref.sxc to c_invalidcellref.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_invalidcellref.pdb. <BR>Change Cell + Reference "A3" = MAX(1;2;3) , "C2" = "blank", + "C3" = a0, in formula bar. <BR>Export the doc back + to c_invalidcellref.pdb. <BR>Merge c_invalidcellref.pdb to + c_invalidcellref.sxc. + </P> + <P>Changes should generate 2 extra errors shown below. + </P> + <P>A3 = 3 + </P> + <P>C2 = "blank" + </P> + <P>C3 = #NAME? + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, excpet "C3" which holds new + invalid input warning generated by the change detailed above, + sheet should also show removal of 2 types of invalid input with + valid input replacements "A3" & "C2".</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/largerange</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 3 columns 3 rows 8 entries - + Spreadsheet large range test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_largerange.sxc</B>. + </P> + <P>Convert c_largerange.sxc to c_largerange.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_largerange.pdb. <BR>Change Cell Reference "B3" = + SUM(E7:G10), in formula bar. <BR>Export the doc back to + c_largerange.pdb. <BR>Merge c_largerange.pdb to + c_largerange.sxc. + </P> + <P>Increases the range by an extra row. + </P> + <P>B3 = SUM(E7:G10) = E7+F7+G7+E8+F8+G8+E9+F9+G9+E10+F10+G10 = + </P> + <P>= 4+4+4+2+2+4+1+4+4+1+1+12 = 31 +12 = 43 + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "B3" which holds new + larger range standard formula SUM generated by the change detailed + above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/listrange</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 5 columns 4 rows 20 entries - + Spreadsheet listrange test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_listrange.sxc</B>. + + </P> + <P>Convert c_listrange.sxc to c_listrange.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_listrange.pdb. <BR>Change Cell Reference "D3" = + 24, in formula bar. <BR>Export the doc back to + c_listrange.pdb. <BR>Merge c_listrange.pdb to + c_listrange.sxc. + </P> + <P>D3 = 24 + </P> + <P>A4 = SUM(A1:A3) = 256.1 + </P> + <P>B4 = AVERAGE(A1:A3) = 17.07 + </P> + <P>C4 = AVERAGE(A4:B4) = AVERAGE( 256.1+17.07) = 136.59 + </P> + <P>D4 = AVERAGE(D1;D2;D3) = AVERAGE( 13.1+18+24) = 18.37 + </P> + <P>E5 = SUM(A4:B4:C4:D4) = (256.1+17.07+136.59+18.37) = 428.13<BR> + <BR> <BR> + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except cells "A4-E4" which + hold the modified standard formula SUM & AVERAGE value's + generated by the change in D3 detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/mathematical</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 5 columns 3 rows 15 entries - + Spreadsheet stanadard math functs test in (Rad). + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_mathematical.sxc</B>. + + </P> + <P>Convert c_mathematical.sxc to c_mathematical.pdb, in MiniCalc + PDB format. <BR>Start POSE with MiniCalc application and + import c_mathematical.pdb. <BR>Change Cell Reference "B1" + = SIN(3.14/2), "B2" =COS(0), "C3"= TAN(1.57/2) + in formula bar. <BR>Export the doc back to + c_mathematical.pdb. <BR>Merge c_mathematical.pdb to + c_mathematical.sxc. + </P> + <P>B1 = 1</P> + <P>B2 = 1 + </P> + <P>C3 =1 + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values except cells "B1,B2,C3" which + hold modified sin,cos & tan value's generated by the changes + stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/protection</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 column 3 rows 3 entries - + Spreadsheet protection test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_protection.sxc</B>. + + </P> + <P>Convert c_protection.sxc to c_protection.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_protection.pdb. <BR>Attempt to Change Cell Reference "A1" + either directly or in formula bar from the value 12 to 1. + <BR>Export the doc back to c_protection.pdb. <BR>Merge + c_protection.pdb to c_protection.sxc. + </P> + <P>User should be unable to change cell contents, popup error + message "Protected cells can not be modified" should + appear. + </P> + <P>This is because the Tools -> Protect Document -> Sheet + option has been enabled with a password and therefore all cells on + sheet are write protected. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/renamedsheet</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 3 sheets 0 entries - + Spreadsheet rename test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_renamedsheet.sxc</B>. + + </P> + <P>Convert c_renamedsheet.sxc to c_renamedsheet.pdb, in MiniCalc + PDB format. <BR>Start POSE with MiniCalc application and + import c_renamedsheet.pdb. <BR>Change sheet named "testplan" + to "renamed". <BR>Export the doc back to + c_renamedsheet.pdb. <BR>Merge c_renamedsheet.pdb to + c_renamedsheet.sxc. + </P> + <P>Click on "testplan" sheet tab, and using 3<SUP>rd</SUP> + mouse button, choose Rename..., from popup menu, enter new sheet + name & OK. + </P> + <P>OR choose Format -> Sheet -> Rename... enter new sheet + name & OK. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheets & names, with the exception of the + "testplan" sheet which should now be labelled "renamed" + .</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/sheetreference</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 3 sheets 4 columns 4 rows 11 + entries - Spreadsheet sheetreference test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_sheetreference.sxc</B>. + + </P> + <P>Convert c_sheetreference.sxc to c_sheetreference.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_sheetreference.pdb. <BR>Change Cell + Reference "A3" = Sheet3.B1. <BR>Export the doc + back to c_sheetrefernce.pdb. <BR>Merge c_sheetreference.pdb + to c_sheetreference.sxc. + </P> + <P>A3 = 3. + </P> + <P>B4 =26.</P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original value's & formulae as in original file, except + cells "A3"& "A4" which should display a + different sheet reference value and the modified sheet reference + formula, reflecting the changes stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/smallrange</B> <BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 4 columns 3 rows 10 entries - + Spreadsheet small range test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_smallrange.sxc</B>. + + </P> + <P>Convert c_smallrange.sxc to c_smallrange.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_smallrange.pdb. <BR>Change Cell Reference "B3" = + AVERAGE(A1:B2), in formula bar. <BR>Export the doc back to + c_smallrange.pdb. <BR>Merge c_smallrange.pdb to + c_smallrange.sxc. + </P> + <P>Decrease the range by 1 row. + </P> + <P>B3 = AVERAGE(A1:B2) = (1+2+3+3)/4 = 2.25 + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A3" which now holds + average value of new smaller range generated by the change + detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cancel</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm confirm &cancel test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cancel.sxc</B>. + </P> + <P>Convert c_cancel.sxc to c_cancel.pdb, in MiniCalc PDB format. + <BR>Start POSE with MiniCalc application and import c_cancel.pdb. + <BR>Select with mouse Cell Reference "A2" on dotted line + on palm type 14, tap “TICK” option (leftmost option on + palm) to confirm, repeat this step this time Changing Cell + Reference “A2” = 1, except this time tap the “X” + option to cancel. <BR>Export the doc back to c_cancel.pdb. + <BR>Merge c_cancel.pdb to c_cancel.sxc. + </P> + <P>A2 = 14. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A2" which now holds + the value 14 generated by the change detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/cut&paste</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm cut&paste test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_cut&paste.sxc</B>. + + </P> + <P>Convert c_cut&paste.sxc to c_cut&paste.pdb, in MiniCalc + PDB format. <BR>Start POSE with MiniCalc application and + import c_cut&paste.pdb. <BR>Choose Cell Reference "A2" + with mouse, tap cut option on palm, choose Cell Reference “A5” + and tap paste option. <BR>Export the doc back to + c_cut&paste.pdb. <BR>Merge c_cut&paste.pdb to + c_cut&paste.sxc. + </P> + <P>A2 = “blank”.</P> + <P>A5 = 14. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A2" & “A5” + which now holds the values blank & 14 resp. generated by the + changes detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/copy&paste</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm copy&paste test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_copy&paste.sxc</B>. + + </P> + <P>Convert c_copy&paste.sxc to c_copy&paste.pdb, in + MiniCalc PDB format. <BR>Start POSE with MiniCalc + application and import c_copy&paste.pdb. <BR>Choose Cell + Reference "A5" with mouse, tap copy option on palm, + choose Cell Reference “A2” and tap paste option. + <BR>Export the doc back to c_copy&paste.pdb. <BR>Merge + c_copy&paste.pdb to c_copy&paste.sxc. + </P> + <P>A2 = 14.</P> + <P>A5 = 14. + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A2" which now holds + the value 14 generated by the change detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/textentry</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm text entry test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_textentry.sxc</B>. + + </P> + <P>Convert c_textentry.sxc to c_textentry.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_textentry.pdb. <BR>Choose Cell Reference "A1" + with mouse, tap textentry option on palm, type the following text + string into the popup text box “This is a MiniCalc text + entry test.”.<BR>Export the doc back to c_textentry.pdb. + <BR>Merge c_textentry.pdb to c_textentry.sxc. + </P> + <P>A1 = “This is a MiniCalc text entry test.”</P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A1" which now holds + the string “This is a MiniCalc text entry test”, + generated by the change detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/function</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm function test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_function.sxc</B>. + + </P> + <P>Convert c_function.sxc to c_function.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_function.pdb. <BR>Choose Cell Reference "A1" + with mouse, tap standard function option on palm, choose the + function AVERAGE from the popup list by tapping, type the values + “1;2;3” between the function brackets on the dotted + line were the cursor is placed and press return.<BR>Export the doc + back to c_function.pdb. <BR>Merge c_function.pdb to + c_function.sxc. + </P> + <P>A1 = AVERAGE(1;2;3) = 2.</P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A1" which now holds + the result of the average function given args (1;2;3) = 2 + generated by the change detailed above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/numberpad</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm numberpad test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_numberpad.sxc</B>. + + </P> + <P>Convert c_numberpad.sxc to c_numberpad.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_numberpad.pdb. <BR>Choose Cell Reference "A1" + with mouse, tap the “123” option on the palm, tap + “->”, “=”, “5-0+2” from + popup numberpad, and press return.<BR>Export the doc back to + c_numberpad.pdb. <BR>Merge c_numberpad.pdb to + c_numberpad.sxc. + </P> + <P>A1 = 5-0+2 = 7.</P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A1" which now holds + the result of the formula 5-0+2, generated by the change detailed + above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/math_funcs</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm numberpad test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_math_funcs.sxc</B>. + + </P> + <P>Convert c_math_funcs.sxc to c_math_funcs.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_math_funcs.pdb. <BR>Choose the Cell References below with + mouse,and for each type on the palm the corresponding entry before + pressing return.</P> + <P>A1 = <BR>Export the doc back to c_math_funcs.pdb. <BR>Merge + c_math_funcs.pdb to c_math_funcs.sxc. + </P> + <P>A1 = .</P> + <P>A2 =</P> + <P>A3 = + </P> + <P>A4 =</P> + <P><BR><BR> + </P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A1" which now holds + the result of the formula 5-0+2, generated by the change detailed + above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/insertrow</B><BR> </P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 columns 4 rows 4entries - + Spreadsheet palm insert row test. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_insertrow.sxc</B>. + + </P> + <P>Convert c_insertrow.sxc to c_insertrow.pdb, in MiniCalc PDB + format. <BR>Start POSE with MiniCalc application and import + c_insertrow.pdb. </P> + <P><BR>Select Cell Reference "A3" with mouse, tap the + side bar of the spreadsheet at position 3 on the palm, tap + “Insert” from popup menu, and press return. Select the + newly inserted Cell Reference with mouse and enter the number “2”, + press return.<BR><BR><BR> + </P> + <P>Export the doc back to c_insertrow.pdb. <BR>Merge + c_insertrow.pdb to c_insertrow.sxc. + </P> + <P>A1 = .</P> + <P><B>Expected result:</B> <BR> Spreadsheet should display + all original sheet values, except "A1" which now holds + the result of the formula 5-0+2, generated by the change detailed + above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><B>minicalc/convert/content/multi_boolean</B></P> + </TD> + <TD WIDTH=584> + <P><B>Summary</B>: Spreadsheet with 1 column 8 entries - + Spreadsheet multi boolean entry. + </P> + <P><B>Procedure:</B> <BR>Use test file <B>c_multi_boolean.sxc</B>. + + </P> + <P>Convert c_multi_boolean.sxc to c_multi_boolean.pdb, in MiniCalc + PDB format. <BR>Start POSE with MiniCalc application and + import c_multi_boolean.pdb. <BR>Export the doc back to + c_multi_boolean.pdb. <BR>Merge c_multi_boolean.pdb to + c_multi_boolean.sxc. + </P> + <P>Logical Funtion test : cells A1-A4: + </P> + <P>A1-A4 = FALSE + </P> + <P>A5-A8 = TRUE + </P> + <P>Returns 4 logical FALSE & TRUE values resp.. + </P> + <P><B>Expected result:</B> <BR> The logical entry of each + cell should be displayed on the sheet as stated above.</P> + </TD> + </TR> + <TR VALIGN=TOP> + <TD WIDTH=431> + <P><BR> + </P> + </TD> + <TD WIDTH=584> + <P><BR> + </P> + </TD> + </TR> +</TABLE> +<P><BR> <BR> <BR> +</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedBinaryObject.java b/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedBinaryObject.java new file mode 100644 index 000000000000..8b6d0d3a4c7c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedBinaryObject.java @@ -0,0 +1,131 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: EmbeddedBinaryObject.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import org.w3c.dom.Document; +import org.w3c.dom.DOMException; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + + +/** + * This class represents embedded object's in an OpenOffice.org document that + * have a binary representation. + */ +public class EmbeddedBinaryObject extends EmbeddedObject { + + /** The object's binary representation. */ + protected byte[] objData = null; + + /** + * Constructor for an embedded object stored using an XML representation. + * + * @param name The name of the object. + * @param type The mime-type of the object. See the class summary. + */ + public EmbeddedBinaryObject(String name, String type) { + super(name, type); + } + + + /** + * Package private constructor for use when reading an object from a + * compressed SX? file. + * + * @param name The name of the object. + * @param type The mime-type of the object. See the class summary. + * @param source The OfficeZip representation of the SX? file that stores + * the object. + */ + EmbeddedBinaryObject(String name, String type, OfficeZip source) { + super(name, type, source); + } + + + /** + * This method returns the data for this object. + * + * @return A <code>byte</code> array containing the object's data. + */ + public byte[] getBinaryData() { + + if (objData == null) { + // See if we came from a Zip file + if (zipFile != null) { + objData = zipFile.getNamedBytes(objName); + } + } + + return objData; + } + + + /** + * Sets the data for this object. + * + * @param data A <code>byte</code> array containing data for the object. + */ + public void setBinaryData(byte[] data) { + objData = data; + hasChanged = true; + } + + /** + * Package private method for writing the data of the EmbeddedObject to a + * SX? file. + * + * @param zip An <code>OfficeZip</code> instance representing the file + * the data is to be written to. + */ + void write(OfficeZip zip) { + if (hasChanged) { + zip.setNamedBytes(objName, objData); + } + } + + + /** + * Package private method that constructs the manifest.xml entries for this + * embedded object. + * + * @return Document <code>Document</code> containing the manifest entries. + */ + void writeManifestData(Document manifestDoc) throws DOMException { + Element objNode = manifestDoc.createElement(OfficeConstants.TAG_MANIFEST_FILE); + + objNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_TYPE, objType); + objNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_PATH, objName); + + manifestDoc.getDocumentElement().appendChild(objNode); + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedObject.java b/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedObject.java new file mode 100644 index 000000000000..528475ab9124 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedObject.java @@ -0,0 +1,120 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: EmbeddedObject.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml; + +import java.io.IOException; + +import org.w3c.dom.Document; +import org.w3c.dom.DOMException; + + +public abstract class EmbeddedObject { + protected String objName; + protected String objType; + + /** Representation of the file from which this object was read. */ + protected OfficeZip zipFile = null; + + /** Flag indicating if this document has changed since reading or is new. */ + protected boolean hasChanged = false; + + /** + * Constructor for an embedded object stored using an XML representation. + * + * @param name The name of the object. + * @param type The mime-type of the object. See the class summary. + */ + public EmbeddedObject(String name, String type) { + objName = name; + objType = type; + + hasChanged = true; + } + + + /** + * Package private constructor for use when reading an object from a + * compressed SX? file. + * + * @param name The name of the object. + * @param type The mime-type of the object. See the class summary. + * @param source The OfficeZip representation of the SX? file that stores + * the object. + */ + EmbeddedObject(String name, String type, OfficeZip source) { + this(name, type); + zipFile = source; + } + + + /** + * Retrieves the name of the embedded object represented by an instance of + * this class. + * + * <b>N.B.</b>The name referes to the name as found in the + * <code>META-INF/manifest.xml</code> file. + * + * @return The name of the object. + */ + public final String getName() { + return objName; + } + + + /** + * Retrieves the type of the embedded object represented by an instance of + * this class. + * + * The <code>META-INF/manifest.xml</code> file currently represents the + * type of an object using MIME types. + */ + public final String getType() { + return objType; + } + + /** + * Package private method for writing the data of the EmbeddedObject to a + * SX? file. + * + * @param zip An <code>OfficeZip</code> instance representing the file + * the data is to be written to. + */ + abstract void write(OfficeZip zip) throws IOException; + + /** + * Package private method that constructs the manifest.xml entries for this + * embedded object. + * + * @return Document <code>Document</code> containing the manifest entries. + */ + abstract void writeManifestData(Document manifestDoc) throws DOMException; +}
\ No newline at end of file diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedXMLObject.java b/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedXMLObject.java new file mode 100644 index 000000000000..bdcb53cd8bf0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/EmbeddedXMLObject.java @@ -0,0 +1,301 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: EmbeddedXMLObject.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.DOMException; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * This class represents those embedded objects in an OpenOffice.org document + * that have an XML representation. Currently, according to the OpenOffice.org + * File Format 1.0 document, there are 6 such objects: + * + * Formulae created with Math (application/vnd.sun.xml.math) + * Charts created with Chart (application/vnd.sun.xml.chart) + * Spreadsheets created with Calc (application/vnd.sun.xml.calc) + * Text created with Writer (application/vnd.sun.xml.writer) + * Drawings created with Draw (application/vnd.sun.xml.draw) + * Presentations created with Impress (application/vnd.sun.xml.impress) + * + * These object types are stored using a combination of content, settings and styles + * XML files. + */ +public class EmbeddedXMLObject extends EmbeddedObject { + + // Entries for the subdocuments that constitute this object; + protected Document contentDOM = null; + protected Document settingsDOM = null; + protected Document stylesDOM = null; + + private DocumentBuilder builder = null; + + /** + * Constructor for an embedded object stored using an XML representation. + * + * @param name The name of the object. + * @param type The mime-type of the object. See the class summary. + */ + public EmbeddedXMLObject(String name, String type) { + super(name, type); + } + + /** + * Package private constructor for use when reading an object from a + * compressed SX? file. + * + * @param name The name of the object. + * @param type The mime-type of the object. See the class summary. + * @param source The OfficeZip representation of the SX? file that stores + * the object. + */ + EmbeddedXMLObject(String name, String type, OfficeZip source) { + super(name, type, source); + } + + + /** + * Returns the content data for this embedded object. + * + * @return DOM represenation of "content.xml" + * + * @throws SAXException If any parser error occurs + * @throws IOException If any IO error occurs + */ + public Document getContentDOM() throws SAXException, IOException { + + if (contentDOM == null) { + contentDOM = getNamedDOM("content.xml"); + } + + return contentDOM; + } + + + /** + * Sets the content data for the embedded object. + * + * @param content DOM representation of the object's content. + */ + public void setContentDOM(Document content) { + contentDOM = content; + hasChanged = true; + } + + + /** + * Returns the settings data for this embedded object. + * + * @return DOM represenation of "settings.xml" + * + * @throws SAXException If any parser error occurs + * @throws IOException If any IO error occurs + */ + public Document getSettingsDOM() throws SAXException, IOException { + + if (settingsDOM == null) { + settingsDOM = getNamedDOM("settings.xml"); + } + + return settingsDOM; + } + + + /** + * Sets the settings data for the embedded object. + * + * @param styles DOM representation of the object's styles. + */ + public void setSettingsDOM(Document settings) { + settingsDOM = settings; + hasChanged = true; + } + + + /** + * Returns the style data for this embedded object. + * + * @return DOM represenation of "styles.xml" + * + * @throws SAXException If any parser error occurs + * @throws IOException If any IO error occurs + */ + public Document getStylesDOM() throws SAXException, IOException { + + if (stylesDOM == null) { + stylesDOM = getNamedDOM("styles.xml"); + } + + return stylesDOM; + } + + + /** + * Sets the styles data for the embedded object. + * + * @param styles DOM representation of the object's styles. + */ + public void setStylesDOM(Document styles) { + stylesDOM = styles; + hasChanged = true; + } + + + /** + * This method extracts the data for the given XML file from the SX? file + * and creates a DOM representation of it. + * + * @param name The name of the XML file to retrieve. It is paired with + * the object name to access the SX? file. + * + * @return DOM representation of the named XML file. + * + * @throws SAXException If any parser error occurs + * @throws IOException If any IO error occurs + */ + private Document getNamedDOM(String name) throws SAXException, IOException { + if (zipFile == null) { + return null; + } + + try { + if (builder == null) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + factory.setValidating(false); + builder = factory.newDocumentBuilder(); + } + + byte[] data = zipFile.getNamedBytes(new String(objName + "/" + name)); + if (data != null) { + return OfficeDocument.parse(builder, data); + } + else { + return null; + } + + } + catch (SAXException se) { + throw se; + } + catch (IOException ioe) { + throw ioe; + } + catch (ParserConfigurationException pce) { + throw new SAXException(pce); + } + } + + + /** + * Package private method for writing the data of the EmbeddedObject to a + * SX? file. + * + * @param zip An <code>OfficeZip</code> instance representing the file + * the data is to be written to. + */ + void write(OfficeZip zip) throws IOException { + if (hasChanged == true) { + if (contentDOM != null) { + zip.setNamedBytes(new String(objName + "/content.xml"), + OfficeDocument.docToBytes(contentDOM)); + } + if (settingsDOM != null) { + zip.setNamedBytes(new String(objName + "/settings.xml"), + OfficeDocument.docToBytes(settingsDOM)); + } + if (stylesDOM != null) { + zip.setNamedBytes(new String(objName + "/styles.xml"), + OfficeDocument.docToBytes(stylesDOM)); + } + } + } + + /** + * Package private method that constructs the manifest.xml entries for this + * embedded object. + * + * @param manifestDoc <code>Document</code> containing the manifest entries. + */ + void writeManifestData(Document manifestDoc) throws DOMException { + Node root = manifestDoc.getDocumentElement(); + + if (contentDOM != null) { + Element contentNode = manifestDoc.createElement(OfficeConstants.TAG_MANIFEST_FILE); + + contentNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + contentNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_PATH, + new String(objName + "/content.xml")); + + root.appendChild(contentNode); + } + + if (settingsDOM != null) { + Element settingsNode = manifestDoc.createElement(OfficeConstants.TAG_MANIFEST_FILE); + + settingsNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + settingsNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_PATH, + new String(objName + "/settings.xml")); + + root.appendChild(settingsNode); + } + + if (stylesDOM != null) { + Element stylesNode = manifestDoc.createElement(OfficeConstants.TAG_MANIFEST_FILE); + + stylesNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + stylesNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_PATH, + new String(objName + "/styles.xml")); + } + + + Element objectNode = manifestDoc.createElement(OfficeConstants.TAG_MANIFEST_FILE); + + objectNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_TYPE, objType); + objectNode.setAttribute(OfficeConstants.ATTRIBUTE_MANIFEST_FILE_PATH, + new String(objName + "/")); + + root.appendChild(objectNode); + } + +}
\ No newline at end of file diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeConstants.java new file mode 100644 index 000000000000..f58d7a64beac --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeConstants.java @@ -0,0 +1,442 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OfficeConstants.java,v $ + * $Revision: 1.12 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +/** + * This interface contains constants for StarOffice XML tags, + * attributes (StarCalc cell types, etc.). + * + * @author Herbie Ong, Paul Rank, Martin Maher + */ +public interface OfficeConstants { + + /** Element tag for <i>office:document</i>, this is the root tag. */ + public final static String TAG_OFFICE_DOCUMENT = "office:document"; + + /** + * Element tag for <i>office:document-content</i>, this is the root + * tag in content.xml. + */ + public final static String TAG_OFFICE_DOCUMENT_CONTENT = "office:document-content"; + + /** + * Element tag for <i>office:document-settings</i>, this is the root + * tag in content.xml. + */ + public final static String TAG_OFFICE_DOCUMENT_SETTINGS= "office:document-settings"; + + /** + * Element tag for <i>office:document-meta</i>, this is the root + * tag in content.xml. + */ + public final static String TAG_OFFICE_DOCUMENT_META= "office:document-meta"; + + /** + * Element tag for <i>office:document-styles</i>, this is the root tag + * in styles.xml. + */ + public final static String TAG_OFFICE_DOCUMENT_STYLES = "office:document-styles"; + + /** + * Attribute tag for <i>office:class</i> of element + * <i>office:document</i>. + */ + public final static String ATTRIBUTE_OFFICE_CLASS = "office:class"; + + /** Element tag for <i>office:styles</i>. */ + public final static String TAG_OFFICE_STYLES = "office:styles"; + + /** Element tag for <i>office:meta</i>. */ + public final static String TAG_OFFICE_META = "office:meta"; + + /** Element tag for <i>office:automatic-styles</i>. */ + public final static String TAG_OFFICE_AUTOMATIC_STYLES = "office:automatic-styles"; + + /** Element tag for <i>office:master-styles</i>. */ + public final static String TAG_OFFICE_MASTER_STYLES = "office:master-styles"; + + /** Element tag for <i>office:body</i>. */ + public final static String TAG_OFFICE_BODY = "office:body"; + + /** Element tag for <i>office:settings</i>. */ + public final static String TAG_OFFICE_SETTINGS = "office:settings"; + + //Adding + + /** Element tag for <i>text:variable-set</i>. */ + public final static String TAG_TEXT_VARIABLE_SET = "text:variable-set"; + + /** Element tag for <i>text:variable-get</i>. */ + public final static String TAG_TEXT_VARIABLE_GET = "text:variable-get"; +/** Element tag for <i>text:expression</i>. */ + public final static String TAG_TEXT_EXPRESSION = "text:expression"; + +/** Element tag for <i>text:user-field-get</i>. */ + public final static String TAG_TEXT_USER_FIELD_GET = "text:user-field-get"; + +/** Element tag for <i>text:page-variable-get</i>. */ + public final static String TAG_TEXT_PAGE_VARIABLE_GET = "text:page-variable-get"; +/** Element tag for <i>text:sequence</i>. */ + public final static String TAG_TEXT_SEQUENCE = "text:sequence"; + + /** Element tag for <i>text:text-input</i>. */ + public final static String TAG_TEXT_VARIABLE_INPUT = "text:variable-input"; + /** Element tag for <i>text:time</i>. */ + public final static String TAG_TEXT_TIME = "text:time"; + + /** Element tag for <i>text:page-count</i>. */ + public final static String TAG_TEXT_PAGE_COUNT = "text:page-count"; + /** Element tag for <i>text:page-number</i>. */ + public final static String TAG_TEXT_PAGE_NUMBER = "text:page-number"; + /** Element tag for <i>text:author-initials</i>. */ + public final static String TAG_TEXT_AUTHOR_INITIALS = "text:author-initials"; + /** Element tag for <i>text:subject</i>. */ + public final static String TAG_TEXT_SUBJECT = "text:subject"; + /** Element tag for <i>text:title</i>. */ + public final static String TAG_TEXT_TITLE = "text:title"; + /** Element tag for <i>text:creation-time</i>. */ + public final static String TAG_TEXT_CREATION_TIME = "text:creation-time"; + + /** Element tag for <i>text:date</i>. */ + public final static String TAG_TEXT_DATE = "text:date"; + /** Element tag for <i>text:text-input</i>. */ + public final static String TAG_TEXT_TEXT_INPUT = "text:text-input"; + + +//end adding + + /** Element tag for <i>office:font-decls</i>. */ + public final static String TAG_OFFICE_FONT_DECLS = "office:font-decls"; + + /** Element tag for <i>style:font-decl</i>. */ + public final static String TAG_STYLE_FONT_DECL = "style:font-decl"; + + /** Attribute tag for <i>style:name</i> of element <i>style:name</i>. */ + public final static String ATTRIBUTE_STYLE_NAME = "style:name"; + + /** + * Attribute tag for <i>style:font-pitch</i> of element + * <i>style:font-pitch</i>. + */ + public final static String ATTRIBUTE_STYLE_FONT_PITCH = "style:font-pitch"; + + /** + * Attribute tag for <i>fo:font-family</i> of element + * <i>fo:font-family</i>. + */ + public final static String ATTRIBUTE_FO_FONT_FAMILY = "fo:font-family"; + + /** + * Attribute tag for <i>fo:font-family</i> of element + * <i>fo:font-family</i>. + */ + public final static String ATTRIBUTE_FO_FONT_FAMILY_GENERIC = "fo:font-family-generic"; + + /** Element tag for <i>text:p</i>. */ + public final static String TAG_PARAGRAPH = "text:p"; + + /** Element tag for <i>text:</i>. */ + public final static String TAG_TEXT = "text:"; + + /** Element tag for <i>text:h</i>. */ + public final static String TAG_HEADING = "text:h"; + + /** Element tag for <i>text:s</i>. */ + public final static String TAG_SPACE = "text:s"; + + /** Element tag for <i>text:tab-stop</i>. */ + public final static String TAG_TAB_STOP = "text:tab-stop"; + + /** Element tag for <i>text:line-break</i>. */ + public final static String TAG_LINE_BREAK = "text:line-break"; + + /** Element tag for <i>text:span</i>. */ + public final static String TAG_SPAN = "text:span"; + + /** Element tag for <i>text:a</i>. */ + public final static String TAG_HYPERLINK = "text:a"; + + /** Element tag for <i>text:bookmark</i>. */ + public final static String TAG_BOOKMARK = "text:bookmark"; + + /** Element tag for <i>text:bookmark-start</i>. */ + public final static String TAG_BOOKMARK_START = "text:bookmark-start"; + + /** Element tag for <i>text:unordered-list</i>. */ + public final static String TAG_UNORDERED_LIST = "text:unordered-list"; + + /** Element tag for <i>text:ordered-list</i>. */ + public final static String TAG_ORDERED_LIST = "text:ordered-list"; + + /** Element tag for <i>text:list-header</i>. */ + public final static String TAG_LIST_HEADER = "text:list-header"; + + /** Element tag for <i>text:list-item</i>. */ + public final static String TAG_LIST_ITEM = "text:list-item"; + + /** Attribute tag for <i>text:c</i> of element <i>text:s</i>. */ + public final static String ATTRIBUTE_SPACE_COUNT = "text:c"; + + /** + * Attribute tag for <i>text:style-name</i> of element + * <i>text:style-name</i>. + */ + public final static String ATTRIBUTE_TEXT_STYLE_NAME = "text:style-name"; + + /** Element tag for <i>table:table</i>. */ + public final static String TAG_TABLE = "table:table"; + + /** Element tag for <i>table:named-expression</i>. */ + public final static String TAG_NAMED_EXPRESSIONS = "table:named-expressions"; + + /** Element tag for <i>table:named-range</i>. */ + public final static String TAG_TABLE_NAMED_RANGE= "table:named-range"; + + /** Element tag for <i>table:named-expression</i>. */ + public final static String TAG_TABLE_NAMED_EXPRESSION= "table:named-expression"; + + /** + * Attribute tag for <i>table:name</i> of element + * <i>table:table</i>. + */ + public final static String ATTRIBUTE_TABLE_NAME = "table:name"; + + /** + * Attribute tag for <i>table:expression</i> of element + * <i>table:named-range</i>. + */ + public final static String ATTRIBUTE_TABLE_EXPRESSION = "table:expression"; + + /** + * Attribute tag for <i>table:base-cell-address</i> of element + * <i>table:named-range</i>. + */ + public final static String ATTRIBUTE_TABLE_BASE_CELL_ADDRESS = "table:base-cell-address"; + + /** + * Attribute tag for <i>table:cell-range-address</i> of element + * <i>table:named-range</i>. + */ + public final static String ATTRIBUTE_TABLE_CELL_RANGE_ADDRESS = "table:cell-range-address"; + + /** Element tag for <i>table:table-row</i>. */ + public final static String TAG_TABLE_ROW = "table:table-row"; + + /** Element tag for <i>table:table-column</i>. */ + public final static String TAG_TABLE_COLUMN = "table:table-column"; + + /** + * Attribute tag for <i>table:default-cell-style-name</i> + * of element <i>table:table-column</i>. + */ + public final static String ATTRIBUTE_DEFAULT_CELL_STYLE = "table:default-cell-style-name"; + + /** Element tag for <i>table:scenario</i>. */ + public final static String TAG_TABLE_SCENARIO = "table:scenario"; + + /** Element tag for <i>table:table-cell</i>. */ + public final static String TAG_TABLE_CELL = "table:table-cell"; + + /** + * Attribute tag for <i>table:value-type</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_VALUE_TYPE = "table:value-type"; + + /** + * Attribute tag for <i>table:number-columns-repeated</i> + * of element <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED = + "table:number-columns-repeated"; + + /** + * Attribute tag for <i>table:number-rows-repeated</i> + * of element <i>table:table-row</i>. + */ + public final static String ATTRIBUTE_TABLE_NUM_ROWS_REPEATED = + "table:number-rows-repeated"; + + /** + * Attribute tag for <i>table:formula</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_FORMULA = "table:formula"; + + /** + * Attribute tag for <i>table:value</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_VALUE = "table:value"; + + /** + * Attribute tag for <i>table:date-value</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_DATE_VALUE = "table:date-value"; + + /** + * Attribute tag for <i>table:time-value</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_TIME_VALUE = "table:time-value"; + + /** + * Attribute tag for <i>table:string-value</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_STRING_VALUE = + "table:string-value"; + + /** + * Attribute tag for <i>table:time-boolean-value</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_BOOLEAN_VALUE = + "table:boolean-value"; + + /** Attribute tag for <i>table:style-name</i> of table elements. */ + public final static String ATTRIBUTE_TABLE_STYLE_NAME = "table:style-name"; + + /** + * Attribute tag for <i>table:currency</i> of element + * <i>table:table-cell</i>. + */ + public final static String ATTRIBUTE_TABLE_CURRENCY = "table:currency"; + + /** The cell contains data of type <i>string</i>. */ + public final static String CELLTYPE_STRING = "string"; + + /** The cell contains data of type <i>float</i>. */ + public final static String CELLTYPE_FLOAT = "float"; + + /** The cell contains data of type <i>time</i>. */ + public final static String CELLTYPE_TIME = "time"; + + /** The cell contains data of type <i>date</i>. */ + public final static String CELLTYPE_DATE = "date"; + + /** The cell contains data of type <i>currency</i>. */ + public final static String CELLTYPE_CURRENCY = "currency"; + + /** The cell contains data of type <i>boolean</i>. */ + public final static String CELLTYPE_BOOLEAN = "boolean"; + + /** The cell contains data of type <i>percent</i>. */ + public final static String CELLTYPE_PERCENT = "percentage"; + + /** StarWriter XML file extension. */ + public final static String SXW_FILE_EXTENSION = ".sxw"; + + /** StarWriter XML <i>office:class</i> value. */ + public final static String SXW_TYPE = "text"; + + /** StarCalc XML file extension. */ + public final static String SXC_FILE_EXTENSION = ".sxc"; + + /** StarCalc XML <i>office:class</i> value. */ + public final static String SXC_TYPE = "spreadsheet"; + + /** Element tag for <i>manifest:manifest</i>entry in Manifest XML */ + public final static String TAG_MANIFEST_ROOT = "manifest:manifest"; + + /** Element tag for <i>manifest:file-entry</i> entry in Manifest XML. */ + public final static String TAG_MANIFEST_FILE = "manifest:file-entry"; + + /** + * Attribute tag for <i>manifest:media-type</i> of element + * <i>manifest:file-entry</i>. + */ + public final static String ATTRIBUTE_MANIFEST_FILE_TYPE = "manifest:media-type"; + + /** + * Attribute tag for <i>manifest:full-path</i> of element + * <i>manifest:file-entry</i>. + */ + public final static String ATTRIBUTE_MANIFEST_FILE_PATH = "manifest:full-path"; + + // Tags and Elements for the settings.xml + + /** Element tag for <i>config:config-item</i>. */ + public final static String TAG_CONFIG_ITEM = "config:config-item"; + + /** Element tag for <i>config:config-item-set</i>. */ + public final static String TAG_CONFIG_ITEM_SET = "config:config-item-set"; + + /** Element tag for <i>config:config-item-map-indexed</i>. */ + public final static String TAG_CONFIG_ITEM_MAP_INDEXED = "config:config-item-map-indexed"; + + /** Element tag for <i>config:config-item-map-named</i>. */ + public final static String TAG_CONFIG_ITEM_MAP_NAMED = "config:config-item-map-named"; + + /** Element tag for <i>config:config-item-map-entry</i>. */ + public final static String TAG_CONFIG_ITEM_MAP_ENTRY= "config:config-item-map-entry"; + + /** + * Attribute tag for <i>config:name</i> of element + * <i>config:config-item</i>. + */ + public final static String ATTRIBUTE_CONFIG_NAME = "config:name"; + + /** + * Attribute tag for <i>config:type</i> of element + * <i>config:config-item</i>. + */ + public final static String ATTRIBUTE_CONFIG_TYPE = "config:type"; + + + /** StarWriter XML MIME type. */ + public final static String SXW_MIME_TYPE = "application/vnd.sun.xml.writer"; + + /** StarWriter XML Template MIME type. */ + public final static String STW_MIME_TYPE = "application/vnd.sun.xml.writer.template"; + + /** StarCalc XML MIME type. */ + public final static String SXC_MIME_TYPE = "application/vnd.sun.xml.calc"; + + /** StarCalc XML Template MIME type. */ + public final static String STC_MIME_TYPE = "application/vnd.sun.xml.calc.template"; + + /** StarImpress XML MIME type. */ + public final static String SXI_MIME_TYPE = "application/vnd.sun.xml.impress"; + + /** StarImpress XML Template MIME type. */ + public final static String STI_MIME_TYPE = "application/vnd.sun.xml.impress.template"; + + /** StarDraw XML MIME type. */ + public final static String SXD_MIME_TYPE = "application/vnd.sun.xml.draw"; + + /** StarMath XML MIME type. */ + public final static String SXM_MIME_TYPE = "application/vnd.sun.xml.math"; + + /** StarWriter Global XML MIME Type */ + public final static String SXG_MIME_TYPE = "application/vnd.sun.xml.writer.global"; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeDocument.java b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeDocument.java new file mode 100644 index 000000000000..7b36d3f49ac2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeDocument.java @@ -0,0 +1,1237 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OfficeDocument.java,v $ + * $Revision: 1.18 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package org.openoffice.xmerge.converter.xml; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.InputStreamReader; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.Document; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.DocumentType; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.w3c.dom.NamedNodeMap; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.openoffice.xmerge.util.Resources; +import org.openoffice.xmerge.util.Debug; + +/** + * An implementation of <code>Document</code> for + * StarOffice documents. + */ +public abstract class OfficeDocument + implements org.openoffice.xmerge.Document, + OfficeConstants { + + /** Factory for <code>DocumentBuilder</code> objects. */ + private static DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + + /** DOM <code>Document</code> of content.xml. */ + private Document contentDoc = null; + + /** DOM <code>Document</code> of meta.xml. */ + private Document metaDoc = null; + + /** DOM <code>Document</code> of settings.xml. */ + private Document settingsDoc = null; + + /** DOM <code>Document</code> of content.xml. */ + private Document styleDoc = null; + + /** DOM <code>Docuemtn</code> of META-INF/manifest.xml. */ + private Document manifestDoc = null; + + private String documentName = null; + private String fileName = null; + + /** Resources object. */ + private Resources res = null; + + /** + * <code>OfficeZip</code> object to store zip contents from + * read <code>InputStream</code>. Note that this member + * will still be null if it was initialized using a template + * file instead of reading from a StarOffice zipped + * XML file. + */ + private OfficeZip zip = null; + + /** Collection to keep track of the embedded objects in the document. */ + private Map embeddedObjects = null; + + /** + * Default constructor. + * + * @param name <code>Document</code> name. + */ + public OfficeDocument(String name) + { + this(name, true, false); + } + + + /** + * Constructor with arguments to set <code>namespaceAware</code> + * and <code>validating</code> flags. + * + * @param name <code>Document</code> name (may or may not + * contain extension). + * @param namespaceAware Value for <code>namespaceAware</code> flag. + * @param validating Value for <code>validating</code> flag. + */ + public OfficeDocument(String name, boolean namespaceAware, boolean validating) { + + res = Resources.getInstance(); + factory.setValidating(validating); + factory.setNamespaceAware(namespaceAware); + this.documentName = trimDocumentName(name); + this.fileName = documentName + getFileExtension(); + } + + + /** + * Removes the file extension from the <code>Document</code> + * name. + * + * @param name Full <code>Document</code> name with extension. + * + * @return Name of <code>Document</code> without the extension. + */ + private String trimDocumentName(String name) { + String temp = name.toLowerCase(); + String ext = getFileExtension(); + + if (temp.endsWith(ext)) { + // strip the extension + int nlen = name.length(); + int endIndex = nlen - ext.length(); + name = name.substring(0,endIndex); + } + + return name; + } + + + /** + * Return a DOM <code>Document</code> object of the content.xml + * file. Note that a content DOM is not created when the constructor + * is called. So, either the <code>read</code> method or the + * <code>initContentDOM</code> method will need to be called ahead + * on this object before calling this method. + * + * @return DOM <code>Document</code> object. + */ + public Document getContentDOM() { + + return contentDoc; + } + + /** + * Return a DOM <code>Document</code> object of the meta.xml + * file. Note that a content DOM is not created when the constructor + * is called. So, either the <code>read</code> method or the + * <code>initContentDOM</code> method will need to be called ahead + * on this object before calling this method. + * + * @return DOM <code>Document</code> object. + */ + public Document getMetaDOM() { + + return metaDoc; + } + + + /** + * Return a DOM <code>Document</code> object of the settings.xml + * file. Note that a content DOM is not created when the constructor + * is called. So, either the <code>read</code> method or the + * <code>initContentDOM</code> method will need to be called ahead + * on this object before calling this method. + * + * @return DOM <code>Document</code> object. + */ + public Document getSettingsDOM() { + + return settingsDoc; + } + + + /** + * Sets the content tree of the document. + * + * @param newDom <code>Node</code> containing the new content tree. + */ + public void setContentDOM( Node newDom) { + contentDoc = (Document)newDom; + } + + + /** + * Sets the meta tree of the document. + * + * @param newDom <code>Node</code> containing the new meta tree. + */ + public void setMetaDOM (Node newDom) { + metaDoc = (Document)newDom; + } + + + /** + * Sets the settings tree of the document. + * + * @param newDom <code>Node</code> containing the new settings tree. + */ + public void setSettingsDOM (Node newDom) { + settingsDoc = (Document)newDom; + } + + + /** + * Sets the style tree of the document. + * + * @param newDom <code>Node</code> containing the new style tree. + */ + public void setStyleDOM (Node newDom) { + styleDoc = (Document)newDom; + } + + + /** + * Return a DOM <code>Document</code> object of the style.xml file. + * Note that this may return null if there is no style DOM. + * Note that a style DOM is not created when the constructor + * is called. Depending on the <code>InputStream</code>, a + * <code>read</code> method may or may not build a style DOM. When + * creating a new style DOM, call the <code>initStyleDOM</code> method + * first. + * + * @return DOM <code>Document</code> object. + */ + public Document getStyleDOM() { + + return styleDoc; + } + + + /** + * Return the name of the <code>Document</code>. + * + * @return The name of <code>Document</code>. + */ + public String getName() { + + return documentName; + } + + + /** + * Return the file name of the <code>Document</code>, possibly + * with the standard extension. + * + * @return The file name of <code>Document</code>. + */ + public String getFileName() { + + return fileName; + } + + + /** + * Returns the file extension for this type of + * <code>Document</code>. + * + * @return The file extension of <code>Document</code>. + */ + protected abstract String getFileExtension(); + + + /** + * Returns all the embedded objects (graphics, formulae, etc.) present in + * this document. + * + * @return An <code>Iterator</code> of <code>EmbeddedObject</code> objects. + */ + public Iterator getEmbeddedObjects() { + + if (embeddedObjects == null && manifestDoc != null) { + embeddedObjects = new HashMap(); + + // Need to read the manifest file and construct a list of objects + NodeList nl = manifestDoc.getElementsByTagName(TAG_MANIFEST_FILE); + + // Dont create the HashMap if there are no embedded objects + int len = nl.getLength(); + for (int i = 0; i < len; i++) { + Node n = nl.item(i); + + NamedNodeMap attrs = n.getAttributes(); + + String type = attrs.getNamedItem(ATTRIBUTE_MANIFEST_FILE_TYPE).getNodeValue(); + String path = attrs.getNamedItem(ATTRIBUTE_MANIFEST_FILE_PATH).getNodeValue(); + + + /* + * According to OpenOffice.org XML File Format document (ver. 1) + * there are only two types of embedded object: + * + * Objects with an XML representation. + * Objects without an XML representation. + * + * The former are represented by one or more XML files. + * The latter are in binary form. + */ + if (type.startsWith("application/vnd.sun.xml")) + { + if (path.equals("/")) { + // Exclude the main document entries + continue; + } + // Take off the trailing '/' + String name = path.substring(0, path.length() - 1); + embeddedObjects.put(name, new EmbeddedXMLObject(name, type, zip)); + } + else if (type.equals("text/xml")) { + // XML entries are either embedded StarOffice doc entries or main + // document entries + continue; + } + else { // FIX (HJ): allows empty MIME type + embeddedObjects.put(path, new EmbeddedBinaryObject(path, type, zip)); + } + } + } + + return embeddedObjects.values().iterator(); + } + + /** + * Returns the embedded object corresponding to the name provided. + * The name should be stripped of any preceding path characters, such as + * '/', '.' or '#'. + * + * @param name The name of the embedded object to retrieve. + * + * @return An <code>EmbeddedObject</code> instance representing the named + * object. + */ + public EmbeddedObject getEmbeddedObject(String name) { + if (name == null) { + return null; + } + + if (embeddedObjects == null) { + getEmbeddedObjects(); + } + + if (embeddedObjects.containsKey(name)) { + return (EmbeddedObject)embeddedObjects.get(name); + } + else { + return null; + } + } + + + /** + * Adds a new embedded object to the document. + * + * @param embObj An instance of <code>EmbeddedObject</code>. + */ + public void addEmbeddedObject(EmbeddedObject embObj) { + if (embObj == null) { + return; + } + + if (embeddedObjects == null) { + embeddedObjects = new HashMap(); + } + + embeddedObjects.put(embObj.getName(), embObj); + } + + + /** + * Read the Office <code>Document</code> from the given + * <code>InputStream</code>. + * + * @param is Office document <code>InputStream</code>. + * + * @throws IOException If any I/O error occurs. + */ + public void read(InputStream is) throws IOException { + + Debug.log(Debug.INFO, "reading Office file"); + + DocumentBuilder builder = null; + + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new OfficeDocumentException(ex); + } + + // read in Office zip file format + + zip = new OfficeZip(); + zip.read(is); + + // grab the content.xml and + // parse it into contentDoc. + + byte contentBytes[] = zip.getContentXMLBytes(); + + if (contentBytes == null) { + + throw new OfficeDocumentException("Entry content.xml not found in file"); + } + + try { + + contentDoc = parse(builder, contentBytes); + + } catch (SAXException ex) { + + throw new OfficeDocumentException(ex); + } + + // if style.xml exists, grab the style.xml + // parse it into styleDoc. + + byte styleBytes[] = zip.getStyleXMLBytes(); + + if (styleBytes != null) { + + try { + + styleDoc = parse(builder, styleBytes); + + } catch (SAXException ex) { + + throw new OfficeDocumentException(ex); + } + } + + byte metaBytes[] = zip.getMetaXMLBytes(); + + if (metaBytes != null) { + + try { + + metaDoc = parse(builder, metaBytes); + + } catch (SAXException ex) { + + throw new OfficeDocumentException(ex); + } + } + + byte settingsBytes[] = zip.getSettingsXMLBytes(); + + if (settingsBytes != null) { + + try { + + settingsDoc = parse(builder, settingsBytes); + + } catch (SAXException ex) { + + throw new OfficeDocumentException(ex); + } + } + + + // Read in the META-INF/manifest.xml file + byte manifestBytes[] = zip.getManifestXMLBytes(); + + if (manifestBytes != null) { + + try { + manifestDoc = parse(builder, manifestBytes); + } catch (SAXException ex) { + throw new OfficeDocumentException(ex); + } + } + + } + + + /** + * Read the Office <code>Document</code> from the given + * <code>InputStream</code>. + * + * @param is Office document <code>InputStream</code>. + * @param isZip <code>boolean</code> Identifies whether + * a file is zipped or not + * + * @throws IOException If any I/O error occurs. + */ + public void read(InputStream is, boolean isZip) throws IOException { + + Debug.log(Debug.INFO, "reading Office file"); + + DocumentBuilder builder = null; + + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new OfficeDocumentException(ex); + } + + if (isZip) + { + read(is); + } + else{ + try{ + //System.out.println("\nParsing Input stream, validating?: "+builder.isValidating()); + //contentDoc= builder.parse((InputStream)is); + + Reader r = secondHack(is); + InputSource ins = new InputSource(r); + org.w3c.dom.Document newDoc = builder.parse(ins); + //org.w3c.dom.Document newDoc = builder.parse((InputStream)is); + Element rootElement=newDoc.getDocumentElement(); + + NodeList nodeList; + Node tmpNode; + Node rootNode = (Node)rootElement; + if (newDoc !=null){ + /*content*/ + contentDoc = createDOM(TAG_OFFICE_DOCUMENT_CONTENT); + rootElement=contentDoc.getDocumentElement(); + rootNode = (Node)rootElement; + + // FIX (HJ): Include office:font-decls in content DOM + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_FONT_DECLS); + if (nodeList.getLength()>0){ + tmpNode = contentDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + if (nodeList.getLength()>0){ + tmpNode = contentDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_BODY); + if (nodeList.getLength()>0){ + tmpNode = contentDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + /*Styles*/ + styleDoc = createDOM(TAG_OFFICE_DOCUMENT_STYLES); + rootElement=styleDoc.getDocumentElement(); + rootNode = (Node)rootElement; + + // FIX (HJ): Include office:font-decls in styles DOM + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_FONT_DECLS); + if (nodeList.getLength()>0){ + tmpNode = styleDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_STYLES); + if (nodeList.getLength()>0){ + tmpNode = styleDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + // FIX (HJ): Include office:automatic-styles in styles DOM + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + if (nodeList.getLength()>0){ + tmpNode = styleDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + // FIX (HJ): Include office:master-styles in styles DOM + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_MASTER_STYLES); + if (nodeList.getLength()>0){ + tmpNode = styleDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + /*Settings*/ + settingsDoc = createDOM(TAG_OFFICE_DOCUMENT_SETTINGS); + rootElement=settingsDoc.getDocumentElement(); + rootNode = (Node)rootElement; + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_SETTINGS); + if (nodeList.getLength()>0){ + tmpNode = settingsDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + /*Meta*/ + metaDoc = createDOM(TAG_OFFICE_DOCUMENT_META); + rootElement=metaDoc.getDocumentElement(); + rootNode = (Node)rootElement; + nodeList= newDoc.getElementsByTagName(TAG_OFFICE_META); + if (nodeList.getLength()>0){ + tmpNode = metaDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + } + } + catch (SAXException ex) { + throw new OfficeDocumentException(ex); + } + } + + } + + + + /** + * Parse given <code>byte</code> array into a DOM + * <code>Document</code> object using the + * <code>DocumentBuilder</code> object. + * + * @param builder <code>DocumentBuilder</code> object for parsing. + * @param bytes <code>byte</code> array for parsing. + * + * @return Resulting DOM <code>Document</code> object. + * + * @throws SAXException If any parsing error occurs. + */ + static Document parse(DocumentBuilder builder, byte bytes[]) + throws SAXException, IOException { + + Document doc = null; + + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + + // TODO: replace hack with a more appropriate fix. + + Reader r = hack(is); + InputSource ins = new InputSource(r); + doc = builder.parse(ins); + + return doc; + } + + + /** + * Method to return the MIME type of the document. + * + * @return String The document's MIME type. + */ + protected abstract String getDocumentMimeType(); + + + /** + * Write out Office ZIP file format. + * + * @param os XML <code>OutputStream</code>. + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream os) throws IOException { + if (zip == null) { + zip = new OfficeZip(); + } + + initManifestDOM(); + + Element domEntry; + Element manifestRoot = manifestDoc.getDocumentElement(); + + // The EmbeddedObjects come first. + Iterator embObjs = getEmbeddedObjects(); + while (embObjs.hasNext()) { + EmbeddedObject obj = (EmbeddedObject)embObjs.next(); + obj.writeManifestData(manifestDoc); + + obj.write(zip); + } + + // Add in the entry for the Pictures directory. Always present. + domEntry = manifestDoc.createElement(TAG_MANIFEST_FILE); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_PATH, "Pictures/"); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_TYPE, ""); + manifestRoot.appendChild(domEntry); + + // Write content to the Zip file and then write any of the optional + // data, if it exists. + zip.setContentXMLBytes(docToBytes(contentDoc)); + + domEntry = manifestDoc.createElement(TAG_MANIFEST_FILE); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_PATH, "content.xml"); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + + manifestRoot.appendChild(domEntry); + + if (styleDoc != null) { + zip.setStyleXMLBytes(docToBytes(styleDoc)); + + domEntry = manifestDoc.createElement(TAG_MANIFEST_FILE); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_PATH, "styles.xml"); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + manifestRoot.appendChild(domEntry); + } + + if (metaDoc != null) { + zip.setMetaXMLBytes(docToBytes(metaDoc)); + + domEntry = manifestDoc.createElement(TAG_MANIFEST_FILE); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_PATH, "meta.xml"); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + manifestRoot.appendChild(domEntry); + } + + if (settingsDoc != null) { + zip.setSettingsXMLBytes(docToBytes(settingsDoc)); + + domEntry = manifestDoc.createElement(TAG_MANIFEST_FILE); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_PATH, "settings.xml"); + domEntry.setAttribute(ATTRIBUTE_MANIFEST_FILE_TYPE, "text/xml"); + manifestRoot.appendChild(domEntry); + } + + zip.setManifestXMLBytes(docToBytes(manifestDoc)); + + zip.write(os); + } + + + /** + * Write out Office ZIP file format. + * + * @param os XML <code>OutputStream</code>. + * @param isZip <code>boolean</code> + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream os, boolean isZip) throws IOException { + + // Create an OfficeZip object if one does not exist. + if (isZip){ + write(os); + } + else{ + try{ + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder= builderFactory.newDocumentBuilder(); + DOMImplementation domImpl = builder.getDOMImplementation(); + DocumentType docType =domImpl.createDocumentType("office:document","-//OpenOffice.org//DTD OfficeDocument 1.0//EN",null); + org.w3c.dom.Document newDoc = domImpl.createDocument("http://openoffice.org/2000/office","office:document",null); + + + Element rootElement=newDoc.getDocumentElement(); + rootElement.setAttribute("xmlns:office","http://openoffice.org/2000/office"); + rootElement.setAttribute("xmlns:style","http://openoffice.org/2000/style" ); + rootElement.setAttribute("xmlns:text","http://openoffice.org/2000/text"); + rootElement.setAttribute("xmlns:table","http://openoffice.org/2000/table"); + + rootElement.setAttribute("xmlns:draw","http://openoffice.org/2000/drawing"); + rootElement.setAttribute("xmlns:fo","http://www.w3.org/1999/XSL/Format" ); + rootElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink" ); + rootElement.setAttribute("xmlns:dc","http://purl.org/dc/elements/1.1/" ); + rootElement.setAttribute("xmlns:meta","http://openoffice.org/2000/meta" ); + rootElement.setAttribute("xmlns:number","http://openoffice.org/2000/datastyle" ); + rootElement.setAttribute("xmlns:svg","http://www.w3.org/2000/svg" ); + rootElement.setAttribute("xmlns:chart","http://openoffice.org/2000/chart" ); + rootElement.setAttribute("xmlns:dr3d","http://openoffice.org/2000/dr3d" ); + rootElement.setAttribute("xmlns:math","http://www.w3.org/1998/Math/MathML" ); + rootElement.setAttribute("xmlns:form","http://openoffice.org/2000/form" ); + rootElement.setAttribute("xmlns:script","http://openoffice.org/2000/script" ); + rootElement.setAttribute("xmlns:config","http://openoffice.org/2001/config" ); + // #i41033# OASIS format needs the "office:class" set. + if(getDocumentMimeType() == SXC_MIME_TYPE) + rootElement.setAttribute("office:class","spreadsheet" ); + else if(getDocumentMimeType() == SXW_MIME_TYPE) + rootElement.setAttribute("office:class","text" ); + rootElement.setAttribute("office:version","1.0"); + + + NodeList nodeList; + Node tmpNode; + Node rootNode = (Node)rootElement; + if (metaDoc !=null){ + nodeList= metaDoc.getElementsByTagName(TAG_OFFICE_META); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + }if (styleDoc !=null){ + nodeList= styleDoc.getElementsByTagName(TAG_OFFICE_STYLES); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + }if (settingsDoc !=null){ + nodeList= settingsDoc.getElementsByTagName(TAG_OFFICE_SETTINGS); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + } + if (contentDoc !=null){ + nodeList= contentDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + + nodeList= contentDoc.getElementsByTagName(TAG_OFFICE_BODY); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + } + + byte contentBytes[] = docToBytes(newDoc); + //System.out.println(new String(contentBytes)); + os.write(contentBytes); + } + catch(Exception exc){ + System.out.println("\nException in OfficeDocument.write():" +exc); + } + //byte contentBytes[] = docToBytes(contentDoc); + } + } + + + /** + * <p>Write out a <code>org.w3c.dom.Document</code> object into a + * <code>byte</code> array.</p> + * + * <p>TODO: remove dependency on com.sun.xml.tree.XmlDocument + * package!</p> + * + * @param Document DOM <code>Document</code> object. + * + * @return <code>byte</code> array of DOM <code>Document</code> + * object. + * + * @throws IOException If any I/O error occurs. + */ + static byte[] docToBytes(Document doc) + throws IOException { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + java.lang.reflect.Constructor con; + java.lang.reflect.Method meth; + + String domImpl = doc.getClass().getName(); + + /* + * We may have multiple XML parsers in the Classpath. + * Depending on which one is first, the actual type of + * doc may vary. Need a way to find out which API is being + * used and use an appropriate serialization method. + */ + try { + // First of all try for JAXP 1.0 + if (domImpl.equals("com.sun.xml.tree.XmlDocument")) { + + Debug.log(Debug.INFO, "Using JAXP"); + + Class jaxpDoc = Class.forName("com.sun.xml.tree.XmlDocument"); + + // The method is in the XMLDocument class itself, not a helper + meth = jaxpDoc.getMethod("write", + new Class[] { Class.forName("java.io.OutputStream") } ); + + meth.invoke(doc, new Object [] { baos } ); + } + else if (domImpl.equals("org.apache.crimson.tree.XmlDocument")) + { + Debug.log(Debug.INFO, "Using Crimson"); + + Class crimsonDoc = Class.forName("org.apache.crimson.tree.XmlDocument"); + // The method is in the XMLDocument class itself, not a helper + meth = crimsonDoc.getMethod("write", + new Class[] { Class.forName("java.io.OutputStream") } ); + + meth.invoke(doc, new Object [] { baos } ); + } + else if (domImpl.equals("org.apache.xerces.dom.DocumentImpl") + || domImpl.equals("org.apache.xerces.dom.DeferredDocumentImpl")) { + + Debug.log(Debug.INFO, "Using Xerces"); + + // Try for Xerces + Class xercesSer = + Class.forName("org.apache.xml.serialize.XMLSerializer"); + + // Get the OutputStream constructor + // May want to use the OutputFormat parameter at some stage too + con = xercesSer.getConstructor(new Class [] + { Class.forName("java.io.OutputStream"), + Class.forName("org.apache.xml.serialize.OutputFormat") } ); + + + // Get the serialize method + meth = xercesSer.getMethod("serialize", + new Class [] { Class.forName("org.w3c.dom.Document") } ); + + + // Get an instance + Object serializer = con.newInstance(new Object [] { baos, null } ); + + + // Now call serialize to write the document + meth.invoke(serializer, new Object [] { doc } ); + } + else { + // We don't have another parser + throw new IOException("No appropriate API (JAXP/Xerces) to serialize XML document: " + domImpl); + } + } + catch (ClassNotFoundException cnfe) { + throw new IOException(cnfe.toString()); + } + catch (Exception e) { + // We may get some other errors, but the bottom line is that + // the steps being executed no longer work + throw new IOException(e.toString()); + } + + byte bytes[] = baos.toByteArray(); + + return bytes; + } + + + /** + * Initializes a new DOM <code>Document</code> with the content + * containing minimum OpenOffice XML tags. + * + * @throws IOException If any I/O error occurs. + */ + public final void initContentDOM() throws IOException { + + contentDoc = createDOM(TAG_OFFICE_DOCUMENT_CONTENT); + + // this is a work-around for a bug in Office6.0 - not really + // needed but StarCalc 6.0 will crash without this tag. + Element root = contentDoc.getDocumentElement(); + + Element child = contentDoc.createElement(TAG_OFFICE_FONT_DECLS); + root.appendChild(child); + + child = contentDoc.createElement(TAG_OFFICE_AUTOMATIC_STYLES); + root.appendChild(child); + + child = contentDoc.createElement(TAG_OFFICE_BODY); + root.appendChild(child); + } + + /** + * Initializes a new DOM <code>Document</code> with the content + * containing minimum OpenOffice XML tags. + * + * @throws IOException If any I/O error occurs. + */ + public final void initSettingsDOM() throws IOException { + + settingsDoc = createSettingsDOM(TAG_OFFICE_DOCUMENT_SETTINGS); + + // this is a work-around for a bug in Office6.0 - not really + // needed but StarCalc 6.0 will crash without this tag. + Element root = settingsDoc.getDocumentElement(); + + Element child = settingsDoc.createElement(TAG_OFFICE_SETTINGS); + root.appendChild(child); + } + + /** + * Initializes a new DOM Document with styles + * containing minimum OpenOffice XML tags. + * + * @throws IOException If any I/O error occurs. + */ + public final void initStyleDOM() throws IOException { + + styleDoc = createDOM(TAG_OFFICE_DOCUMENT_STYLES); + } + + /** + * <p>Creates a new DOM <code>Document</code> containing minimum + * OpenOffice XML tags.</p> + * + * <p>This method uses the subclass + * <code>getOfficeClassAttribute</code> method to get the + * attribute for <i>office:class</i>.</p> + * + * @param rootName root name of <code>Document</code>. + * + * @throws IOException If any I/O error occurs. + */ + private final Document createSettingsDOM(String rootName) throws IOException { + + Document doc = null; + + try { + + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.newDocument(); + + } catch (ParserConfigurationException ex) { + + throw new OfficeDocumentException(ex); + + } + + Element root = (Element) doc.createElement(rootName); + doc.appendChild(root); + + root.setAttribute("xmlns:office", "http://openoffice.org/2000/office"); + root.setAttribute("xmlns:xlink", "http://openoffice.org/1999/xlink"); + root.setAttribute("xmlns:config", "http://openoffice.org/2001/config"); + root.setAttribute("office:version", "1.0"); + + return doc; + } + + + /** + * <p>Creates a new DOM <code>Document</code> containing minimum + * OpenOffice XML tags.</p> + * + * <p>This method uses the subclass + * <code>getOfficeClassAttribute</code> method to get the + * attribute for <i>office:class</i>.</p> + * + * @param rootName root name of <code>Document</code>. + * + * @throws IOException If any I/O error occurs. + */ + private final Document createDOM(String rootName) throws IOException { + + Document doc = null; + + try { + + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.newDocument(); + + } catch (ParserConfigurationException ex) { + + throw new OfficeDocumentException(ex); + + } + + Element root = (Element) doc.createElement(rootName); + doc.appendChild(root); + + root.setAttribute("xmlns:office", "http://openoffice.org/2000/office"); + root.setAttribute("xmlns:style", "http://openoffice.org/2000/style"); + root.setAttribute("xmlns:text", "http://openoffice.org/2000/text"); + root.setAttribute("xmlns:table", "http://openoffice.org/2000/table"); + root.setAttribute("xmlns:draw", "http://openoffice.org/2000/drawing"); + root.setAttribute("xmlns:fo", "http://www.w3.org/1999/XSL/Format"); + root.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); + root.setAttribute("xmlns:number", "http://openoffice.org/2000/datastyle"); + root.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg"); + root.setAttribute("xmlns:chart", "http://openoffice.org/2000/chart"); + root.setAttribute("xmlns:dr3d", "http://openoffice.org/2000/dr3d"); + root.setAttribute("xmlns:math", "http://www.w3.org/1998/Math/MathML"); + root.setAttribute("xmlns:form", "http://openoffice.org/2000/form"); + root.setAttribute("xmlns:script", "http://openoffice.org/2000/script"); + root.setAttribute("office:class", getOfficeClassAttribute()); + root.setAttribute("office:version", "1.0"); + + return doc; + } + + + /** + * Return the <i>office:class</i> attribute value. + * + * @return The attribute value. + */ + protected abstract String getOfficeClassAttribute(); + + + /** + * <p>Hacked code to filter <!DOCTYPE> tag before + * sending stream to parser.</p> + * + * <p>This hacked code needs to be changed later on.</p> + * + * <p>Issue: using current jaxp1.0 parser, there is no way + * to turn off processing of dtds. Current set of dtds + * have bugs, processing them will throw exceptions.</p> + * + * <p>This is a simple hack that assumes the whole <!DOCTYPE> + * tag are all in the same line. This is sufficient for + * current StarOffice 6.0 generated XML files. Since this + * hack really needs to go away, I don't want to spend + * too much time in making it a perfect hack.</p> + * FIX (HJ): Removed requirement for DOCTYPE to be in one line + * FIX (HJ): No longer removes newlines + * + * @param is <code>InputStream</code> to be filtered. + * + * @return Reader value without the <!DOCTYPE> tag. + * + * @throws IOException If any I/O error occurs. + */ + private static Reader hack(InputStream is) throws IOException { + + BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + StringBuffer buffer = new StringBuffer(is.available()); + + String str = null; + + while ((str = br.readLine()) != null) { + + int sIndex = str.indexOf("<!DOCTYPE"); + + if (sIndex > -1) { + + buffer.append(str.substring(0, sIndex)); + + int eIndex = str.indexOf('>', sIndex + 8 ); + + if (eIndex > -1) { + + buffer.append(str.substring(eIndex + 1, str.length())); + // FIX (HJ): Preserve the newline + buffer.append("\n"); + + } else { + + // FIX (HJ): More than one line. Search for '>' in following lines + boolean bOK = false; + while ((str = br.readLine())!=null) { + eIndex = str.indexOf('>'); + if (eIndex>-1) { + buffer.append(str.substring(eIndex+1)); + // FIX (HJ): Preserve the newline + buffer.append("\n"); + bOK = true; + break; + } + } + + if (!bOK) { throw new IOException("Invalid XML"); } + } + + } else { + + buffer.append(str); + // FIX (HJ): Preserve the newline + buffer.append("\n"); + } + } + + StringReader r = new StringReader(buffer.toString()); + return r; + } + + /** + * <p>Transform the InputStream to a Reader Stream.</p> + * + * <p>This hacked code needs to be changed later on.</p> + * + * <p>Issue: the new oasis input file stream means + * that the old input stream fails. see #i33702# </p> + * + * @param is <code>InputStream</code> to be filtered. + * + * @return Reader value of the InputStream(). + * + * @throws IOException If any I/O error occurs. + */ + private static Reader secondHack(InputStream is) throws IOException { + + BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + char[] charArray = new char[is.available()]; + + br.read(charArray,0,is.available()); + String sStr = new String(charArray); + StringBuffer sBuf = new StringBuffer(is.available()); + // ensure there is no trailing garbage after the end of the stream. + int sIndex = sStr.lastIndexOf("</office:document>"); + sBuf.append(sStr.substring(0, sIndex)); + sBuf.append("</office:document>"); + StringReader r = new StringReader(sBuf.toString()); + return r; + } + + + /** + * Method to create the initial entries in the manifest.xml file stored + * in an SX? file. + */ + private void initManifestDOM() throws IOException { + + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + DOMImplementation domImpl = builder.getDOMImplementation(); + + DocumentType docType = domImpl.createDocumentType(TAG_MANIFEST_ROOT, + "-//OpenOffice.org//DTD Manifest 1.0//EN", + "Manifest.dtd"); + manifestDoc = domImpl.createDocument("manifest", TAG_MANIFEST_ROOT, docType); + } catch (ParserConfigurationException ex) { + throw new OfficeDocumentException(ex); + } + + // Add the <manifest:manifest> entry + Element manifestRoot = manifestDoc.getDocumentElement(); + + manifestRoot.setAttribute("xmlns:manifest", "http://openoffice.org/2001/manifest"); + + Element docRoot = manifestDoc.createElement(TAG_MANIFEST_FILE); + + docRoot.setAttribute(ATTRIBUTE_MANIFEST_FILE_PATH, "/"); + docRoot.setAttribute(ATTRIBUTE_MANIFEST_FILE_TYPE, getDocumentMimeType()); + + manifestRoot.appendChild(docRoot); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeDocumentException.java b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeDocumentException.java new file mode 100644 index 000000000000..49f4a84598ee --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeDocumentException.java @@ -0,0 +1,134 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OfficeDocumentException.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.openoffice.xmerge.util.Resources; + +/** + * Used by OfficeDocument to encapsulate exceptions. It will add + * more details to the message string if it is of type + * <code>SAXParseException</code>. + * + * @author Herbie Ong + */ + +public final class OfficeDocumentException extends IOException { + + StringBuffer message = null; + + + /** + * Constructor, capturing additional information from the + * <code>SAXException</code>. + * + * @param e The <code>SAXException</code>. + */ + public OfficeDocumentException(SAXException e) { + super(e.toString()); + message = new StringBuffer(); + if (e instanceof SAXParseException) { + String msgParseError = + Resources.getInstance().getString("PARSE_ERROR"); + String msgLine = + Resources.getInstance().getString("LINE"); + String msgColumn = + Resources.getInstance().getString("COLUMN"); + String msgPublicId = + Resources.getInstance().getString("PUBLIC_ID"); + String msgSystemId = + Resources.getInstance().getString("SYSTEM_ID"); + SAXParseException spe = (SAXParseException) e; + message.append(msgParseError); + message.append(": "); + message.append(msgLine); + message.append(": "); + message.append(spe.getLineNumber()); + message.append(", "); + message.append(msgColumn); + message.append(": "); + message.append(spe.getColumnNumber()); + message.append(", "); + message.append(msgSystemId); + message.append(": "); + message.append(spe.getSystemId()); + message.append(", "); + message.append(msgPublicId); + message.append(": "); + message.append(spe.getPublicId()); + message.append("\n"); + } + + // if there exists an embedded exception + Exception ex = e.getException(); + if (ex != null) { + message.append(ex.getMessage()); + } + } + + + /** + * Constructor, creates exception with provided message. + * + * @param s Message value for the exception. + */ + public OfficeDocumentException(String s) { + super(s); + } + + + /** + * Constructor, creates exception with the message + * corresponding to the message value of the provided + * exception. + * + * @param e The Exception. + */ + public OfficeDocumentException(Exception e) { + super(e.getMessage()); + } + + + /** + * Returns the message value for the <code>Exception</code>. + * + * @return The message value for the <code>Exception</code>. + */ + public String getMessage() { + return message.toString() + super.getMessage(); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeZip.java b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeZip.java new file mode 100644 index 000000000000..48ae950d9b32 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/OfficeZip.java @@ -0,0 +1,461 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OfficeZip.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import java.util.List; +import java.util.ListIterator; +import java.util.LinkedList; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.CRC32; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.io.ByteArrayOutputStream; + +import org.openoffice.xmerge.util.Debug; + +/** + * Class used by {@link + * org.openoffice.xmerge.converter.OfficeDocument + * OfficeDocument} to handle reading and writing + * from a ZIP file, as well as storing ZIP entries. + * + * @author Herbie Ong + */ +class OfficeZip { + + /** File name of the XML file in a zipped document. */ + private final static String CONTENTXML = "content.xml"; + + private final static String STYLEXML = "styles.xml"; + private final static String METAXML = "meta.xml"; + private final static String SETTINGSXML = "settings.xml"; + private final static String MANIFESTXML = "META-INF/manifest.xml"; + + private final static int BUFFERSIZE = 1024; + + private List entryList = null; + + private int contentIndex = -1; + private int styleIndex = -1; + private int metaIndex = -1; + private int settingsIndex = -1; + private int manifestIndex = -1; + + /** Default constructor. */ + OfficeZip() { + + entryList = new LinkedList(); + } + + + /** + * <p>Read each zip entry in the <code>InputStream</code> object + * and store in entryList both the <code>ZipEntry</code> object + * as well as the bits of each entry. Call this method before + * calling the <code>getContentXMLBytes</code> method or the + * <code>getStyleXMLBytes</code> method.</p> + * + * <p>Keep track of the CONTENTXML and STYLEXML using + * contentIndex and styleIndex, respectively.</p> + * + * @param is <code>InputStream</code> object to read. + * + * @throws IOException If any I/O error occurs. + */ + void read(InputStream is) throws IOException { + + ZipInputStream zis = new ZipInputStream(is); + ZipEntry ze = null; + int i = -1; + + while ((ze = zis.getNextEntry()) != null) { + + String name = ze.getName(); + + Debug.log(Debug.TRACE, "reading entry: " + name); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int len = 0; + byte buffer[] = new byte[BUFFERSIZE]; + + while ((len = zis.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + + byte bytes[] = baos.toByteArray(); + Entry entry = new Entry(ze,bytes); + + entryList.add(entry); + + i++; + + if (name.equalsIgnoreCase(CONTENTXML)) { + contentIndex = i; + } + else if (name.equalsIgnoreCase(STYLEXML)) { + styleIndex = i; + } + else if (name.equalsIgnoreCase(METAXML)) { + metaIndex = i; + } + else if (name.equalsIgnoreCase(SETTINGSXML)) { + settingsIndex = i; + } + else if (name.equalsIgnoreCase(MANIFESTXML)) { + manifestIndex = i; + } + + } + + zis.close(); + } + + + /** + * This method returns the CONTENTXML file in a + * <code>byte</code> array. It returns null if there is no + * CONTENTXML in this zip file. + * + * @return CONTENTXML in a <code>byte</code> array. + */ + byte[] getContentXMLBytes() { + + return getEntryBytes(contentIndex); + } + + + /** + * This method returns the STYLEXML file in a + * <code>byte</code> array. It returns null if there is + * no STYLEXML in this zip file. + * + * @return STYLEXML in a <code>byte</code> array. + */ + byte[] getStyleXMLBytes() { + + return getEntryBytes(styleIndex); + } + + /** + * This method returns the METAXML file in a + * <code>byte</code> array. It returns null if there is + * no METAXML in this zip file. + * + * @return METAXML in a <code>byte</code> array. + */ + byte[] getMetaXMLBytes() { + return getEntryBytes(metaIndex); + } + + /** + * This method returns the SETTINGSXML file in a + * <code>byte</code> array. It returns null if there is + * no SETTINGSXML in this zip file. + * + * @return SETTINGSXML in a <code>byte</code> array. + */ + byte[] getSettingsXMLBytes() { + return getEntryBytes(settingsIndex); + } + + /** + * This method returns the MANIFESTXML file in a <code>byte</code> array. + * It returns null if there is no MANIFESTXML in this zip file. + * + * @return MANIFESTXML in a <code>byte</code> array. + */ + byte[] getManifestXMLBytes() { + return getEntryBytes(manifestIndex); + } + + /** + * This method returns the bytes corresponding to the entry named in the + * parameter. + * + * @param name The name of the entry in the Zip file to retrieve. + * + * @return The data for the named entry in a <code>byte</code> array or + * <code>null</code> if no entry is found. + */ + byte[] getNamedBytes(String name) { + + // The list is not sorted, and sorting it for a binary search would + // invalidate the indices stored for the main files. + + // Could improve performance by caching the name and index when + // iterating through the ZipFile in read(). + for (int i = 0; i < entryList.size(); i++) { + Entry e = (Entry)entryList.get(i); + + if (e.zipEntry.getName().equals(name)) { + return getEntryBytes(i); + } + } + + return null; + } + + + /** + * This method sets the bytes for the named entry. It searches for a + * matching entry in the LinkedList. If no entry is found, a new one is + * created. + * + * Writing of data is defferred to setEntryBytes(). + * + * @param name The name of the entry to search for. + * @param bytes The new data to write. + */ + void setNamedBytes(String name, byte[] bytes) { + for (int i = 0; i < entryList.size(); i++) { + Entry e = (Entry)entryList.get(i); + + if (e.zipEntry.getName().equals(name)) { + setEntryBytes(i, bytes, name); + return; + } + } + + // If we're here, no entry was found. Call setEntryBytes with an index + // of -1 to insert a new entry. + setEntryBytes(-1, bytes, name); + } + + /** + * Used by the <code>getContentXMLBytes</code> method and the + * <code>getStyleXMLBytes</code> method to return the + * <code>byte</code> array from the corresponding + * <code>entry</code> in the <code>entryList</code>. + * + * @param index Index of <code>Entry</code> object in + * <code>entryList</code>. + * + * @return <code>byte</code> array associated in that + * <code>Entry</code> object or null, if there is + * not such <code>Entry</code>. + */ + private byte[] getEntryBytes(int index) { + + byte[] bytes = null; + + if (index > -1) { + Entry entry = (Entry) entryList.get(index); + bytes = entry.bytes; + } + return bytes; + } + + + /** + * Set or replace the <code>byte</code> array for the + * CONTENTXML file. + * + * @param bytes <code>byte</code> array for the + * CONTENTXML file. + */ + void setContentXMLBytes(byte bytes[]) { + + contentIndex = setEntryBytes(contentIndex, bytes, CONTENTXML); + } + + + /** + * Set or replace the <code>byte</code> array for the + * STYLEXML file. + * + * @param bytes <code>byte</code> array for the + * STYLEXML file. + */ + void setStyleXMLBytes(byte bytes[]) { + + styleIndex = setEntryBytes(styleIndex, bytes, STYLEXML); + } + + + /** + * Set or replace the <code>byte</code> array for the + * METAXML file. + * + * @param bytes <code>byte</code> array for the + * METAXML file. + */ + void setMetaXMLBytes(byte bytes[]) { + + metaIndex = setEntryBytes(metaIndex, bytes, METAXML); + } + + + /** + * Set or replace the <code>byte</code> array for the + * SETTINGSXML file. + * + * @param bytes <code>byte</code> array for the + * SETTINGSXML file. + */ + void setSettingsXMLBytes(byte bytes[]) { + + settingsIndex = setEntryBytes(settingsIndex, bytes, SETTINGSXML); + } + + + /** + * Set or replace the <code>byte</code> array for the MANIFESTXML file. + * + * @param bytes <code>byte</code> array for the MANIFESTXML file. + */ + void setManifestXMLBytes(byte bytes[]) { + manifestIndex = setEntryBytes(manifestIndex, bytes, MANIFESTXML); + } + + /** + * <p>Used by the <code>setContentXMLBytes</code> method and + * the <code>setStyleXMLBytes</code> to either replace an + * existing <code>Entry</code>, or create a new entry in + * <code>entryList</code>.</p> + * + * <p>If there is an <code>Entry</code> object within + * entryList that corresponds to the index, replace the + * <code>ZipEntry</code> info.</p> + * + * @param index Index of <code>Entry</code> to modify. + * @param bytes <code>Entry</code> value. + * @param name Name of <code>Entry</code>. + * + * @return Index of value added or modified in entryList + */ + private int setEntryBytes(int index, byte bytes[], String name) { + + if (index > -1) { + + // replace existing entry in entryList + + Entry entry = (Entry) entryList.get(index); + name = entry.zipEntry.getName(); + int method = entry.zipEntry.getMethod(); + + ZipEntry ze = createZipEntry(name, bytes, method); + + entry.zipEntry = ze; + entry.bytes= bytes; + + } else { + + // add a new entry into entryList + ZipEntry ze = createZipEntry(name, bytes, ZipEntry.DEFLATED); + Entry entry = new Entry(ze, bytes); + entryList.add(entry); + index = entryList.size() - 1; + } + + return index; + } + + + /** + * Write out the ZIP entries into the <code>OutputStream</code> + * object. + * + * @param os <code>OutputStream</code> object to write ZIP. + * + * @throws IOException If any ZIP I/O error occurs. + */ + void write(OutputStream os) throws IOException { + + Debug.log(Debug.TRACE, "Writing out the following entries into zip."); + + ZipOutputStream zos = new ZipOutputStream(os); + + ListIterator iterator = entryList.listIterator(); + + while (iterator.hasNext()) { + + Entry entry = (Entry) iterator.next(); + ZipEntry ze = entry.zipEntry; + + String name = ze.getName(); + + Debug.log(Debug.TRACE, "... " + name); + + zos.putNextEntry(ze); + zos.write(entry.bytes); + } + + zos.close(); + } + + + /** + * Creates a <code>ZipEntry</code> object based on the given params. + * + * @param name Name for the <code>ZipEntry</code>. + * @param bytes <code>byte</code> array for <code>ZipEntry</code>. + * @param method ZIP method to be used for <code>ZipEntry</code>. + * + * @return A <code>ZipEntry</code> object. + */ + private ZipEntry createZipEntry(String name, byte bytes[], int method) { + + ZipEntry ze = new ZipEntry(name); + + ze.setMethod(method); + ze.setSize(bytes.length); + + CRC32 crc = new CRC32(); + crc.reset(); + crc.update(bytes); + ze.setCrc(crc.getValue()); + + ze.setTime(System.currentTimeMillis()); + + return ze; + } + + /** + * This inner class is used as a data structure for holding + * a <code>ZipEntry</code> info and its corresponding bytes. + * These are stored in entryList. + */ + private class Entry { + + ZipEntry zipEntry = null; + byte bytes[] = null; + + Entry(ZipEntry zipEntry, byte bytes[]) { + this.zipEntry = zipEntry; + this.bytes = bytes; + } + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/ParaStyle.java b/xmerge/java/org/openoffice/xmerge/converter/xml/ParaStyle.java new file mode 100644 index 000000000000..5300da6a3a44 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/ParaStyle.java @@ -0,0 +1,610 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ParaStyle.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import java.io.IOException; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import java.lang.reflect.Constructor; +import org.openoffice.xmerge.util.Debug; + + +abstract class conversionAlgorithm { + int I(String val) { + return 0; + } +} + + /* + * This algorithm expects only values in millimeters, e.g. "20.3mm". + */ +class horizSize extends conversionAlgorithm { + int I(String value) { + if (value.endsWith("mm")) { + float size = (float)0.0; + String num = value.substring(0, value.length() - 2); + try { + size = Float.parseFloat(num); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Error parsing " + value, e); + } + size *= 100; + return (int)size; + } else { + Debug.log(Debug.ERROR, "Unexpected value (" + value + + ") in horizSize.I()"); + return 0; + } + } +} + + +/* + * This algorithm does line height - can be either millimeters or + * a percentage. + */ +class lineHeight extends conversionAlgorithm { + int I(String value) { + if (value.endsWith("mm")) { + float size = (float)0.0; + String num = value.substring(0, value.length() - 2); + try { + size = Float.parseFloat(num); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Error parsing " + value, e); + } + size *= 100; + return (int)size; + } else if (value.endsWith("%")) { + float size = (float)0.0; + String num = value.substring(0, value.length() - 1); + try { + size = Float.parseFloat(num); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Error parsing " + value, e); + } + int retval = (int) size; + retval |= ParaStyle.LH_PCT; + return retval; + } + return 0; + } +} + + +/** + * This class converts alignment values. + */ +class alignment extends conversionAlgorithm { + int I(String value) { + if (value.equals("end")) + return ParaStyle.ALIGN_RIGHT; + if (value.equals("right")) + return ParaStyle.ALIGN_RIGHT; + if (value.equals("center")) + return ParaStyle.ALIGN_CENTER; + if (value.equals("justify")) + return ParaStyle.ALIGN_JUST; + if (value.equals("justified")) + return ParaStyle.ALIGN_JUST; + if (value.equals("start")) + return ParaStyle.ALIGN_LEFT; + if (value.equals("left")) + return ParaStyle.ALIGN_LEFT; + Debug.log(Debug.ERROR, "Unknown string (" + + value + ") in alignment.I()"); + return ParaStyle.ALIGN_LEFT; + } +} + + +/** + * <p>This class represents a paragraph <code>Style</code>.</p> + * + * <p><table border="1" cellpadding="1"><tr><td> + * Attribute </td><td>Value + * </td></tr><tr><td> + * MARGIN_LEFT </td><td>mm * 100 + * </td></tr><tr><td> + * MARGIN_RIGHT </td><td>mm * 100 + * </td></tr><tr><td> + * MARGIN_TOP </td><td>mm * 100 (space on top of paragraph) + * </td></tr><tr><td> + * MARGIN_BOTTOM </td><td>mm * 100 + * </td></tr><tr><td> + * TEXT_INDENT </td><td>mm * 100 (first line indent) + * </td></tr><tr><td> + * LINE_HEIGHT </td><td>mm * 100, unless or'ed with LH_PCT, in which + * case it is a percentage (e.g. 200% for double spacing) + * Can also be or'ed with LH_ATLEAST. Value is stored + * in bits indicated by LH_VALUEMASK. + * </td></tr><tr><td> + * TEXT_ALIGN </td><td>ALIGN_RIGHT, ALIGN_CENTER, ALIGN_JUST, ALIGN_LEFT + * </td></tr></table></p> + * + * @author David Proulx + */ +public class ParaStyle extends Style implements Cloneable { + + /** The left margin property. */ + public static final int MARGIN_LEFT = 0; + /** The right margin property. */ + public static final int MARGIN_RIGHT = 1; + /** The top margin property. */ + public static final int MARGIN_TOP = 2; + /** The bottom margin property. */ + public static final int MARGIN_BOTTOM = 3; + /** Indent left property. */ + public static final int TEXT_INDENT = 4; + /** Indent right property. */ + public static final int LINE_HEIGHT = 5; + /** Align text property. */ + public static final int TEXT_ALIGN = 6; + // This must always be one more than highest property + /** Total number of properties. */ + protected static final int NR_PROPERTIES = 7; + + /** + * Array of flags indicating which attributes are set for this + * paragraph <code>Style</code>. + */ + protected boolean isSet[] = new boolean[NR_PROPERTIES]; + /** Array of attribute values for this paragraph <code>tyle</code>. */ + protected int value[] = new int[NR_PROPERTIES]; + /** Array of attribute names for this paragraph <code>Style</code>. */ + protected String attrName[] = { + "fo:margin-left", + "fo:margin-right", + "fo:margin-top", + "fo:margin-bottom", + "fo:text-indent", + "fo:line-height", + "fo:text-align" + }; + + /** Array of attribute structures for this paragraph <code>Style</code>. */ + protected Class algor[] = { + horizSize.class, + horizSize.class, + horizSize.class, + horizSize.class, + horizSize.class, + lineHeight.class, + alignment.class + }; + + /** Align right. */ + public static final int ALIGN_RIGHT = 1; + /** Align center. */ + public static final int ALIGN_CENTER = 2; + /** Align justified. */ + public static final int ALIGN_JUST = 3; + /** Align left. */ + public static final int ALIGN_LEFT = 4; + + /** Line height percentage. */ + public static final int LH_PCT = 0x40000000; + /** Line height minimum value. */ + public static final int LH_ATLEAST = 0x20000000; + /** Line height mask. */ + public static final int LH_VALUEMASK = 0x00FFFFFF; + + /** Ignored tags. */ + private static String[] ignored = { + "style:font-name", "fo:font-size", "fo:font-weight", "fo:color", + "fo:language", "fo:country", "style:font-name-asian", + "style:font-size-asian", "style:language-asian", + "style:country-asian", "style:font-name-complex", + "style:font-size-complex", "style:language-complex", + "style:country-complex", "style:text-autospace", "style:punctuation-wrap", + "style:line-break", "fo:keep-with-next", "fo:font-style", + "text:number-lines", "text:line-number" + }; + + + /** + * Constructor for use when going from DOM to client device format. + * + * @param node A <i>style:style</i> <code>Node</code> which, which + * is assumed to have <i>family</i> attribute of + * <i>paragraph</i>. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public ParaStyle(Node node, StyleCatalog sc) { + + super(node, sc); + + // Look for children. Only ones we care about are "style:properties" + // nodes. If any are found, recursively traverse them, passing + // along the style element to add properties to. + // + if (node.hasChildNodes()) { + NodeList children = node.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++) { + Node child = children.item(i); + String name = child.getNodeName(); + if (name.equals("style:properties")) { + NamedNodeMap childAttrNodes = child.getAttributes(); + if (childAttrNodes != null) { + int nChildAttrNodes = childAttrNodes.getLength(); + for (int j = 0; j < nChildAttrNodes; j++) { + Node attr = childAttrNodes.item(j); + setAttribute(attr.getNodeName(), attr.getNodeValue()); + } + } + } + } + } + } + + + /** + * Constructor for use when going from client device format to DOM. + * + * @param name Name of the <code>Style</code>. Can be null. + * @param family Family of the <code>Style</code> - usually + * <i>paragraph</i>, <i>text</i>, etc. Can be null. + * @param parent Name of the parent <code>Style</code>, or null + * if none. + * @param attribs Array of attributes to set. + * @param values Array of values to set. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public ParaStyle(String name, String familyName, String parentName, + String attribs[], String values[], StyleCatalog sc) { + super(name, familyName, parentName, sc); + if (attribs != null) + for (int i = 0; i < attribs.length; i++) + setAttribute(attribs[i], values[i]); + } + + + /** + * Alternate constructor for use when going from client device + * format to DOM. + * + * @param name Name of the <code>Style</code>. Can be null. + * @param family Family of the <code>Style</code> - usually + * <i>paragraph</i>, <i>text</i>, etc. Can be null. + * @param parent Name of the parent <code>Style</code>, or + * null if none. + * @param attribs Array of attributes indices to set. + * @param values Array of values to set. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public ParaStyle(String name, String familyName, String parentName, + int attribs[], String values[], StyleCatalog lookup) { + super(name, familyName, parentName, lookup); + if (attribs != null) + for (int i = 0; i < attribs.length; i++) + setAttribute(attribs[i], values[i]); + } + + + /** + * This code checks whether an attribute is one that we + * intentionally ignore. + * + * @param attribute The attribute to check. + * + * @return true if attribute can be ignored, false otherwise. + */ + private boolean isIgnored(String attribute) { + for (int i = 0; i < ignored.length; i++) { + if (ignored[i].equals(attribute)) + return true; + } + return false; + } + + + /** + * Set an attribute for this paragraph <code>Style</code>. + * + * @param attr The attribute to set. + * @param value The attribute value to set. + */ + public void setAttribute(String attr, String value) { + for (int i = 0; i < NR_PROPERTIES; i++) { + if (attr.equals(attrName[i])) { + setAttribute(i, value); + return; + } + } + if (!isIgnored(attr)) + Debug.log(Debug.INFO, "ParaStyle Unhandled: " + attr + "=" + value); + } + + + /** + * Check whether an attribute is set in this <code>Style</code>. + * + * @param attrIndex The attribute index to check. + * + * @return true if the attribute at specified index is set, + * false otherwise. + */ + public boolean isAttributeSet(int attrIndex) { + return isSet[attrIndex]; + } + + + /** + * Get the value of an integer attribute. + * + * @param attrIndex Index of the attribute. + * + * @return Value of the attribute, 0 if not set. + */ + public int getAttribute(int attrIndex) { + if (isSet[attrIndex]) + return value[attrIndex]; + else return 0; + } + + + /** + * Set an attribute for this paragraph <code>Style</code>. + * + * @param attr The attribute index to set. + * @apram value The attribute value to set. + */ + public void setAttribute(int attr, String value) { + isSet[attr] = true; + try { + this.value[attr] = (((conversionAlgorithm)algor[attr].newInstance())).I(value); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Instantiation error", e); + } + } + + + /** + * Return the <code>Style</code> in use. + * + * @return The fully-resolved copy of the <code>Style</code> in use. + */ + public Style getResolved() { + ParaStyle resolved = null; + try { + resolved = (ParaStyle)this.clone(); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Can't clone", e); + } + + // Look up the parent style. (If there is no style catalog + // specified, we can't do any lookups). + ParaStyle parentStyle = null; + if (sc != null) { + if (parent != null) { + parentStyle = (ParaStyle)sc.lookup(parent, family, null, + this.getClass()); + if (parentStyle == null) + Debug.log(Debug.ERROR, "parent style lookup of " + + parent + " failed!"); + else + parentStyle = (ParaStyle)parentStyle.getResolved(); + } else if (!name.equals("DEFAULT_STYLE")) { + parentStyle = (ParaStyle)sc.lookup("DEFAULT_STYLE", null, null, + this.getClass()); + } + } + + // If we found a parent, for any attributes which we don't have + // set, try to get the values from the parent. + if (parentStyle != null) { + parentStyle = (ParaStyle)parentStyle.getResolved(); + for (int i = 0; i < NR_PROPERTIES; i++) { + if (!isSet[i] && parentStyle.isSet[i]) { + resolved.isSet[i] = true; + resolved.value[i] = parentStyle.value[i]; + } + } + } + return resolved; + } + + + /** + * Private function to return the value as an element in + * a Comma Separated Value (CSV) format. + * + * @param value The value to format. + * + * @return The formatted value. + */ + private static String toCSV(String value) { + if (value != null) + return "\"" + value + "\","; + else + return "\"\","; + } + + + /** + * Private function to return the value as a last element in + * a Comma Separated Value (CSV) format. + * + * @param value The value to format. + * + * @return The formatted value. + */ + private static String toLastCSV(String value) { + if (value != null) + return "\"" + value + "\""; + else + return "\"\""; + } + + + /** + * Print a Comma Separated Value (CSV) header line for the + * spreadsheet dump. + */ + public static void dumpHdr() { + System.out.println(toCSV("Name") + toCSV("Family") + toCSV("parent") + + toCSV("left mgn") + toCSV("right mgn") + + toCSV("top mgn") + toCSV("bottom mgn") + toCSV("txt indent") + + toCSV("line height") + toLastCSV("txt align")); + } + + + /** + * Dump this <code>Style</code> as a Comma Separated Value (CSV) + * line. + */ + public void dumpCSV() { + String attributes = ""; + for (int index = 0; index <= 6; index++) { + if (isSet[index]) { + attributes += toCSV("" + value[index]); + } + else + attributes += toCSV(null); // unspecified + } + System.out.println(toCSV(name) + toCSV(family) + toCSV(parent) + + attributes + toLastCSV(null)); + } + + + /** + * Create the <code>Node</code> with the specified elements. + * + * @parentDoc Parent <code>Document</code> of the + * <code>Node</code> to create. + * @param name Name of the <code>Node</code>. + * + * @return The created <code>Node</code>. + */ + public Node createNode(org.w3c.dom.Document parentDoc, String name) { + Element node = parentDoc.createElement(name); + writeAttributes(node); + return node; + } + + + /** + * Return true if <code>style</code> is a subset of the + * <code>Style</code>. + * + * @param style <code>Style</code> to check. + * + * @return true if <code>style</code> is a subset, false + * otherwise. + */ + public boolean isSubset(Style style) { + + if (!super.isSubset(style)) + return false; + if (!this.getClass().isAssignableFrom(style.getClass())) + return false; + ParaStyle ps = (ParaStyle)style; + + for (int i = 0; i < NR_PROPERTIES; i++) { + if (ps.isSet[i]) { + // if (!isSet[i]) return false; + + if (i < NR_PROPERTIES - 1) { + // Compare the actual values. We allow a margin of error + // here because the conversion loses precision. + int diff; + if (value[i] > ps.value[i]) + diff = value[i] - ps.value[i]; + else + diff = ps.value[i] - value[i]; + if (diff > 32) + return false; + } else { + if (i == TEXT_ALIGN) + if ((value[i] == 0) && (ps.value[i] == 4)) + continue; + if (value[i] != ps.value[i]) + return false; + } + } + } + return true; + } + + + /** + * Add <code>Style</code> attributes to the given + * <code>Node</code>. This may involve writing child + * <code>Node</code> objects as well. + * + * @param node The <code>Node</code> to add <code>Style</code> + * attributes. + */ + public void writeAttributes(Element node) { + for (int i = 0; i <= TEXT_INDENT; i++) { + if (isSet[i]) { + double temp = value[i] / 100.0; + String stringVal = (new Double(temp)).toString() + "mm"; + node.setAttribute(attrName[i], stringVal); + } + } + + if (isSet[LINE_HEIGHT]) { + String stringVal; + if ((value[LINE_HEIGHT] & LH_PCT) != 0) + stringVal = (new Integer(value[LINE_HEIGHT] & LH_VALUEMASK)).toString() + "%"; + else { + double temp = (value[LINE_HEIGHT] & LH_VALUEMASK) / 100.0; + stringVal = (new Double(temp)).toString() + "mm"; + } + node.setAttribute(attrName[LINE_HEIGHT], stringVal); + } + + if (isSet[TEXT_ALIGN]) { + String val; + switch (value[TEXT_ALIGN]) { + case ALIGN_RIGHT: val = "end"; break; + case ALIGN_CENTER: val = "center"; break; + case ALIGN_JUST: val = "justify"; break; + case ALIGN_LEFT: val = "left"; break; + default: val = "unknown"; break; + } + node.setAttribute(attrName[TEXT_ALIGN], val); + } + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/Style.java b/xmerge/java/org/openoffice/xmerge/converter/xml/Style.java new file mode 100644 index 000000000000..a270e3f19fc0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/Style.java @@ -0,0 +1,238 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Style.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import java.io.IOException; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; + +/** + * An object of class <code>Style</code> represents a <i>style</i> + * in an OpenOffice document. In practice subclasses of this + * <code>Style</code>, such as <code>TextStyle</code>, + * <code>ParaStyle</code> are used. + * + * @author David Proulx + * @see <a href="TextStyle.html">TextStyle</a>, + * <a href="ParaStyle.html">ParaStyle</a> + */ +public class Style { + + /** Name of the <code>Style</code>. */ + protected String name = null; + /** Family of the <code>Style</code>. */ + protected String family = null; + /** Parent of the <code>Style</code>. */ + protected String parent = null; + + /** + * A reference to the <code>StyleCatalog</code> to be used for + * looking up ancestor <code>Style</code> objects. + */ + protected StyleCatalog sc; + + + /** + * Constructor for use when going from DOM to client device format. + * + * @param node A <i>style:style</i> or <i>style:default-style</i> + * <code>Node</code> from the document being parsed. + * No checking of <code>Node</code> is done, so if it + * is not of the proper type the results will be + * unpredictable. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public Style(Node node, StyleCatalog sc) { + + this.sc = sc; + + // Run through the attributes of this node, saving + // the ones we're interested in. + if (node.getNodeName().equals("style:default-style")) + name = "DEFAULT_STYLE"; + NamedNodeMap attrNodes = node.getAttributes(); + if (attrNodes != null) { + int len = attrNodes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attrNodes.item(i); + if (attr.getNodeName().equals("style:family")) + family = attr.getNodeValue(); + else if (attr.getNodeName().equals("style:name")) { + name = attr.getNodeValue(); + } else if (attr.getNodeName().equals("style:parent-style-name")) + parent = attr.getNodeValue(); + + } + } + } + + + /** + * Constructor for use when going from client device format to DOM. + * + * @param name Name of the <code>Style</code>. Can be null. + * @param family Family of the <code>Style</code> - usually + * <i>paragraph</i>, <i>text</i>, etc. Can be null. + * @param parent Name of the parent <code>Style</code>, or null if none. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public Style(String name, String family, String parent, StyleCatalog sc) { + this.sc = sc; + this.name = name; + this.family = family; + this.parent = parent; + } + + + /** + * Set the <code>StyleCatalog</code> to be used when looking up the + * <code>Style</code> parent. + * + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public void setCatalog(StyleCatalog sc) { + this.sc = sc; + } + + + /** + * Returns the name of this <code>Style</code>. + * + * @return The name of this <code>Style</code>. + */ + public String getName() { + return name; + } + + + /** + * Sets the name of this <code>Style</code>. + * + * @param newName The new name of this <code>Style</code>. + */ + public void setName(String newName) { + name = newName; + } + + + /** + * Return the family of this <code>Style</code>. + * + * @return The family of this <code>Style</code>. + */ + public String getFamily() { + return family; + } + + /** + * Return the name of the parent of this <code>Style</code>. + * + * @return The parent of this <code>Style</code>. + */ + public String getParent() { + return parent; + } + + + /** + * Return a <code>Style</code> object corresponding to this one, but with + * all of the inherited information from parent <code>Style</code> + * objects filled in. The object returned will be a new object, not a + * reference to this object, even if it does not need any information + * added. + * + * @return A resolved <code>Style</code> object in which to look up + * ancestors. + */ + public Style getResolved() { + return new Style(name, family, parent, sc); + } + + + /** + * Write a <code>Node</code> in <code>parentDoc</code> + * representing this <code>Style</code>. Note that the + * <code>Node</code> is returned unconnected. + * + * @param parentDoc Document to which new <code>Node</code> will + * belong. + * @param name Name to use for new <code>Node</code>. + */ + public Node createNode(org.w3c.dom.Document parentDoc, String name) { + // DJP: write this! Should call writeAttributes() + return null; + } + + + /** + * Write this <code>Style</code> object's attributes to the given + * <code>Node</code>. This may involve writing child + * <code>Node</code> objects as well. This is similar to the + * <code>writeNode</code> method, but the <code>Node</code> + * already exists, and this does <b>not</b> write the name, + * family, and parent attributes, which are assumed to already + * exist in the <code>Node</code>. + * + * @param node The <code>Node</code> to add style attributes. + */ + public void writeAttributes(Node node) { + } + + + /** + * Return true if <code>Style</code> is a subset of this one. Note + * that this will return true even if <code>Style</code> is less + * specific than this <code>Style</code>, so long as it does not + * contradict this <code>Style</code> in any way. + * + * This always returns true since only subclasses of + * <code>Style</code> contain any actual <code>Style</code> + * information. + * + * @param style The <code>Style</code> to check + * + * @return true if the <code>Style</code> is a subset, false otherwise. + */ + public boolean isSubset(Style style) { + return true; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/StyleCatalog.java b/xmerge/java/org/openoffice/xmerge/converter/xml/StyleCatalog.java new file mode 100644 index 000000000000..fe54f0fbd999 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/StyleCatalog.java @@ -0,0 +1,400 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: StyleCatalog.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; +import org.openoffice.xmerge.util.*; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import java.io.IOException; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import java.util.Vector; +import java.lang.reflect.Constructor; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + + +/** + * A <code>StyleCatalog</code> holds a collection of <code>Style</code> + * objects. It is intended for use when parsing or building a DOM + * document. + * + * Each entry in the <code>StyleCatalog</code> represents a + * <code>Style</code>, and is an object which is a subclass of + * <code>Style</code>. + * + * @author David Proulx + * @see <a href="Style.html">Style</a> + */ +public class StyleCatalog { + + private Vector styles; // The actual styles + + /** + * Constructor + * + * @param initialEntries Expected number of entries to set + * for efficiency purposes. + */ + public StyleCatalog(int initialEntries) { + styles = new Vector(initialEntries); + } + + + /** + * <p>Parse the <code>Document</code> starting from <code>node</code> + * and working downward, and add all styles found, so long as their + * family name is listed in <code>families</code>. For each + * family name in <code>families</code> there must be a corresponding + * element in <code>classes</code>, which specifies the class type + * to use for that family. All of these classes must be + * subclasses of <code>Style</code>. There can be multiple + * classes specified for a particular family.</p> + * + * <p>If <code>defaultClass</code> is non-null, then all styles that + * are found will be added. Any <code>Style</code> whose family is + * not listed in <code>families</code> will be added using defaultClass, + * which, of course, must be a subclass of <code>Style</code>. + * If <code>alwaysCreateDefault</code> is true, then a class + * of type <code>defaultClass</code> will always be created, + * regardless of whether there was also a match in + * <code>families</code>.</p> + * + * <p>DJP Todo: make it recursive so that <code>node</code> can be + * higher up in the <code>Document</code> tree.</p> + * + * @param node The node to be searched for + * <code>Style</code> objects. + * @param families An array of <code>Style</code> families + * to add. + * @param classes An array of class types corresponding + * to the families array. + * @param defaultClass All <code>Style</code> objects that are + * found are added to this class. + * @param alwaysCreateDefault A class of type <code>defaultClass</code> + * will always be created, regardless of + * whether there is a match in the + * families array. + */ + public void add(Node node, String families[], Class classes[], + Class defaultClass, boolean alwaysCreateDefault) { + + if (node == null) + return; + + if (families == null) + families = new String[0]; + if (classes == null) + classes = new Class[0]; + if (node.hasChildNodes()) { + NodeList children = node.getChildNodes(); + int len = children.getLength(); + + for (int i = 0; i < len; i++) { + boolean found = false; + Node child = children.item(i); + String name = child.getNodeName(); + if (name.equals("style:default-style") || name.equals("style:style")) { + String familyName = getFamilyName(child); + if (familyName == null) { + Debug.log(Debug.ERROR, "familyName is null!"); + continue; + } + + for (int j = 0; j < families.length; j++) { + if (families[j].equals(familyName)) { + Class styleClass = classes[j]; + callConstructor(classes[j], child); + found = true; + } + } + if ((!found || alwaysCreateDefault) && (defaultClass != null)) + callConstructor(defaultClass, child); + } + } + } + } + + + /** + * Call the constructor of class <code>cls</code> with parameters + * <code>node</code>, and add the resulting <code>Style</code> to + * the catalog. + * + * @param cls The class whose constructor will be called. + * @param node The constructed class will be added to this node. + */ + private void callConstructor(Class cls, Node node) { + Class params[] = new Class[2]; + params[0] = Node.class; + params[1] = this.getClass(); + try { + Constructor c = cls.getConstructor(params); + Object p[] = new Object[2]; + p[0] = node; + p[1] = this; + styles.add(c.newInstance(p)); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Exception when calling constructor", e); + } + } + + + /** + * Add a <code>Style</code> to the catalog. + * + * @param s The <code>Style</code> to add. + */ + public void add(Style s) { + styles.addElement(s); + } + + + /** + * Return the first <code>Style</code> matching the specified names. + * + * @param name Name to match, null is considered + * <i>always match</i>. + * @param family Family to match, null is considered + * <i>always match</i>. + * @param parent Parent to match, null is considered + * <i>always match</i>. + * @param styleClass styleClass to match, null is considered + * <i>always match</i>. + * + * @return <code>Style</code> value if all parameters match, + * null otherwise + */ + public Style lookup(String name, String family, String parent, + Class styleClass) { + int nStyles = styles.size(); + for (int i = 0; i < nStyles; i++) { + Style s = (Style)styles.elementAt(i); + if ((name != null) && (s.getName() != null) + && (!s.getName().equals(name))) + continue; + if ((family != null) && (s.getFamily() != null) + && (!s.getFamily().equals(family))) + continue; + if ((parent != null) && (s.getParent() != null) + && (!s.getParent().equals(parent))) + continue; + if ((styleClass != null) && (s.getClass() != styleClass)) + continue; + if (s.getName() == null) continue; // DJP: workaround for "null name" problem + return s; + } + return null; // none found + } + + + /** + * Given a <code>Style</code> <code>s<code> return all + * <code>Style</code> objects that match. + * + * @param s <code>Style</code> to match. + * + * @return An array of <code>Style</code> objects that match, an + * empty array if none match. + */ + public Style[] getMatching(Style s) { + + // Run through and count the matching styles so we know how big of + // an array to allocate. + int matchCount = 0; + int nStyles = styles.size(); + for (int j = 0; j < nStyles; j++) { + Style p = ((Style)styles.elementAt(j)).getResolved(); + if (p.isSubset(s)) matchCount++; + } + + // Now allocate the array, and run through again, populating it. + Style[] matchArray = new Style[matchCount]; + matchCount = 0; + for (int j = 0; j < nStyles; j++) { + Style p = ((Style)styles.elementAt(j)).getResolved(); + if (p.isSubset(s)) matchArray[matchCount++] = p; + } + return matchArray; + } + + + /** + * Given a <code>Style</code> <code>s</code>, return the + * <code>style</code> that is the closest match. Not currently + * implemented. + * + * @param s <code>Style</code> to match. + * + * @return The <code>Style</code> that most closely matches. + */ + public Style getBestMatch(Style s) { + // DJP: is this needed? + // DJP ToDo: implement this + return null; + } + + + /** + * <p>Create a <code>Node</code> named <code>name</code> in + * <code>Document</code> <code>parentDoc</code>, and write the + * entire <code>StyleCatalog</code> to it.</p> + * + * <p>Note that the resulting node is returned, but is not connected + * into the document. Placing the output node in the document is + * left to the caller.</p> + * + * @param parentDoc The <code>Document</code> to add the + * <code>Node</code>. + * @param name The name of the <code>Node</code> to add. + * + * @return The <code>Element</code> that was created. + */ + public Element writeNode(org.w3c.dom.Document parentDoc, String name) { + Element rootNode = parentDoc.createElement(name); + + int len = styles.size(); + for (int j = 0; j < len; j++) { + Style s = (Style)styles.get(j); + + Element styleNode = parentDoc.createElement("style:style"); + + if (s.getName() != null) + styleNode.setAttribute("style:name", s.getName()); + if (s.getParent() != null) + styleNode.setAttribute("style:parent-style-name", s.getParent()); + if (s.getFamily() != null) + styleNode.setAttribute("style:family", s.getFamily()); + + Element propertiesNode = (Element) s.createNode(parentDoc, "style:properties"); + // if (propertiesNode.getFirstChild() != null) + // DJP: only add node if has children OR attributes + if (propertiesNode != null) + styleNode.appendChild(propertiesNode); + + rootNode.appendChild(styleNode); + } + + return rootNode; + } + + + /** + * Dump the <code>Style</code> table in Comma Separated Value (CSV) + * format + * + * @param para If true, dump in paragraph <code>Style</code>, + * otherwise dump in text style. + */ + public void dumpCSV(boolean para) { + if (!para) { + TextStyle.dumpHdr(); + int nStyles = styles.size(); + for (int i = 0; i < nStyles; i++) { + Style s = (Style)styles.get(i); + if (s.getClass().equals(TextStyle.class)) + ((TextStyle)s).dumpCSV(); + } + } else { + ParaStyle.dumpHdr(); + int nStyles = styles.size(); + for (int i = 0; i < nStyles; i++) { + Style s = (Style)styles.get(i); + if (s.getClass().equals(ParaStyle.class)) + ((ParaStyle)s).dumpCSV(); + } + } + + } + + + /** + * Check whether a given node represents a <code>Style</code> + * that should be added to the catalog, and if so, return the + * class type for it. If <code>Style</code> should not be added, + * or if node is not a <code>Style</code>, return null. + * + * @param node The <code>Node</code> to be checked. + * @param families An array of <code>Style</code> families. + * @param classes An array of class types corresponding to the + * families array. + * @param defaultClass The default class. + * + * @return The class that is appropriate for this node. + */ + private Class getClass(Node node, String[] families, Class[] classes, + Class defaultClass) { + NamedNodeMap attributes = node.getAttributes(); + if (attributes != null) { + int len = attributes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attributes.item(i); + if (attr.getNodeName().equals("style:family")) { + String familyName = attr.getNodeValue(); + for (int j = 0; j < families.length; j++) { + if (families[j].equals(familyName)) + return classes[j]; + } + return defaultClass; + } + } + } + return null; + } + + + /** + * Find the family attribute of a <code>Style</code> <code>Node</code>. + * + * @param node The <code>Node</code> to check. + * + * @return The family attribute, or null if one does not + * exist. + */ + private String getFamilyName(Node node) { + NamedNodeMap attributes = node.getAttributes(); + if (attributes != null) { + int len = attributes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attributes.item(i); + if (attr.getNodeName().equals("style:family")) { + return attr.getNodeValue(); + } + } + } + return null; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/StyleTest01.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/StyleTest01.xml new file mode 100644 index 000000000000..ac2652c49ee6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/StyleTest01.xml @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document office:class="text" office:version="0.9" xmlns:office="http://openoffice.org/2000/office" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="http://openoffice.org/2000/meta" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" xmlns:zensync="haha"> + + <!-- styles01 is four styles, named "TX01" through "TX04". Each is a + child of its predecessor. They define properties as follows: + fo:margin-right fo:margin-top fo:margin-bottom + TX01 100 300 + TX02 + TX03 200 + TX04 301 + When inheritance is considered, the properties look like this: + fo:margin-right fo:margin-top fo:margin-bottom + TX01 100 300 + TX02 100 300 + TX03 100 200 300 + TX04 100 200 301 + DJP: change prop1, prop2, prop3 to paragraph or text properties so + the actual classes can be tested. + --> + <zensync:styles01> + + <style:style style:name="TX01" style:family="text" + style:class="text"> + <style:properties fo:margin-right="100" fo:margin-bottom="300"/> + </style:style> + + <style:style style:name="TX02" style:family="text" + style:parent-style-name="TX01" style:class="text"> + </style:style> + + <style:style style:name="TX03" style:family="text" + style:parent-style-name="TX02" style:class="text"> + <style:properties fo:margin-top="200" /> + </style:style> + + <style:style style:name="TX04" style:family="text" + style:parent-style-name="TX03" style:class="text"> + <style:properties fo:margin-bottom="301" /> + </style:style> + + </zensync:styles01> + + + + <office:styles> + <style:default-style style:family="paragraph"> + <style:properties fo:color="#000000" style:font-name="Times New Roman" fo:font-size="12pt" fo:language="en" fo:country="US" style:font-name-asian="Andale WT UI" style:font-size-asian="12pt" style:language-asian="none" style:country-asian="none" style:font-name-complex="Simplified Arabic" style:font-size-complex="12pt" style:language-complex="none" style:country-complex="none" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict"> + <style:tab-stops> + <style:tab-stop style:position="22.05mm" style:type="default"/> + </style:tab-stops> + </style:properties> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text body" style:class="text"> + <style:properties style:font-name="Arial" fo:font-size="14pt" fo:margin-top="4.23mm" fo:margin-bottom="2.12mm" fo:keep-with-next="true"/> + </style:style> + <style:style style:name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text"> + <style:properties fo:margin-top="0mm" fo:margin-bottom="2.12mm"/> + </style:style> + <style:style style:name="List" style:family="paragraph" style:parent-style-name="Text body" style:class="list"> + <style:properties style:font-name="Times New Roman"/> + </style:style> + <style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:properties style:font-name="Times New Roman" fo:font-size="10pt" fo:font-style="italic" fo:margin-top="2.12mm" fo:margin-bottom="2.12mm" text:number-lines="false" text:line-number="0"/> + </style:style> + <style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index"> + <style:properties style:font-name="Times New Roman" text:number-lines="false" text:line-number="0"/> + </style:style> + <style:style style:name="Heading 1" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text body" style:class="text"> + <style:properties fo:font-size="16pt" fo:font-weight="bold"/> + </style:style> + <style:style style:name="Heading 2" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text body" style:class="text"> + <style:properties fo:font-size="14pt" fo:font-style="italic" fo:font-weight="bold"/> + </style:style> + <style:style style:name="Heading 3" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text body" style:class="text"> + <style:properties fo:font-size="14pt" fo:font-weight="bold"/> + </style:style> + <style:style style:name="First line indent" style:family="paragraph" style:parent-style-name="Text body" style:class="text"> + <style:properties fo:margin-left="0mm" fo:margin-right="0mm" fo:text-indent="4.99mm"/> + </style:style> + <style:style style:name="Hanging indent" style:family="paragraph" style:parent-style-name="Text body" style:class="text"> + <style:properties fo:margin-left="10mm" fo:margin-right="0mm" fo:text-indent="-4.99mm"> + <style:tab-stops> + <style:tab-stop style:position="0mm"/> + </style:tab-stops> + </style:properties> + </style:style> + <style:style style:name="Marginalia" style:family="paragraph" style:parent-style-name="Text body" style:class="text"> + <style:properties fo:margin-left="40.01mm" fo:margin-right="0mm" fo:text-indent="0mm"/> + </style:style> + <style:style style:name="Salutation" style:family="paragraph" style:parent-style-name="Standard" style:class="text"> + <style:properties text:number-lines="false" text:line-number="0"/> + </style:style> + <style:style style:name="Strong Emphasis" style:family="text"> + <style:properties fo:font-weight="bold"/> + </style:style> + <style:style style:name="Example" style:family="text"> + <style:properties style:font-name="Courier"/> + </style:style> + <style:style style:name="Definition" style:family="text"/> + <style:style style:name="Line numbering" style:family="text"/> + <style:default-style style:family="graphics"> + <style:properties svg:width="0mm" svg:height="0mm" text:anchor-type="page" text:anchor-page-number="0" svg:x="0mm" svg:y="0mm" style:run-through="foreground" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="page-content" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" fo:background-color="transparent" fo:padding="0mm" style:editable="false"/> + </style:default-style> + <style:style style:name="Frame" style:family="graphics"> + <style:properties text:anchor-type="paragraph" svg:x="0mm" svg:y="0mm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" fo:padding="1.5mm" fo:border="0.02mm solid #000000"/> + </style:style> + <text:outline-style> + <text:outline-level-style text:level="1" style:num-format=""/> + <text:outline-level-style text:level="2" style:num-format=""/> + <text:outline-level-style text:level="3" style:num-format=""/> + <text:outline-level-style text:level="4" style:num-format=""/> + <text:outline-level-style text:level="5" style:num-format=""/> + <text:outline-level-style text:level="6" style:num-format=""/> + <text:outline-level-style text:level="7" style:num-format=""/> + <text:outline-level-style text:level="8" style:num-format=""/> + <text:outline-level-style text:level="9" style:num-format=""/> + <text:outline-level-style text:level="10" style:num-format=""/> + </text:outline-style> + <text:footnotes-configuration style:num-format="1" text:offset="0" text:footnotes-position="page" text:start-numbering-at="document"/> + <text:endnotes-configuration style:num-format="i" text:offset="0"/> + <text:bibliography-configuration text:prefix="[" text:suffix="]"/> + <text:linenumbering-configuration text:style-name="Line numbering" text:number-lines="false" text:offset="4.99mm" style:num-format="1" text:number-position="left" text:increment="5"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:properties fo:font-style="normal" fo:font-weight="normal"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard"> + <style:properties fo:line-height="200%" fo:margin-top="6mm" fo:margin-bottom="20mm"/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:properties fo:font-style="italic"/> + </style:style> + <style:style style:name="T2" style:family="text"> + <style:properties fo:font-style="normal"/> + </style:style> + <style:style style:name="T3" style:family="text"> + <style:properties fo:font-style="normal" fo:font-weight="bold"/> + </style:style> + <style:style style:name="T4" style:family="text"> + <style:properties fo:font-style="normal" fo:font-weight="normal"/> + </style:style> + <style:style style:name="T5" style:family="text"> + <style:properties style:text-underline="double" style:text-underline-color="#000000"/> + </style:style> + <style:style style:name="T6" style:family="text"> + <style:properties style:text-underline="single" style:text-underline-color="#000000"/> + </style:style> + <style:style style:name="T7" style:family="text" style:parent-style-name="Example"> + <style:properties fo:font-size="24pt"/> + </style:style> + <style:style style:name="T8" style:family="text" style:parent-style-name="Definition"> + <style:properties fo:font-size="24pt"/> + </style:style> + <style:page-master style:name="pm1"> + <style:properties fo:page-width="209.99mm" fo:page-height="296.99mm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="25.4mm" fo:margin-bottom="25.4mm" fo:margin-left="31.75mm" fo:margin-right="31.75mm"/> + <style:header-style/> + <style:footer-style/> + </style:page-master> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-master-name="pm1"/> + </office:master-styles> +</office:document> + + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/TextStyle.java b/xmerge/java/org/openoffice/xmerge/converter/xml/TextStyle.java new file mode 100644 index 000000000000..9bba83c0d135 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/TextStyle.java @@ -0,0 +1,687 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TextStyle.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// DJP ToDo: need way of specifying fg/bg colors on ws->DOM + +package org.openoffice.xmerge.converter.xml; + +import java.awt.Color; +import java.io.IOException; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.util.Debug; + +/** + * Represents a text <code>Style</code> in an OpenOffice document. + * + * @author David Proulx + */ +public class TextStyle extends Style implements Cloneable { + + final protected static int FIRST_ATTR = 0x01; + /** Indicates <i>bold</i> text. */ + final public static int BOLD = 0x01; + /** Indicates <i>italic</i> text. */ + final public static int ITALIC = 0x02; + /** Indicates <i>underlined</i> text. */ + final public static int UNDERLINE = 0x04; + /** Indicates <i>strike-through</i> in the text. */ + final public static int STRIKETHRU = 0x08; + /** Indicates <i>superscripted</i> text. */ + final public static int SUPERSCRIPT = 0x10; + /** Indicates <i>subscripted</i> text. */ + final public static int SUBSCRIPT = 0x20; + /** Indicates the last attribute. */ + final protected static int LAST_ATTR = 0x20; + + /** Values of text attributes. */ + protected int values = 0; + /** Bitwise mask of text attributes. */ + protected int mask = 0; + + /** Font size in points. */ + protected int sizeInPoints = 0; + /** Font name. */ + protected String fontName = null; + /** Font <code>Color</code>. */ + protected Color fontColor = null; + /** Background <code>Color</code>. */ + protected Color bgColor = null; + + /** + * Constructor for use when going from DOM to client device format. + * + * @param Node The <i>style:style</i> <code>Node</code> containing + * the <code>Style</code>. (This <code>Node</code> is + * assumed have a <i>family</i> attribute of <i>text</i>). + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public TextStyle(Node node, StyleCatalog sc) { + super(node, sc); + + // Run through the attributes of this node, saving + // the ones we're interested in. + NamedNodeMap attrNodes = node.getAttributes(); + if (attrNodes != null) { + int len = attrNodes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attrNodes.item(i); + handleAttribute(attr.getNodeName(), attr.getNodeValue()); + } + } + + // Look for children. Only ones we care about are "style:properties" + // nodes. If any are found, recursively traverse them, passing + // along the style element to add properties to. + if (node.hasChildNodes()) { + NodeList children = node.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++) { + Node child = children.item(i); + String name = child.getNodeName(); + if (name.equals("style:properties")) { + NamedNodeMap childAttrNodes = child.getAttributes(); + if (childAttrNodes != null) { + int nChildAttrNodes = childAttrNodes.getLength(); + for (int j = 0; j < nChildAttrNodes; j++) { + Node attr = childAttrNodes.item(j); + handleAttribute(attr.getNodeName(), + attr.getNodeValue()); + } + } + } + } + } + } + + + /** + * Constructor for use when going from client device format to DOM + * + * @param name Name of text <code>Style</code>. Can be null. + * @param family Family of text <code>Style</code> (usually + * <i>text</i>). Can be null. + * @param parent Name of parent text <code>Style</code>, or null + * for none. + * @param mask Bitwise mask of text attributes that this text + * <code>Style</code> will specify. Can be any + * combination of the following, or'ed together: + * {@link #BOLD}, {@link #ITALIC}, {@link #UNDERLINE}, + * {@link #STRIKETHRU}, {@link #SUPERSCRIPT}, + * {@link #SUBSCRIPT}. This parameter determines what + * attributes this <code>Style</code> will specify. + * When an attribute is specified in a + * <code>Style</code>, its value can be either + * <i>on</i> or <i>off</i>. The on/off value for + * each attribute is controlled by the + * <code>values</code> parameter. + * @param values Values of text attributes that this text + * <code>Style</code> will be setting. Any of the + * attributes ({@link #BOLD}, etc) listed for + * <code>mask</code> can be used for this. + * @param fontSize Font size in points. + * @param fontName Name of font. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public TextStyle(String name, String family, String parent, + int mask, int values, int fontSize, String fontName, StyleCatalog sc) { + super(name, family, parent, sc); + this.mask = mask; + this.values = values; + this.sizeInPoints = fontSize; + this.fontName = fontName; + } + + + /** + * Parse a color specification of the form <i>#rrggbb</i> + * + * @param value <code>Color</code> specification to parse. + * + * @returns The <code>Color</code> associated the value. + */ + private Color parseColorString(String value) { + // Assume color value is of form #rrggbb + String r = value.substring(1, 3); + String g = value.substring(3, 5); + String b = value.substring(5, 7); + int red = 0; + int green = 0; + int blue = 0; + try { + red = Integer.parseInt(r, 16); + green = Integer.parseInt(g, 16); + blue = Integer.parseInt(b, 16); + } catch (NumberFormatException e) { + Debug.log(Debug.ERROR, "Problem parsing a color string", e); + } + return new Color(red, green, blue); + } + + + /** + * Set an attribute. + * + * @param attr The attribute to set. + * @param value The attribute value to set. + */ + private void handleAttribute(String attr, String value) { + + if (attr.equals("fo:font-weight")) { + if (value.equals("bold")) turnAttributesOn(BOLD); + else if (value.equals("normal")) turnAttributesOff(BOLD); + } + + else if (attr.equals("fo:font-style")) { + if (value.equals("italic")) turnAttributesOn(ITALIC); + else if (value.equals("oblique")) turnAttributesOn(ITALIC); + else if (value.equals("normal")) turnAttributesOff(ITALIC); + } + + else if (attr.equals("style:text-underline")) { + if (value.equals("none")) + turnAttributesOff(UNDERLINE); + else + turnAttributesOn(UNDERLINE); + } + + else if (attr.equals("style:text-crossing-out")) { + if (value.equals("none")) + turnAttributesOff(STRIKETHRU); + else + turnAttributesOn(STRIKETHRU); + } + + else if (attr.equals("style:text-position")) { + if (value.startsWith("super ")) + turnAttributesOn(SUPERSCRIPT); + else if (value.startsWith("sub ")) + turnAttributesOn(SUBSCRIPT); + else if (value.startsWith("0% ")) + turnAttributesOff(SUPERSCRIPT | SUBSCRIPT); + else { + String firstPart = value.substring(0, value.indexOf(" ")); + if (firstPart.endsWith("%")) { + firstPart = firstPart.substring(0, value.indexOf("%")); + int amount; + try { + amount = Integer.parseInt(firstPart); + } catch (NumberFormatException e) { + amount = 0; + Debug.log(Debug.ERROR, "Problem with style:text-position tag", e); + } + if (amount < 0) turnAttributesOn(SUBSCRIPT); + else if (amount > 0) turnAttributesOn(SUPERSCRIPT); + } + } + } + + else if (attr.equals("fo:font-size")) { + if (value.endsWith("pt")) { + String num = value.substring(0, value.length() - 2); + sizeInPoints = Integer.parseInt(num); + } + } + + else if (attr.equals("style:font-name")) + fontName = value; + + else if (attr.equals("fo:color")) + fontColor = parseColorString(value); + + else if (attr.equals("style:text-background-color")) + bgColor = parseColorString(value); + + else if (isIgnored(attr)) {} + + else { + Debug.log(Debug.INFO, "TextStyle Unhandled: " + attr + "=" + value); + } + } + + + /** + * Return true if text <code>attribute</code> is set in this + * <code>Style</code>. An attribute that is set may have a + * value of <i>on</i> or <i>off</i>. + * + * @param attribute The attribute to check ({@link #BOLD}, + * {@link #ITALIC}, etc.). + * + * @return true if text <code>attribute</code> is set in this + * <code>Style</code>, false otherwise. + */ + public boolean isSet(int attribute) { + return (!((mask & attribute) == 0)); + } + + + /** + * Return true if the <code>attribute</code> is set to <i>on</i> + * + * @param attribute Attribute to check ({@link #BOLD}, + * {@link #ITALIC}, etc.) + * + * @return true if <code>attribute</code> is set to <i>on</i>, + * otherwise false. + */ + public boolean getAttribute(int attribute) { + if ((mask & attribute) == 0) + return false; + return (!((values & attribute) == 0)); + } + + + /** + * Return the font size for this <code>Style</code>. + * + * @return The font size in points + */ + public int getFontSize() { + return sizeInPoints; + } + + + /** + * Return the name of the font for this <code>Style</code>. + * + * @return Name of font, or null if no font is specified by + * this <code>Style</code>. + */ + public String getFontName() { + return fontName; + } + + + /** + * Return the font <code>Color</code> for this <code>Style</code>. + * Can be null if none was specified. + * + * @return <code>Color</code> value for this <code>Style</code>. + * Can be null. + */ + public Color getFontColor() { + return fontColor; + } + + + /** + * Return the background <code>Color</code> for this + * <code>Style</code>. Can be null if none was specified. + * + * @return Background <code>Color</code> value for this + * <code>Style</code>. Can be null. + */ + public Color getBackgroundColor() { + return bgColor; + } + + + /** + * Set the font and/or background <code>Color</code> for this + * <code>Style</code>. + * + * @param fontColor The font <code>Color</code> to set. + * @param backgroundColor The background <code>Color</code> to set. + */ + public void setColors(Color fontColor, Color backgroundColor) { + if (fontColor != null) + this.fontColor = fontColor; + if (backgroundColor != null) + this.bgColor = backgroundColor; + } + + + /** + * Return a <code>Style</code> object corresponding to this one, + * but with all of the inherited information from parent + * <code>Style</code> objects filled in. The object returned will + * be a new object, not a reference to this object, even if it does + * not need any information added. + * + * @return The <code>StyleCatalog</code> in which to look up + * ancestors. + */ + public Style getResolved() { + // Create a new object to return, which is a clone of this one. + TextStyle resolved = null; + try { + resolved = (TextStyle)this.clone(); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Can't clone", e); + } + + // Look up the parentStyle. (If there is no style catalog + // specified, we can't do any lookups.) + TextStyle parentStyle = null; + if (sc != null) { + if (parent != null) { + parentStyle = (TextStyle)sc.lookup(parent, family, null, + this.getClass()); + if (parentStyle == null) + Debug.log(Debug.ERROR, "parent style lookup of " + + parent + " failed!"); + else + parentStyle = (TextStyle)parentStyle.getResolved(); + + } else if (!name.equals("DEFAULT_STYLE")) { + parentStyle = (TextStyle)sc.lookup("DEFAULT_STYLE", null, + null, this.getClass()); + } + } + + // If we found a parent, for any attributes which we don't have + // set, try to get the values from the parent. + if (parentStyle != null) { + parentStyle = (TextStyle)parentStyle.getResolved(); + + if ((sizeInPoints == 0) && (parentStyle.sizeInPoints != 0)) + resolved.sizeInPoints = parentStyle.sizeInPoints; + if ((fontName == null) && (parentStyle.fontName != null)) + resolved.fontName = parentStyle.fontName; + if ((fontColor == null) && (parentStyle.fontColor != null)) + resolved.fontColor = parentStyle.fontColor; + if ((bgColor == null) && (parentStyle.bgColor != null)) + resolved.bgColor = parentStyle.bgColor; + for (int m = BOLD; m <= SUBSCRIPT; m = m << 1) { + if (((mask & m) == 0) && ((parentStyle.mask & m) != 0)) { + resolved.mask |= m; + resolved.values |= (parentStyle.mask & m); + } + } + + } + return resolved; + } + + + /** + * Set one or more text attributes to <i>on</i>. + * + * @param flags Flag values to set <i>on</i>. + */ + private void turnAttributesOn(int flags) { + mask |= flags; + values |= flags; + } + + + /** + * Set one or more text attributes to <i>off</i>. + * + * @param flags The flag values to set <i>off</i>. + */ + private void turnAttributesOff(int flags) { + mask |= flags; + values &= ~flags; + } + + + /** + * Private function to return the value as an element in + * a Comma Separated Value (CSV) format. + * + * @param The value to format. + * + * @return The formatted value. + */ + private static String toCSV(String value) { + if (value != null) + return "\"" + value + "\","; + else + return "\"\","; + } + + + /** + * Private function to return the value as a last element in + * a Comma Separated Value (CSV) format. + * + * @param value The value to format. + * + * @return The formatted value. + */ + private static String toLastCSV(String value) { + if (value != null) + return "\"" + value + "\""; + else + return "\"\""; + } + + + /** + * Print a Comma Separated Value (CSV) header line for the + * spreadsheet dump. + */ + public static void dumpHdr() { + System.out.println(toCSV("Name") + toCSV("Family") + toCSV("parent") + + toCSV("Font") + toCSV("Size") + + toCSV("Bold") + toCSV("Italic") + toCSV("Underline") + + toCSV("Strikethru") + toCSV("Superscript") + toLastCSV("Subscript")); + } + + + /** + * Dump this <code>Style</code> as a Comma Separated Value (CSV) line. + */ + public void dumpCSV() { + String attributes = ""; + for (int bitVal = 0x01; bitVal <= 0x20; bitVal = bitVal << 1) { + if ((bitVal & mask) != 0) { + attributes += toCSV(((bitVal & values) != 0) ? "yes" : "no"); + } else attributes += toCSV(null); // unspecified + } + System.out.println(toCSV(name) + toCSV(family) + toCSV(parent) + + toCSV(fontName) + toCSV("" + sizeInPoints) + attributes + toLastCSV(null)); + } + + + /** + * Create a new <code>Node</code> in the <code>Document</code>, and + * write this <code>Style</code> to it. + * + * @param parentDoc Parent <code>Document</code> of the + * <code>Node</code> to create. + * @param name Name to use for the new <code>Node</code> (e.g. + * <i>style:style</i>) + * + * @return Created <code>Node</code>. + */ + public Node createNode(org.w3c.dom.Document parentDoc, String name) { + Element node = parentDoc.createElement(name); + writeAttributes(node); + return node; + } + + + /** + * Return true if <code>style</code> specifies as much or less + * than this <code>Style</code>, and nothing it specifies + * contradicts this <code>Style</code>. + * + * @param style The <code>Style</code> to check. + * + * @return true if <code>style</code> is a subset, false + * otherwise. + */ + public boolean isSubset(Style style) { + if (style.getClass() != this.getClass()) + return false; + TextStyle tStyle = (TextStyle)style; + + if (tStyle.values != values) + return false; + + if (tStyle.sizeInPoints != 0) { + if (sizeInPoints != tStyle.sizeInPoints) + return false; + } + + if (tStyle.fontName != null) { + if (fontName == null) + return false; + if (!fontName.equals(tStyle.fontName)) + return false; + } + + if (tStyle.fontColor != null) { + if (fontColor == null) + return false; + if (!fontColor.equals(tStyle.fontColor)) + return false; + } + + if (tStyle.bgColor != null) { + if (bgColor == null) + return false; + if (!bgColor.equals(tStyle.bgColor)) + return false; + } + + return true; + } + + + /** + * Write this <code>Style</code> object's attributes to a + * <code>Node</code> in the <code>Document</code>. + * + * @param node The <code>Node</code> to add <code>Style</code> + * attributes. + */ + public void writeAttributes(Element node) { + + if ((mask & BOLD) != 0) + if ((values & BOLD) != 0) + node.setAttribute("fo:font-weight", "bold"); + + if ((mask & ITALIC) != 0) + if ((values & ITALIC) != 0) + node.setAttribute("fo:font-style", "italic"); + + if ((mask & UNDERLINE) != 0) + if ((values & UNDERLINE) != 0) + node.setAttribute("style:text-underline", "single"); + + if ((mask & STRIKETHRU) != 0) + if ((values & STRIKETHRU) != 0) + node.setAttribute("style:text-crossing-out", "single-line"); + + if ((mask & SUPERSCRIPT) != 0) + if ((values & SUPERSCRIPT) != 0) + node.setAttribute("style:text-position", "super 58%"); + + if ((mask & SUBSCRIPT) != 0) + if ((values & SUBSCRIPT) != 0) + node.setAttribute("style:text-position", "sub 58%"); + + if (sizeInPoints != 0) { + Integer fs = new Integer(sizeInPoints); + node.setAttribute("fo:font-size", fs.toString() + "pt"); + } + + if (fontName != null) + node.setAttribute("style:font-name", fontName); + + if (fontColor != null) + node.setAttribute("fo:color", buildColorString(fontColor)); + + if (bgColor != null) + node.setAttribute("style:text-background-color", + buildColorString(bgColor)); + } + + + /** + * Given a <code>Color</code>, return a string of the form + * <i>#rrggbb</i>. + * + * @param c The <code>Color</code> value. + * + * @return The <code>Color</code> value in the form <i>#rrggbb</i>. + */ + private String buildColorString(Color c) { + int v[] = new int[3]; + v[0] = c.getRed(); + v[1] = c.getGreen(); + v[2] = c.getBlue(); + String colorString = new String("#"); + for (int i = 0; i <= 2; i++) { + String xx = Integer.toHexString(v[i]); + if (xx.length() < 2) + xx = "0" + xx; + colorString += xx; + } + return colorString; + } + + + private static String[] ignored = { + "style:text-autospace", "style:text-underline-color", + "fo:margin-left", "fo:margin-right", "fo:text-indent", + "fo:margin-top", "fo:margin-bottom", "text:line-number", + "text:number-lines", "style:country-asian", + "style:font-size-asian", "style:font-name-complex", + "style:language-complex", "style:country-complex", + "style:font-size-complex", "style:punctuation-wrap", + "fo:language", "fo:country", + "style:font-name-asian", "style:language-asian", + "style:line-break", "fo:keep-with-next" + }; + + + /* + * This code checks whether an attribute is one that we + * intentionally ignore. + * + * @param attribute The attribute to check. + * + * @return true if <code>attribute</code> can be ignored, + * otherwise false. + */ + private boolean isIgnored(String attribute) { + for (int i = 0; i < ignored.length; i++) { + if (ignored[i].equals(attribute)) + return true; + } + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/build.xml new file mode 100644 index 000000000000..e179322cd3de --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/build.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.5 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxc_xml" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxc_xml"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/EmbeddedObject.java"/> + <include name="${package}/EmbeddedBinaryObject.java"/> + <include name="${package}/EmbeddedXMLObject.java"/> + <include name="${package}/OfficeConstants.java"/> + <include name="${package}/OfficeZip.java"/> + <include name="${package}/OfficeDocument.java"/> + <include name="${package}/OfficeDocumentException.java"/> + <include name="${package}/ParaStyle.java"/> + <include name="${package}/StyleCatalog.java"/> + <include name="${package}/Style.java"/> + <include name="${package}/TextStyle.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/makefile.mk new file mode 100644 index 000000000000..a7c593f13472 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxc_xml +PRJ=../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/package.html new file mode 100644 index 000000000000..170dfed4ab53 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/package.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.util package</title> +</head> + +<body bgcolor="white"> + +<p><code>Document</code> and <code>PluginFactory</code> implementations +for XML based formats. + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/BookSettings.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/BookSettings.java new file mode 100644 index 000000000000..3643654ca906 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/BookSettings.java @@ -0,0 +1,232 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BookSettings.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.util.Vector; +import java.util.Enumeration; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import java.awt.Point; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.XmlUtil; + +/** + * This is a class representing the different attributes for a worksheet + * contained in settings.xml. + * + * @author Martin Maher + */ +public class BookSettings implements OfficeConstants { + + /** A w3c <code>Document</code>. */ + private org.w3c.dom.Document settings = null; + + private boolean hasColumnRowHeaders = true; + private String activeSheet = new String(); + private Vector worksheetSettings = new Vector(); + + /** + * Default Constructor for a <code>BookSettings</code> + * + * @param dimension if it's a row the height, a column the width + * @param repeated + */ + public BookSettings(Node root) { + readNode(root); + } + + /** + * Default Constructor for a <code>BookSettings</code> + * + * @param worksheetSettings if it's a row the height, a column the width + */ + public BookSettings(Vector worksheetSettings) { + this.worksheetSettings = worksheetSettings; + } + + /** + * + */ + public void setColumnRowHeaders(boolean hasColumnRowHeaders) { + this.hasColumnRowHeaders = hasColumnRowHeaders; + } + + /** + * + */ + public boolean hasColumnRowHeaders() { + return hasColumnRowHeaders; + } + + /** + * Gets the <code>Vector</code> of <code>SheetSettings</code> + * + * @return <code>Vector</code> of <code>SheetSettings</code> + */ + public Vector getSheetSettings() { + return worksheetSettings; + } + + /** + * Gets the active sheet name + * + * @return the active sheet name + */ + public String getActiveSheet() { + + return activeSheet; + } + + /** + * Sets the active sheet name + * + * @param activeSheet the active sheet name + */ + public void setActiveSheet(String activeSheet) { + + this.activeSheet = activeSheet; + } + + + /** + * Adds an XML entry for a particular setting + * + * @param root the root node at which to add the xml entry + * @param attriute the name of the attribute to add + * @param type the attribute type (int, short etc) + * @param value the value of the attribute + */ + private void addConfigItem(Node root, String attribute, String type, String value) { + + Element configItem = settings.createElement(TAG_CONFIG_ITEM); + configItem.setAttribute(ATTRIBUTE_CONFIG_NAME, attribute); + configItem.setAttribute(ATTRIBUTE_CONFIG_TYPE, type); + + configItem.appendChild(settings.createTextNode(value)); + + root.appendChild(configItem); + } + + /** + * Writes out a settings.xml entry for this BookSettings object + * + * @param settings a <code>Document</code> object representing the settings.xml + * @param root the root xml node to add to + */ + public void writeNode(org.w3c.dom.Document settings, Node root) { + + this.settings = settings; + Element configItemMapNamed = (Element) settings.createElement(TAG_CONFIG_ITEM_MAP_NAMED); + configItemMapNamed.setAttribute(ATTRIBUTE_CONFIG_NAME, "Tables"); + for(Enumeration e = worksheetSettings.elements();e.hasMoreElements();) { + SheetSettings s = (SheetSettings) e.nextElement(); + s.writeNode(settings, configItemMapNamed); + } + addConfigItem(root, "ActiveTable", "string", activeSheet); + String booleanValue = Boolean.toString(hasColumnRowHeaders); + addConfigItem(root, "HasColumnRowHeaders", "boolean", booleanValue); + root.appendChild(configItemMapNamed); + } + + /** + * Sets a variable based on a String value read from XML + * + * @param name xml name of the attribute to set + * @param value String value fo the attribute + */ + public void addAttribute(String name, String value) { + + if(name.equals("ActiveTable")) { + activeSheet = value; + } else if(name.equals("HasColumnRowHeaders")) { + Boolean b = Boolean.valueOf(value); + hasColumnRowHeaders = b.booleanValue(); + } + } + + /** + * Reads document settings from xml and inits SheetSettings variables + * + * @param root XML Node to read from + */ + public void readNode(Node root) { + + if (root.hasChildNodes()) { + + NodeList nodeList = root.getChildNodes(); + int len = nodeList.getLength(); + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_CONFIG_ITEM)) { + + NamedNodeMap cellAtt = child.getAttributes(); + + Node configNameNode = + cellAtt.getNamedItem(ATTRIBUTE_CONFIG_NAME); + + String name = configNameNode.getNodeValue(); + NodeList nodeList2 = child.getChildNodes(); + int len2 = nodeList2.getLength(); + String s = ""; + for (int j = 0; j < len2; j++) { + Node child2 = nodeList2.item(j); + if (child2.getNodeType() == Node.TEXT_NODE) { + s = child2.getNodeValue(); + } + } + addAttribute(name, s); + + } else if (nodeName.equals(TAG_CONFIG_ITEM_MAP_NAMED)) { + + readNode(child); + + } else if (nodeName.equals(TAG_CONFIG_ITEM_MAP_ENTRY)) { + + SheetSettings s = new SheetSettings(child); + worksheetSettings.add(s); + + } else { + + Debug.log(Debug.TRACE, "<OTHERS " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/CellStyle.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/CellStyle.java new file mode 100644 index 000000000000..5d4eae4da4b4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/CellStyle.java @@ -0,0 +1,518 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CellStyle.java,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.awt.Color; +import java.io.IOException; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.Style; +import org.openoffice.xmerge.converter.xml.StyleCatalog; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.util.Debug; + +/** + * Represents a text <code>Style</code> in an OpenOffice document. + * + * @author Martin Maher + */ +public class CellStyle extends Style implements Cloneable { + + private Format fmt = new Format(); + + /** + * Constructor for use when going from DOM to client device format. + * + * @param Node The <i>style:style</i> <code>Node</code> containing + * the <code>Style</code>. (This <code>Node</code> is + * assumed have a <i>family</i> attribute of <i>text</i>). + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public CellStyle(Node node, StyleCatalog sc) { + super(node, sc); + + // Run through the attributes of this node, saving + // the ones we're interested in. + NamedNodeMap attrNodes = node.getAttributes(); + if (attrNodes != null) { + int len = attrNodes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attrNodes.item(i); + handleAttribute(attr.getNodeName(), attr.getNodeValue()); + } + } + + // Look for children. Only ones we care about are "style:properties" + // nodes. If any are found, recursively traverse them, passing + // along the style element to add properties to. + if (node.hasChildNodes()) { + NodeList children = node.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++) { + Node child = children.item(i); + String name = child.getNodeName(); + if (name.equals("style:properties")) { + NamedNodeMap childAttrNodes = child.getAttributes(); + if (childAttrNodes != null) { + int nChildAttrNodes = childAttrNodes.getLength(); + for (int j = 0; j < nChildAttrNodes; j++) { + Node attr = childAttrNodes.item(j); + handleAttribute(attr.getNodeName(), + attr.getNodeValue()); + } + } + } + } + } + } + + + /** + * Constructor for use when going from client device format to DOM + * + * @param name Name of cell <code>Style</code>. Can be null. + * @param family Family of text <code>Style</code> (usually + * <i>text</i>). Can be null. + * @param parent Name of parent text <code>Style</code>, or null + * for none. + * @param fmt size in points. + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public CellStyle(String name, String family, String parent,Format fmt, StyleCatalog sc) { + super(name, family, parent, sc); + this.fmt = fmt; + } + + /** + * Returns the <code>Format</code> object for this particular style + * + * @return the <code>Format</code> object + */ + public Format getFormat() { + return fmt; + } + + /** + * Parse a color specification of the form <i>#rrggbb</i> + * + * @param value <code>Color</code> specification to parse. + * + * @return The <code>Color</code> associated the value. + */ + private Color parseColorString(String value) { + // Assume color value is of form #rrggbb + String r = value.substring(1, 3); + String g = value.substring(3, 5); + String b = value.substring(5, 7); + int red = 0; + int green = 0; + int blue = 0; + try { + red = Integer.parseInt(r, 16); + green = Integer.parseInt(g, 16); + blue = Integer.parseInt(b, 16); + } catch (NumberFormatException e) { + Debug.log(Debug.ERROR, "Problem parsing a color string", e); + } + return new Color(red, green, blue, 0); + } + + + /** + * Set an attribute. + * + * @param attr The attribute to set. + * @param value The attribute value to set. + */ + private void handleAttribute(String attr, String value) { + + if (attr.equals("fo:font-weight")) { + fmt.setAttribute(Format.BOLD, value.equals("bold")); + } + + else if (attr.equals("fo:font-style")) { + if (value.equals("italic") || value.equals("oblique")) + fmt.setAttribute(Format.ITALIC, true); + else if (value.equals("normal")) + fmt.setAttribute(Format.ITALIC, false); + } + + else if (attr.equals("style:text-underline")) { + fmt.setAttribute(Format.UNDERLINE, !value.equals("none")); + } + + else if (attr.equals("style:text-crossing-out")) { + fmt.setAttribute(Format.STRIKETHRU, !value.equals("none")); + } + + else if (attr.equals("style:text-position")) { + if (value.startsWith("super ")) + fmt.setAttribute(Format.SUPERSCRIPT, true); + else if (value.startsWith("sub ")) + fmt.setAttribute(Format.SUBSCRIPT, true); + else if (value.startsWith("0% ")) + fmt.setAttribute(Format.SUPERSCRIPT | Format.SUBSCRIPT, false); + else { + String firstPart = value.substring(0, value.indexOf(" ")); + if (firstPart.endsWith("%")) { + firstPart = firstPart.substring(0, value.indexOf("%")); + int amount; + try { + amount = Integer.parseInt(firstPart); + } catch (NumberFormatException e) { + amount = 0; + Debug.log(Debug.ERROR, "Problem with style:text-position tag", e); + } + if (amount < 0) fmt.setAttribute(Format.SUBSCRIPT, true); + else if (amount > 0) fmt.setAttribute(Format.SUPERSCRIPT, false); + } + } + } + + else if (attr.equals("fo:font-size")) { + if (value.endsWith("pt")) { + String num = value.substring(0, value.length() - 2); + fmt.setFontSize(Integer.parseInt(num)); + } + } + + else if (attr.equals("style:font-name")) + fmt.setFontName(value); + + else if (attr.equals("fo:color")) + fmt.setForeground(parseColorString(value)); + + else if (attr.equals("fo:background-color")) + fmt.setBackground(parseColorString(value)); + + else if (attr.equals("fo:text-align")) { + if(value.equals("center")) { + fmt.setAlign(Format.CENTER_ALIGN); + } else if(value.equals("end")) { + fmt.setAlign(Format.RIGHT_ALIGN); + } else if(value.equals("start")) { + fmt.setAlign(Format.LEFT_ALIGN); + } + } + + else if (attr.equals("fo:vertical-align")) { + if(value.equals("top")) { + fmt.setVertAlign(Format.TOP_ALIGN); + } else if(value.equals("middle")) { + fmt.setVertAlign(Format.MIDDLE_ALIGN); + } else if(value.equals("bottom")) { + fmt.setVertAlign(Format.BOTTOM_ALIGN); + } + } + + else if (attr.equals("fo:border")) { + fmt.setAttribute(Format.TOP_BORDER, !value.equals("none")); + fmt.setAttribute(Format.BOTTOM_BORDER, !value.equals("none")); + fmt.setAttribute(Format.LEFT_BORDER, !value.equals("none")); + fmt.setAttribute(Format.RIGHT_BORDER, !value.equals("none")); + } + else if (attr.equals("fo:border-top")) { + fmt.setAttribute(Format.TOP_BORDER, !value.equals("none")); + } + else if (attr.equals("fo:border-bottom")) { + fmt.setAttribute(Format.BOTTOM_BORDER, !value.equals("none")); + } + else if (attr.equals("fo:border-left")) { + fmt.setAttribute(Format.LEFT_BORDER, !value.equals("none")); + } + else if (attr.equals("fo:border-right")) { + fmt.setAttribute(Format.RIGHT_BORDER, !value.equals("none")); + } + else if (attr.equals("fo:wrap-option")) { + fmt.setAttribute(Format.WORD_WRAP, value.equals("wrap")); + } + + else if (isIgnored(attr)) {} + + else { + Debug.log(Debug.INFO, "CellStyle Unhandled: " + attr + "=" + value); + } + } + + + /** + * Return a <code>Style</code> object corresponding to this one, + * but with all of the inherited information from parent + * <code>Style</code> objects filled in. The object returned will + * be a new object, not a reference to this object, even if it does + * not need any information added. + * + * @return The <code>StyleCatalog</code> in which to look up + * ancestors. + */ + public Style getResolved() { + // Create a new object to return, which is a clone of this one. + CellStyle resolved = null; + try { + resolved = (CellStyle)this.clone(); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Can't clone", e); + } + + // Look up the parentStyle. (If there is no style catalog + // specified, we can't do any lookups.) + CellStyle parentStyle = null; + if (sc != null) { + if (parent != null) { + parentStyle = (CellStyle)sc.lookup(parent, family, null, + this.getClass()); + if (parentStyle == null) + Debug.log(Debug.ERROR, "parent style lookup of " + + parent + " failed!"); + else + parentStyle = (CellStyle)parentStyle.getResolved(); + + } else if (!name.equals("DEFAULT_STYLE")) { + parentStyle = (CellStyle)sc.lookup("DEFAULT_STYLE", null, + null, this.getClass()); + } + } + + // If we found a parent, for any attributes which we don't have + // set, try to get the values from the parent. + if (parentStyle != null) { + parentStyle = (CellStyle)parentStyle.getResolved(); + Format parentFormat = parentStyle.getFormat(); + Format resolvedFormat = resolved.getFormat(); + + if ((fmt.getAlign() == Format.LEFT_ALIGN) && (parentFormat.getAlign() != Format.LEFT_ALIGN)) + resolvedFormat.setAlign(parentFormat.getAlign()); + if ((fmt.getVertAlign() == Format.BOTTOM_ALIGN) && (parentFormat.getVertAlign() != Format.BOTTOM_ALIGN)) + resolvedFormat.setVertAlign(parentFormat.getVertAlign()); + if ((fmt.getFontSize() == 0) && (parentFormat.getFontSize() != 0)) + resolvedFormat.setFontSize(parentFormat.getFontSize()); + if ((fmt.getFontName() == null) && (parentFormat.getFontName() != null)) + resolvedFormat.setFontName(parentFormat.getFontName()); + if ((fmt.getForeground() == null) && (parentFormat.getForeground() != null)) + resolvedFormat.setForeground(parentFormat.getForeground()); + if ((fmt.getBackground() == null) && (parentFormat.getBackground() != null)) + resolvedFormat.setBackground(parentFormat.getBackground()); + for (int m = Format.BOLD; m <= Format.SUBSCRIPT; m = m << 1) { + if ((fmt.getAttribute(m)) && (parentFormat.getAttribute(m))) { + resolvedFormat.setAttribute(m, parentFormat.getAttribute(m)); + } + } + + } + return resolved; + } + + + /** + * Create a new <code>Node</code> in the <code>Document</code>, and + * write this <code>Style</code> to it. + * + * @param parentDoc Parent <code>Document</code> of the + * <code>Node</code> to create. + * @param name Name to use for the new <code>Node</code> (e.g. + * <i>style:style</i>) + * + * @return Created <code>Node</code>. + */ + public Node createNode(org.w3c.dom.Document parentDoc, String name) { + Element node = parentDoc.createElement(name); + writeAttributes(node); + return node; + } + + + /** + * Return true if <code>style</code> specifies as much or less + * than this <code>Style</code>, and nothing it specifies + * contradicts this <code>Style</code>. + * + * @param style The <code>Style</code> to check. + * + * @return true if <code>style</code> is a subset, false + * otherwise. + */ + public boolean isSubset(Style style) { + if (style.getClass() != this.getClass()) + return false; + CellStyle tStyle = (CellStyle)style; + + Format rhs = tStyle.getFormat(); + + if(!fmt.isSubset(rhs)) + return false; + + return true; + } + + + /** + * Write this <code>Style</code> object's attributes to a + * <code>Node</code> in the <code>Document</code>. + * + * @param node The <code>Node</code> to add <code>Style</code> + * attributes. + */ + public void writeAttributes(Element node) { + + if (fmt.getAlign()==Format.RIGHT_ALIGN) + node.setAttribute("fo:text-align", "end"); + + if (fmt.getAlign()==Format.LEFT_ALIGN) + node.setAttribute("fo:text-align", "start"); + + if (fmt.getAlign()==Format.CENTER_ALIGN) + node.setAttribute("fo:text-align", "center"); + + if (fmt.getVertAlign()==Format.TOP_ALIGN) + node.setAttribute("fo:vertical-align", "top"); + + if (fmt.getVertAlign()==Format.MIDDLE_ALIGN) + node.setAttribute("fo:vertical-align", "middle"); + + if (fmt.getVertAlign()==Format.BOTTOM_ALIGN) + node.setAttribute("fo:vertical-align", "bottom"); + + if (fmt.getAttribute(Format.BOLD)) + node.setAttribute("fo:font-weight", "bold"); + + if (fmt.getAttribute(Format.ITALIC)) + node.setAttribute("fo:font-style", "italic"); + + if (fmt.getAttribute(Format.UNDERLINE)) + node.setAttribute("style:text-underline", "single"); + + if (fmt.getAttribute(Format.STRIKETHRU)) + node.setAttribute("style:text-crossing-out", "single-line"); + + if (fmt.getAttribute(Format.SUPERSCRIPT)) + node.setAttribute("style:text-position", "super 58%"); + + if (fmt.getAttribute(Format.SUBSCRIPT)) + node.setAttribute("style:text-position", "sub 58%"); + + if (fmt.getFontSize() != 0) { + Integer fs = new Integer(fmt.getFontSize()); + node.setAttribute("fo:font-size", fs.toString() + "pt"); + } + + if (fmt.getFontName() != null) + node.setAttribute("style:font-name", fmt.getFontName()); + + if (fmt.getForeground() != null) + node.setAttribute("fo:color", buildColorString(fmt.getForeground())); + + if (fmt.getBackground() != null) + node.setAttribute("fo:background-color", + buildColorString(fmt.getBackground())); + + if (fmt.getAttribute(Format.TOP_BORDER)) + node.setAttribute("fo:border-top", "0.0008inch solid #000000"); + + if (fmt.getAttribute(Format.BOTTOM_BORDER)) + node.setAttribute("fo:border-bottom", "0.0008inch solid #000000"); + + if (fmt.getAttribute(Format.RIGHT_BORDER)) + node.setAttribute("fo:border-right", "0.0008inch solid #000000"); + + if (fmt.getAttribute(Format.LEFT_BORDER)) + node.setAttribute("fo:border-left", "0.0008inch solid #000000"); + + if (fmt.getAttribute(Format.WORD_WRAP)) + node.setAttribute("fo:wrap-option", "wrap"); + + } + + + /** + * Given a <code>Color</code>, return a string of the form + * <i>#rrggbb</i>. + * + * @param c The <code>Color</code> value. + * + * @return The <code>Color</code> value in the form <i>#rrggbb</i>. + */ + private String buildColorString(Color c) { + int v[] = new int[3]; + v[0] = c.getRed(); + v[1] = c.getGreen(); + v[2] = c.getBlue(); + String colorString = new String("#"); + for (int i = 0; i <= 2; i++) { + String xx = Integer.toHexString(v[i]); + if (xx.length() < 2) + xx = "0" + xx; + colorString += xx; + } + return colorString; + } + + + private static String[] ignored = { + "style:text-autospace", "style:text-underline-color", + "fo:margin-left", "fo:margin-right", "fo:text-indent", + "fo:margin-top", "fo:margin-bottom", "text:line-number", + "text:number-lines", "style:country-asian", + "style:font-size-asian", "style:font-name-complex", + "style:language-complex", "style:country-complex", + "style:font-size-complex", "style:punctuation-wrap", + "fo:language", "fo:country", + "style:font-name-asian", "style:language-asian", + "style:line-break", "fo:keep-with-next" + }; + + + /* + * This code checks whether an attribute is one that we + * intentionally ignore. + * + * @param attribute The attribute to check. + * + * @return true if <code>attribute</code> can be ignored, + * otherwise false. + */ + private boolean isIgnored(String attribute) { + for (int i = 0; i < ignored.length; i++) { + if (ignored[i].equals(attribute)) + return true; + } + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/ColumnRowInfo.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/ColumnRowInfo.java new file mode 100644 index 000000000000..a179633de71c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/ColumnRowInfo.java @@ -0,0 +1,198 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ColumnRowInfo.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +/** + * This is a class to define a table-column structure. This can then be + * used by plugins to write or read their own column types. + * + * @author Martin Maher + */ +public class ColumnRowInfo { + + final public static int COLUMN = 0x01; + final public static int ROW = 0x02; + + final private static int DEFAULTROWSIZE_MIN = 250; + final private static int DEFAULTROWSIZE_MAX = 260; + + private int type; + private int dimension = 0; + private int repeated = 1; + private boolean userDefined = true; + private Format fmt = new Format(); + + /** + * Constructor for a <code>ColumnRowInfo</code> + * + * @param dimension if it's a row the height, a column the width + * @param repeated + */ + public ColumnRowInfo(int type) { + + this.type = type; + } + + /** + * Constructor for a <code>ColumnRowInfo</code> + * + * @param dimension if it's a row the height, a column the width + * @param repeated how many times it is repeated + * @param type whether Row or column record + */ + public ColumnRowInfo(int dimension, int repeated, int type) { + + this.dimension = dimension; + this.repeated = repeated; + this.type = type; + } + + /** + * Constructor that includes userDefined field + * + * @param userDefined whether the record is manually set + */ + public ColumnRowInfo(int dimension, int repeated, int type, boolean userDefined) { + + this(dimension, repeated, type); + this.userDefined = userDefined; + } + + /** + * sets the definition + * + * @param newDefinition sets the definition + */ + public void setFormat(Format fmt) { + + this.fmt = fmt; + } + + /** + * returns Name of the definition + * + * @return the name which identifies the definition + */ + public Format getFormat() { + + return fmt; + } + + /** + * returns Name of the definition + * + * @return the name which identifies the definition + */ + public int getSize() { + + return dimension; + } + + /** + * sets the definition + * + * @param newDefinition sets the definition + */ + public void setSize(int dimension) { + + this.dimension = dimension; + } + /** + * Returns the definition itself + * + * @return the definition + */ + public int getRepeated() { + + return repeated; + } + + /** + * Returns the base Cell address + * + * @return the base cell address + */ + public void setRepeated(int repeated) { + + this.repeated = repeated; + } + + /** + * Returns the definition itself + * + * @return the definition + */ + public boolean isRow() { + + if(type==ROW) + return true; + else + return false; + } + + /** + * Returns the base Cell address + * + * @return the base cell address + */ + public boolean isColumn() { + + if(type==COLUMN) + return true; + else + return false; + } + + /** + * Test if the row height as been set manually + * + * @return true if user defined otherwise false + */ + public boolean isUserDefined() { + + return userDefined; + } + + /** + * Test if the row height is default + * + * @return true if default otherwise false + */ + public boolean isDefaultSize() { + + if( type==ROW && + dimension>DEFAULTROWSIZE_MIN && + dimension<DEFAULTROWSIZE_MAX) + return true; + else + return false; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/ColumnStyle.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/ColumnStyle.java new file mode 100644 index 000000000000..2b9c169ff352 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/ColumnStyle.java @@ -0,0 +1,309 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ColumnStyle.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.awt.Color; +import java.io.IOException; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.Style; +import org.openoffice.xmerge.converter.xml.StyleCatalog; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.TwipsConverter; + +/** + * Represents a text <code>Style</code> in an OpenOffice document. + * + * @author Martin Maher + */ +public class ColumnStyle extends Style implements Cloneable { + + private int colWidth = 0; + /** + * Constructor for use when going from DOM to client device format. + * + * @param Node The <i>style:style</i> <code>Node</code> containing + * the <code>Style</code>. (This <code>Node</code> is + * assumed have a <i>family</i> attribute of <i>text</i>). + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public ColumnStyle(Node node, StyleCatalog sc) { + super(node, sc); + + // Run through the attributes of this node, saving + // the ones we're interested in. + NamedNodeMap attrNodes = node.getAttributes(); + if (attrNodes != null) { + int len = attrNodes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attrNodes.item(i); + handleAttribute(attr.getNodeName(), attr.getNodeValue()); + } + } + + // Look for children. Only ones we care about are "style:properties" + // nodes. If any are found, recursively traverse them, passing + // along the style element to add properties to. + if (node.hasChildNodes()) { + NodeList children = node.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++) { + Node child = children.item(i); + String name = child.getNodeName(); + if (name.equals("style:properties")) { + NamedNodeMap childAttrNodes = child.getAttributes(); + if (childAttrNodes != null) { + int nChildAttrNodes = childAttrNodes.getLength(); + for (int j = 0; j < nChildAttrNodes; j++) { + Node attr = childAttrNodes.item(j); + handleAttribute(attr.getNodeName(), + attr.getNodeValue()); + } + } + } + } + } + } + + + /** + * Constructor for use when going from client device format to DOM + * + * @param name Name of text <code>Style</code>. Can be null. + * @param family Family of text <code>Style</code> (usually + * <i>text</i>). Can be null. + * @param parent Name of parent text <code>Style</code>, or null + * for none. + * @param mask the width of this column + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public ColumnStyle(String name, String family, String parent,int colWidth, StyleCatalog sc) { + super(name, family, parent, sc); + this.colWidth = colWidth; + } + + /** + * Returns the width of this column + * + * @return the <code>Format</code> object + */ + public int getColWidth() { + return colWidth; + } + + /** + * Sets the width of this column + * + * @return the <code>Format</code> object + */ + public void setColWidth(int colWidth) { + + this.colWidth = colWidth; + } + + /** + * Parse a colwidth in the form "1.234cm" to twips + * + * @param value <code>String</code> specification to parse. + * + * @return The twips equivalent. + */ + private int parseColWidth(String value) { + + int width = 255; // Default value + + if(value.indexOf("cm")!=-1) { + float widthCM = Float.parseFloat(value.substring(0,value.indexOf("c"))); + width = TwipsConverter.cm2twips(widthCM); + } else if(value.indexOf("inch")!=-1) { + float widthInch = Float.parseFloat(value.substring(0,value.indexOf("i"))); + width = TwipsConverter.inches2twips(widthInch); + } + + return (width); + } + + + /** + * Set an attribute. + * + * @param attr The attribute to set. + * @param value The attribute value to set. + */ + private void handleAttribute(String attr, String value) { + + if (attr.equals("style:column-width")) { + colWidth = parseColWidth(value); + } + else { + Debug.log(Debug.INFO, "ColumnStyle Unhandled: " + attr + "=" + value); + } + } + + + /** + * Return a <code>Style</code> object corresponding to this one, + * but with all of the inherited information from parent + * <code>Style</code> objects filled in. The object returned will + * be a new object, not a reference to this object, even if it does + * not need any information added. + * + * @return The <code>StyleCatalog</code> in which to look up + * ancestors. + */ + public Style getResolved() { + // Create a new object to return, which is a clone of this one. + ColumnStyle resolved = null; + try { + resolved = (ColumnStyle)this.clone(); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Can't clone", e); + } + + // Look up the parentStyle. (If there is no style catalog + // specified, we can't do any lookups.) + ColumnStyle parentStyle = null; + if (sc != null) { + if (parent != null) { + parentStyle = (ColumnStyle)sc.lookup(parent, family, null, + this.getClass()); + if (parentStyle == null) + Debug.log(Debug.ERROR, "parent style lookup of " + + parent + " failed!"); + else + parentStyle = (ColumnStyle)parentStyle.getResolved(); + + } else if (!name.equals("DEFAULT_STYLE")) { + parentStyle = (ColumnStyle)sc.lookup("DEFAULT_STYLE", null, + null, this.getClass()); + } + } + + // If we found a parent, for any attributes which we don't have + // set, try to get the values from the parent. + if (parentStyle != null) { + parentStyle = (ColumnStyle)parentStyle.getResolved(); + + if ((colWidth == 0) && (parentStyle.getColWidth() != 0)) + resolved.setColWidth(parentStyle.getColWidth()); + } + return resolved; + } + + + /** + * Create a new <code>Node</code> in the <code>Document</code>, and + * write this <code>Style</code> to it. + * + * @param parentDoc Parent <code>Document</code> of the + * <code>Node</code> to create. + * @param name Name to use for the new <code>Node</code> (e.g. + * <i>style:style</i>) + * + * @return Created <code>Node</code>. + */ + public Node createNode(org.w3c.dom.Document parentDoc, String name) { + Element node = parentDoc.createElement(name); + writeAttributes(node); + return node; + } + + + /** + * Return true if <code>style</code> specifies as much or less + * than this <code>Style</code>, and nothing it specifies + * contradicts this <code>Style</code>. + * + * @param style The <code>Style</code> to check. + * + * @return true if <code>style</code> is a subset, false + * otherwise. + */ + public boolean isSubset(Style style) { + if (style.getClass() != this.getClass()) + return false; + ColumnStyle tStyle = (ColumnStyle)style; + + if(colWidth!=tStyle.getColWidth()) + return false; + + return true; + } + + + /** + * Write this <code>Style</code> object's attributes to a + * <code>Node</code> in the <code>Document</code>. + * + * @param node The <code>Node</code> to add <code>Style</code> + * attributes. + */ + public void writeAttributes(Element node) { + + if(colWidth!=0) { + String width = TwipsConverter.twips2cm(colWidth) + "cm"; + node.setAttribute("style:column-width", width); + } + } + + + private static String[] ignored = { + "fo:break-before", "fo:keep-with-next" + }; + + + /* + * This code checks whether an attribute is one that we + * intentionally ignore. + * + * @param attribute The attribute to check. + * + * @return true if <code>attribute</code> can be ignored, + * otherwise false. + */ + private boolean isIgnored(String attribute) { + for (int i = 0; i < ignored.length; i++) { + if (ignored[i].equals(attribute)) + return true; + } + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/DocumentMergerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/DocumentMergerImpl.java new file mode 100644 index 000000000000..3ae4f16acfcf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/DocumentMergerImpl.java @@ -0,0 +1,202 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentMergerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.MergeException; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.Difference; +import org.openoffice.xmerge.merger.Iterator; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.NodeMergeAlgorithm; +import org.openoffice.xmerge.merger.diff.IteratorRowCompare; +import org.openoffice.xmerge.merger.diff.RowIterator; +import org.openoffice.xmerge.merger.merge.SheetMerge; +import org.openoffice.xmerge.merger.merge.PositionBaseRowMerge; +import org.openoffice.xmerge.merger.MergeAlgorithm; +import org.openoffice.xmerge.util.XmlUtil; +import org.openoffice.xmerge.util.Debug; + + +/** + * Generic small device implementation of <code>DocumentMerger</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcPluginFactory + * SxcPluginFactory}. Used with SXC <code>Document</code> objects.</p> + */ +public class DocumentMergerImpl implements DocumentMerger { + + private ConverterCapabilities cc_; + private org.openoffice.xmerge.Document orig = null; + + /** + * Constructor + * + * @param doc The original "Office" <code>Document</code> + * to merge. + * @param cc The <code>ConverterCapabilities</code>. + */ + public DocumentMergerImpl(org.openoffice.xmerge.Document doc, ConverterCapabilities cc) { + cc_ = cc; + this.orig = doc; + } + + public void merge(Document modifiedDoc) throws MergeException { + + SxcDocument sdoc1 = (SxcDocument)orig; + SxcDocument sdoc2 = (SxcDocument)modifiedDoc; + + org.w3c.dom.Document doc1 = sdoc1.getContentDOM(); + org.w3c.dom.Document doc2 = sdoc2.getContentDOM(); + + Element elem1 = doc1.getDocumentElement(); + Element elem2 = doc2.getDocumentElement(); + + // get table name + NodeList workSheetList1 = + elem1.getElementsByTagName(OfficeConstants.TAG_TABLE); + NodeList workSheetList2 = + elem2.getElementsByTagName(OfficeConstants.TAG_TABLE); + + int numOfWorkSheet = workSheetList1.getLength(); + + for (int i=0; i < numOfWorkSheet; i++) { + Node workSheet = workSheetList1.item(i); + + // try to match the workSheet + Node matchingWorkSheet = matchWorkSheet(workSheet, workSheetList2); + + if (matchingWorkSheet != null) { + + // need to put it into a row Iterator + // use a straight comparsion algorithm then do a merge on it + Iterator i1 = new RowIterator(cc_, workSheet); + Iterator i2 = new RowIterator(cc_, matchingWorkSheet); + + // find out the diff + DiffAlgorithm diffAlgo = new IteratorRowCompare(); + + // find out the paragrah level diffs + Difference[] diffResult = diffAlgo.computeDiffs(i1, i2); + + if (Debug.isFlagSet(Debug.INFO)) { + Debug.log(Debug.INFO, "Diff Result: "); + + for (int j = 0; j < diffResult.length; j++) { + Debug.log(Debug.INFO, diffResult[j].debug()); + } + } + + // merge back the result + NodeMergeAlgorithm rowMerger = new PositionBaseRowMerge(cc_); + MergeAlgorithm merger = new SheetMerge(cc_, rowMerger); + + Iterator result = null; + + merger.applyDifference(i1, i2, diffResult); + } + } + + numOfWorkSheet = workSheetList2.getLength(); + + // for those workSheet from target don't have a matching one + // in the original workSheet list, we add it + + // find out the office body node first + NodeList officeBodyList = + elem1.getElementsByTagName(OfficeConstants.TAG_OFFICE_BODY); + + Node officeBody = officeBodyList.item(0); + + // for each WorkSheets, try to see whether we have it or not + for (int j=0; j < numOfWorkSheet; j++) { + Node workSheet= workSheetList2.item(j); + + // try to match the workSheet + // + Node matchingWorkSheet = matchWorkSheet(workSheet, workSheetList1); + + // add the new WorkSheet to the original document iff match not + // found + // + if (matchingWorkSheet == null) { + Node cloneNode = XmlUtil.deepClone(officeBody, workSheet); + officeBody.appendChild(cloneNode); + } + } + } + + /** + * Try to find a WorkSheet from the modified WorkSheetList that + * has a matching table name from the original WorkSheet. + * + * @param orgSheet The original WorkSheet. + * @param modSheetList The modified WorkSheet. + * + * @return The Node in modSheetList that matches the orgSheet. + */ + private Node matchWorkSheet(Node orgSheet, NodeList modSheetList) { + + Node matchSheet = null; + + String orgTableName = ((Element)orgSheet).getAttribute( + OfficeConstants.ATTRIBUTE_TABLE_NAME); + + if (orgTableName == null) + return null; + + int numOfWorkSheet = modSheetList.getLength(); + + String modTableName; + + for (int i=0; i < numOfWorkSheet; i++) { + modTableName = ((Element)modSheetList.item(i)).getAttribute( + OfficeConstants.ATTRIBUTE_TABLE_NAME); + if (modTableName == null) + continue; + + if (orgTableName.equals(modTableName)) { + matchSheet = modSheetList.item(i); + break; + } + } + + return matchSheet; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/Format.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/Format.java new file mode 100644 index 000000000000..8e58ea0dd968 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/Format.java @@ -0,0 +1,480 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Format.java,v $ + * $Revision: 1.13 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.awt.Color; + +import org.openoffice.xmerge.util.Debug; + +/** + * This class specifies the format for a given spreadsheet cell. + * + * @author Mark Murnane + * @author Martin Maher (Extended Style Support) + */ +public class Format implements Cloneable { + + /** Horizontal Alignment Constants. */ + final public static int RIGHT_ALIGN = 0x01; + final public static int CENTER_ALIGN = 0x02; + final public static int LEFT_ALIGN = 0x03; + final public static int JUST_ALIGN = 0x04; + + /** Vertical Alignment Constants. */ + final public static int TOP_ALIGN = 0x01; + final public static int MIDDLE_ALIGN = 0x02; + final public static int BOTTOM_ALIGN = 0x03; + + /** Indicates <i>bold</i> text. */ + final public static int BOLD = 0x01; + /** Indicates <i>italic</i> text. */ + final public static int ITALIC = 0x02; + /** Indicates <i>underlined</i> text. */ + final public static int UNDERLINE = 0x04; + /** Indicates <i>strike-through</i> in the text. */ + final public static int STRIKETHRU = 0x08; + /** Indicates <i>superscripted</i> text. */ + final public static int SUPERSCRIPT = 0x10; + /** Indicates <i>subscripted</i> text. */ + final public static int SUBSCRIPT = 0x20; + + final public static int LEFT_BORDER = 0x40; + final public static int RIGHT_BORDER = 0x80; + final public static int TOP_BORDER = 0x100; + final public static int BOTTOM_BORDER = 0x200; + + final public static int WORD_WRAP = 0x400; + + private int align; + private int vertAlign; + private String category; + private String value; + private String formatSpecifier; + private int decimalPlaces; + + /** Font name. */ + private String fontName; + /** Font size in points. */ + protected int sizeInPoints; + + private Color foreground, background; + + /** Values of text attributes. */ + protected int attributes = 0; + /** Bitwise mask of text attributes. */ + protected int mask = 0; + + /** + * Constructor for creating a new <code>Format</code>. + */ + public Format() { + clearFormatting(); + } + + /** + * Constructor that creates a new <code>Format</code> object + * by setting all the format attributes. + * + */ + public Format(int attributes, int fontSize, String fontName) { + + this.attributes = attributes; + sizeInPoints = fontSize; + this.fontName = fontName; + } + + /** + * Constructor for creating a new <code>Format</code> object + * based on an existing one. + * + * @param fmt <code>Format</code> to copy. + */ + public Format(Format fmt) { + category = fmt.getCategory(); + value = fmt.getValue(); + formatSpecifier = fmt.getFormatSpecifier(); + decimalPlaces = fmt.getDecimalPlaces(); + + attributes = fmt.attributes; + mask = fmt.mask; + + fontName = fmt.getFontName(); + align = fmt.getAlign(); + vertAlign = fmt.getVertAlign(); + foreground = fmt.getForeground(); + background = fmt.getBackground(); + sizeInPoints = fmt.sizeInPoints; + } + + + /** + * Reset this <code>Format</code> description. + */ + public void clearFormatting() { + category = ""; + value = ""; + formatSpecifier = ""; + decimalPlaces = 0; + attributes = 0; + mask = 0; + sizeInPoints = 10; + align = LEFT_ALIGN; + vertAlign = BOTTOM_ALIGN; + fontName = ""; + foreground = null; + background = null; + } + + /** + * Set one or more text attributes to <i>on</i>. + * + * @param flags Flag attributes to set <i>on</i>. + */ + public void setAttribute(int flags, boolean toggle) { + mask |= flags; + if(toggle) { + attributes |= flags; + } else { + attributes &= ~flags; + } + } + + /** + * Return true if the <code>attribute</code> is set to <i>on</i> + * + * @param attribute Attribute to check ({@link #BOLD}, + * {@link #ITALIC}, etc.) + * + * @return true if <code>attribute</code> is set to <i>on</i>, + * otherwise false. + */ + public boolean getAttribute(int attribute) { + if ((mask & attribute) == 0) + return false; + return (!((attributes & attribute) == 0)); + } + + /** + * Return true if text <code>attribute</code> is set in this + * <code>Style</code>.An attribute that is set may have a + * value of <i>on</i> or <i>off</i>. + * + * @param attribute The attribute to check ({@link #BOLD}, + * {@link #ITALIC}, etc.). + * + * @return true if text <code>attribute</code> is set in this + * <code>Style</code>, false otherwise. + */ + public boolean isSet(int attribute) { + return (!((mask & attribute) == 0)); + } + + + /** + * Set the formatting category of this object, ie number, date, + * currency.The <code>OfficeConstants</code> class contains string + * constants for the category types. + * + * @see org.openoffice.xmerge.converter.xml.OfficeConstants + * + * @param newCategory The name of the category to be set. + */ + public void setCategory(String newCategory) { + category = newCategory; + } + + /** + * Return the formatting category of the object. + * + * @see org.openoffice.xmerge.converter.xml.OfficeConstants + * + * @return The formatting category of the object. + */ + public String getCategory() { + return category; + } + + /** + * In the case of Formula returns the value of the formula. + * + * @return The value of the formula + */ + public String getValue() { + return value; + } + + /** + * In the case of formula the contents are set as the formula string and + * the value of the formula is a formatting attribute. + * + * @param newValue the formuala value + */ + public void setValue(String newValue) { + value = newValue; + } + + + /** + * Set the <code>Format</code> specifier for this category. + * + * @param formatString The new <code>Format</code> specifier. + */ + public void setFormatSpecifier(String formatString) { + formatSpecifier = formatString; + } + + + /** + * Get the <code>Format</code> specifier for this category. + * + * @return <code>Format</code> specifier for this category. + */ + public String getFormatSpecifier() { + return formatSpecifier; + } + + + /** + * Set the precision of the number to be displayed. + * + * @param precision The number of decimal places to display. + */ + public void setDecimalPlaces(int precision) { + decimalPlaces = precision; + } + + + /** + * Get the number of decimal places displayed. + * + * @return Number of decimal places. + */ + public int getDecimalPlaces() { + return decimalPlaces; + } + + + /** + * Set the font used for this cell. + * + * @param fontName The name of the font. + */ + public void setFontName(String fontName) { + this.fontName = fontName; + } + + + /** + * Get the font used for this cell. + * + * @return The font name. + */ + public String getFontName() { + return fontName; + } + + /** + * Set the font used for this cell. + * + * @param fontName The name of the font. + */ + public void setFontSize(int fontSize) { + sizeInPoints = fontSize; + } + + + /** + * Get the font used for this cell. + * + * @return The font name. + */ + public int getFontSize() { + return sizeInPoints; + } + + /** + * Set the alignmen used for this cell. + * + * @param fontName The name of the font. + */ + public void setVertAlign(int vertAlign) { + this.vertAlign = vertAlign; + } + + + /** + * Get the alignment used for this cell. + * + * @return The font name. + */ + public int getVertAlign() { + return vertAlign; + } + + /** + * Set the alignmen used for this cell. + * + * @param fontName The name of the font. + */ + public void setAlign(int align) { + this.align = align; + } + + + /** + * Get the alignment used for this cell. + * + * @return The font name. + */ + public int getAlign() { + return align; + } + /** + * Set the Foreground <code>Color</code> for this cell. + * + * @param color A <code>Color</code> object representing the + * foreground color. + */ + public void setForeground(Color c) { + if(c!=null) + foreground = new Color(c.getRGB()); + } + + + /** + * Get the Foreground <code>Color</code> for this cell. + * + * @return Foreground <code>Color</code> value. + */ + public Color getForeground() { + return foreground; + } + + + /** + * Set the Background <code>Color</code> for this cell + * + * @param color A <code>Color</code> object representing + * the background color. + */ + public void setBackground(Color c) { + if(c!=null) + background = new Color(c.getRGB()); + } + + + /** + * Get the Foreground <code>Color</code> for this cell + * + * @return Background <code>Color</code> value + */ + public Color getBackground() { + return background; + } + + /** + * Get the Foreground <code>Color</code> for this cell + * + * @return Background <code>Color</code> value + */ + public String toString() { + return new String("Value : " + getValue() + " Category : " + getCategory()); + } + + /** + * Tests if the current <code>Format</code> object has default attribute + * values. + * + * @return true if it contains default value + */ + public boolean isDefault() { + + Format rhs = new Format(); + + if (rhs.attributes!= attributes) + return false; + + if (foreground!=rhs.foreground) + return false; + + if (background!=rhs.background) + return false; + + if (rhs.align!= align) + return false; + + if (rhs.vertAlign!= vertAlign) + return false; + + return true; + } + + /** + * Return true if <code>style</code> specifies as much or less + * than this <code>Style</code>, and nothing it specifies + * contradicts this <code>Style</code>. + * + * @param style The <code>Style</code> to check. + * + * @return true if <code>style</code> is a subset, false + * otherwise. + */ + public boolean isSubset(Format rhs) { + if (rhs.getClass() != this.getClass()) + return false; + + if (rhs.attributes!= attributes) + return false; + + if (rhs.sizeInPoints != 0) { + if (sizeInPoints != rhs.sizeInPoints) + return false; + } + + if (fontName!=rhs.fontName) + return false; + + if (foreground!=rhs.foreground) + return false; + + if (background!=rhs.background) + return false; + + if (rhs.align!= align) + return false; + + if (rhs.vertAlign!= vertAlign) + return false; + + return true; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/NameDefinition.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/NameDefinition.java new file mode 100644 index 000000000000..65f0979c4ed2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/NameDefinition.java @@ -0,0 +1,219 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: NameDefinition.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.XmlUtil; + +/** + * This is a class to define a Name Definition structure. This can then be + * used by plugins to write or read their own definition types. + * + * @author Martin Maher + */ +public class NameDefinition implements OfficeConstants { + + private String name; // name which identifies the definition + private String definition; // the definition itself + private String baseCellAddress; // the basecelladdress + private boolean rangeType = false; // true if definition of type range + private boolean expressionType = false; // true if definition of type expression + + /** + * Default Constructor for a <code>NameDefinition</code> + * + */ + public NameDefinition() { + + } + + /** + * Constructor that takes a <code>Node</code> to build a + * <code>NameDefinition</code> + * + * @param root XML Node to read from + */ + public NameDefinition(Node root) { + readNode(root); + } + + /** + * Default Constructor for a <code>NameDefinition</code> + * + */ + public NameDefinition(String name, String definition, String + baseCellAddress, boolean rangeType, boolean expressionType ) { + this.name = name; + this.definition = definition; + this.baseCellAddress = baseCellAddress; + this.rangeType = rangeType; + this.expressionType = expressionType; + } + + /** + * returns Name of the definition + * + * @return the name which identifies the definition + */ + public String getName() { + + return name; + } + /** + * sets the definition + * + * @param newDefinition sets the definition + */ + public void setDefinition(String newDefinition) { + + definition = newDefinition; + } + /** + * Returns the definition itself + * + * @return the definition + */ + public String getDefinition() { + + return definition; + } + + /** + * Returns the base Cell address + * + * @return the base cell address + */ + public String getBaseCellAddress() { + + return baseCellAddress; + } + + /** + * Tests if definition is of type expression + * + * @return whether or not this name definition is of type expression + */ + public boolean isExpressionType() { + return expressionType; + } + + /** + * Tests if definition is of type range + * + * @return whether or not this name definition is of type range + */ + public boolean isRangeType() { + return rangeType; + } + + /** + * Writes out a content.xml entry for this NameDefinition object + * + * @param settings a <code>Document</code> object representing the settings.xml + * @param root the root xml node to add to + */ + public void writeNode(org.w3c.dom.Document doc, Node root) { + + if(isRangeType()) { + + Debug.log(Debug.TRACE, "Found Range Name : " + getName()); + Element namedRangeElement = (Element) doc.createElement(TAG_TABLE_NAMED_RANGE); + namedRangeElement.setAttribute(ATTRIBUTE_TABLE_NAME, getName()); + namedRangeElement.setAttribute(ATTRIBUTE_TABLE_BASE_CELL_ADDRESS, getBaseCellAddress()); + namedRangeElement.setAttribute(ATTRIBUTE_TABLE_CELL_RANGE_ADDRESS, getDefinition()); + root.appendChild(namedRangeElement); + } else if (isExpressionType()) { + + Debug.log(Debug.TRACE, "Found Expression Name : " + getName()); + Element namedExpressionElement = (Element) doc.createElement(TAG_TABLE_NAMED_EXPRESSION); + namedExpressionElement.setAttribute(ATTRIBUTE_TABLE_NAME, getName()); + namedExpressionElement.setAttribute(ATTRIBUTE_TABLE_BASE_CELL_ADDRESS,getBaseCellAddress()); + namedExpressionElement.setAttribute(ATTRIBUTE_TABLE_EXPRESSION, getDefinition()); + root.appendChild(namedExpressionElement); + } else { + + Debug.log(Debug.TRACE, "Unknown Name Definition : " + getName()); + } + } + + /** + * Reads document settings from xml and inits Settings variables + * + * @param root XML Node to read from + */ + public void readNode(Node root) { + + String nodeName = root.getNodeName(); + NamedNodeMap cellAtt = root.getAttributes(); + + if (nodeName.equals(TAG_TABLE_NAMED_RANGE)) { + + Node tableNameNode = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_NAME); + Node tableBaseCellAddress = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_BASE_CELL_ADDRESS); + Node tableCellRangeAddress = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_CELL_RANGE_ADDRESS); + Debug.log(Debug.TRACE,"Named-range : " + tableNameNode.getNodeValue()); + // Create a named-range name definition + name = tableNameNode.getNodeValue(); + definition = tableCellRangeAddress.getNodeValue(); + baseCellAddress = tableBaseCellAddress.getNodeValue(); + expressionType = true; + rangeType = false; + + } else if (nodeName.equals(TAG_TABLE_NAMED_EXPRESSION)) { + + Node tableNameNode = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_NAME); + Node tableBaseCellAddress = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_BASE_CELL_ADDRESS); + Node tableExpression= + cellAtt.getNamedItem(ATTRIBUTE_TABLE_EXPRESSION); + Debug.log(Debug.TRACE,"Named-expression: " + tableNameNode.getNodeValue()); + // Create a named-range name definition + name = tableNameNode.getNodeValue(); + definition = tableExpression.getNodeValue(); + baseCellAddress = tableBaseCellAddress.getNodeValue(); + expressionType = false; + rangeType = true; + } else { + Debug.log(Debug.TRACE, "<OTHERS " + XmlUtil.getNodeInfo(root) + " />"); + } + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/RowStyle.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/RowStyle.java new file mode 100644 index 000000000000..71839e238d43 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/RowStyle.java @@ -0,0 +1,308 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: RowStyle.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.io.IOException; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.Style; +import org.openoffice.xmerge.converter.xml.StyleCatalog; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.TwipsConverter; + +/** + * Represents a text <code>Style</code> in an OpenOffice document. + * + * @author Martin Maher + */ +public class RowStyle extends Style implements Cloneable { + + private int rowHeight = 255; + /** + * Constructor for use when going from DOM to client device format. + * + * @param Node The <i>style:style</i> <code>Node</code> containing + * the <code>Style</code>. (This <code>Node</code> is + * assumed have a <i>family</i> attribute of <i>text</i>). + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public RowStyle(Node node, StyleCatalog sc) { + super(node, sc); + + // Run through the attributes of this node, saving + // the ones we're interested in. + NamedNodeMap attrNodes = node.getAttributes(); + if (attrNodes != null) { + int len = attrNodes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attrNodes.item(i); + handleAttribute(attr.getNodeName(), attr.getNodeValue()); + } + } + + // Look for children. Only ones we care about are "style:properties" + // nodes. If any are found, recursively traverse them, passing + // along the style element to add properties to. + if (node.hasChildNodes()) { + NodeList children = node.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++) { + Node child = children.item(i); + String name = child.getNodeName(); + if (name.equals("style:properties")) { + NamedNodeMap childAttrNodes = child.getAttributes(); + if (childAttrNodes != null) { + int nChildAttrNodes = childAttrNodes.getLength(); + for (int j = 0; j < nChildAttrNodes; j++) { + Node attr = childAttrNodes.item(j); + handleAttribute(attr.getNodeName(), + attr.getNodeValue()); + } + } + } + } + } + } + + + /** + * Constructor for use when going from client device format to DOM + * + * @param name Name of text <code>Style</code>. Can be null. + * @param family Family of text <code>Style</code> (usually + * <i>text</i>). Can be null. + * @param parent Name of parent text <code>Style</code>, or null + * for none. + * @param mask The height of this row + * @param sc The <code>StyleCatalog</code>, which is used for + * looking up ancestor <code>Style</code> objects. + */ + public RowStyle(String name, String family, String parent,int rowHeight, StyleCatalog sc) { + super(name, family, parent, sc); + this.rowHeight=rowHeight; + } + + /** + * Returns the height of this row + * + * @return the <code>Format</code> object + */ + public int getRowHeight() { + return rowHeight; + } + + /** + * Sets the height of this row + * + * @return the <code>Format</code> object + */ + public void setRowHeight(int RowHeight) { + + this.rowHeight = rowHeight; + } + /** + * Parse a colheight in the form "1.234cm" to twips + * + * @param value <code>String</code> specification to parse. + * + * @return The twips equivalent. + */ + private int parseRowHeight(String value) { + + int height = 255; // Default value + + if(value.indexOf("cm")!=-1) { + float heightCM = Float.parseFloat(value.substring(0,value.indexOf("c"))); + height = TwipsConverter.cm2twips(heightCM); + } else if(value.indexOf("inch")!=-1) { + float heightInch = Float.parseFloat(value.substring(0,value.indexOf("i"))); + height = TwipsConverter.inches2twips(heightInch); + } + + return (height); + + } + + + /** + * Set an attribute. + * + * @param attr The attribute to set. + * @param value The attribute value to set. + */ + private void handleAttribute(String attr, String value) { + + if (attr.equals("style:row-height")) { + rowHeight = parseRowHeight(value); + } + else { + Debug.log(Debug.INFO, "RowStyle Unhandled: " + attr + "=" + value); + } + } + + + /** + * Return a <code>Style</code> object corresponding to this one, + * but with all of the inherited information from parent + * <code>Style</code> objects filled in. The object returned will + * be a new object, not a reference to this object, even if it does + * not need any information added. + * + * @return The <code>StyleCatalog</code> in which to look up + * ancestors. + */ + public Style getResolved() { + // Create a new object to return, which is a clone of this one. + RowStyle resolved = null; + try { + resolved = (RowStyle)this.clone(); + } catch (Exception e) { + Debug.log(Debug.ERROR, "Can't clone", e); + } + + // Look up the parentStyle. (If there is no style catalog + // specified, we can't do any lookups.) + RowStyle parentStyle = null; + if (sc != null) { + if (parent != null) { + parentStyle = (RowStyle)sc.lookup(parent, family, null, + this.getClass()); + if (parentStyle == null) + Debug.log(Debug.ERROR, "parent style lookup of " + + parent + " failed!"); + else + parentStyle = (RowStyle)parentStyle.getResolved(); + + } else if (!name.equals("DEFAULT_STYLE")) { + parentStyle = (RowStyle)sc.lookup("DEFAULT_STYLE", null, + null, this.getClass()); + } + } + + // If we found a parent, for any attributes which we don't have + // set, try to get the values from the parent. + if (parentStyle != null) { + parentStyle = (RowStyle)parentStyle.getResolved(); + + if ((rowHeight == 0) && (parentStyle.getRowHeight() != 0)) + resolved.setRowHeight(parentStyle.getRowHeight()); + } + return resolved; + } + + + /** + * Create a new <code>Node</code> in the <code>Document</code>, and + * write this <code>Style</code> to it. + * + * @param parentDoc Parent <code>Document</code> of the + * <code>Node</code> to create. + * @param name Name to use for the new <code>Node</code> (e.g. + * <i>style:style</i>) + * + * @return Created <code>Node</code>. + */ + public Node createNode(org.w3c.dom.Document parentDoc, String name) { + Element node = parentDoc.createElement(name); + writeAttributes(node); + return node; + } + + + /** + * Return true if <code>style</code> specifies as much or less + * than this <code>Style</code>, and nothing it specifies + * contradicts this <code>Style</code>. + * + * @param style The <code>Style</code> to check. + * + * @return true if <code>style</code> is a subset, false + * otherwise. + */ + public boolean isSubset(Style style) { + if (style.getClass() != this.getClass()) + return false; + RowStyle tStyle = (RowStyle)style; + + if(rowHeight!=tStyle.getRowHeight()) + return false; + + return true; + } + + + /** + * Write this <code>Style</code> object's attributes to a + * <code>Node</code> in the <code>Document</code>. + * + * @param node The <code>Node</code> to add <code>Style</code> + * attributes. + */ + public void writeAttributes(Element node) { + + if(rowHeight!=0) { + String height = TwipsConverter.twips2cm(rowHeight) + "cm"; + node.setAttribute("style:row-height", height); + } + } + + + private static String[] ignored = { + "fo:break-before", "fo:keep-with-next" + }; + + + /* + * This code checks whether an attribute is one that we + * intentionally ignore. + * + * @param attribute The attribute to check. + * + * @return true if <code>attribute</code> can be ignored, + * otherwise false. + */ + private boolean isIgnored(String attribute) { + for (int i = 0; i < ignored.length; i++) { + if (ignored[i].equals(attribute)) + return true; + } + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SheetSettings.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SheetSettings.java new file mode 100644 index 000000000000..765da090611c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SheetSettings.java @@ -0,0 +1,377 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SheetSettings.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import java.awt.Point; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.util.Debug; + +/** + * This is a class representing the different attributes for a worksheet + * contained in settings.xml. + * + * @author Martin Maher + */ +public class SheetSettings implements OfficeConstants { + + /** A w3c <code>Document</code>. */ + private org.w3c.dom.Document settings = null; + + private String sheetName; + private int cursorX = 0; + private int cursorY = 0; + private int splitTypeX; + private int splitTypeY; + private int splitPointX = 0; + private int splitPointY = 0; + private int posLeft = 0; + private int posRight = 0; + private int posBottom = 0; + private int posTop = 0; + private int paneNumber = 2; + + final public static int NONE = 0x00; + final public static int SPLIT = 0x01; + final public static int FREEZE = 0x02; + + + /** + * Default Constructor for a <code>ColumnRowInfo</code> + * + */ + public SheetSettings() { + } + + /** + * Constructor that takes a <code>Node</code> to build a <code>SheetSettings</code> + * + * @param root XML Node to read from + */ + public SheetSettings(Node root) { + readNode(root); + } + + /** + * Constructor for a <code>ColumnRowInfo</code> + * + * @param dimension if it's a row the height, a column the width + * @param repeated + */ + public SheetSettings(String name) { + sheetName = name; + } + + /** + * sets the position of the acitve cell + * + * @param activeCell the current curor position + */ + public void setCursor(Point activeCell) { + + cursorX = (int) activeCell.getX(); + cursorY = (int) activeCell.getY(); + } + + /** + * Gets the position of the acitve cell + * + * @return The position as a <code>Point</code> + */ + public Point getCursor() { + + return (new Point(cursorX, cursorY)); + } + + /** + * Sets the position of the freeze + * + * @param splitPoint the point at where the split occurs + */ + public void setFreeze(Point splitPoint) { + + splitTypeX = FREEZE; + splitTypeY = FREEZE; + splitPointX = (int) splitPoint.getX(); + splitPointY = (int) splitPoint.getY(); + } + + /** + * Sets the position of the split + * + * @param splitPoint the point at where the split occurs + */ + public void setSplit(Point splitPoint) { + + splitTypeX = SPLIT; + splitTypeY = SPLIT; + splitPointX = (int) splitPoint.getX(); + splitPointY = (int) splitPoint.getY(); + } + + /** + * sets the position and type of the split + * + * @return The position as a <code>Point</code> where the split occurs + */ + public Point getSplit() { + + return (new Point(splitPointX, splitPointY)); + } + + /** + * sets the position and type of the split + * + * @return The position as a <code>Point</code> where the split occurs + */ + public Point getSplitType() { + + return (new Point(splitTypeX, splitTypeY)); + } + + /** + * Sets the top row visible in the lower pane and the leftmost column + * visibile in the right pane. + * + * @param top The top row visible in the lower pane + * @param left The leftmost column visibile in the right pane + */ + public void setTopLeft(int top, int left) { + + posLeft = left; + posTop = top; + } + + /** + * Gets the the leftmost column visibile in the right pane. + * + * @return the 0-based index to the column + */ + public int getLeft() { + + return posLeft; + } + /** + * Sets the top row visible in the lower pane and the leftmost column + * visibile in the right pane. + * + * @param top The top row visible in the lower pane + * @param left The leftmost column visibile in the right pane + */ + public int getTop() { + + return posTop; + } + + /** + * Gets the active Panel + * 0 - Bottom Right, 1 - Top Right + * 2 - Bottom Left, 3 - Top Left + * + * @return int representing the active panel + */ + public int getPaneNumber() { + + return paneNumber; + } + + /** + * Sets the sheetname this settings object applies to + * + * @param sheetName the name of the worksheet + */ + public void setSheetName(String sheetName) { + + this.sheetName = sheetName; + + } + + /** + * Sets the active pane number + * 0 - Bottom Right, 1 - Top Right + * 2 - Bottom Left, 3 - Top Left + * + * @param paneNumber the pane number + */ + public void setPaneNumber(int paneNumber) { + + this.paneNumber = paneNumber; + } + + /** + * Gets the name of the worksheet these <code>Settings</code> apply to + * + * @return the name of the worksheet + */ + public String getSheetName() { + + return sheetName; + } + + /** + * Adds an XML entry for a particular setting + * + * @param root the root node at which to add the xml entry + * @param attriute the name of the attribute to add + * @param type the attribute type (int, short etc) + * @param value the value of the attribute + */ + private void addConfigItem(Node root, String attribute, String type, String value) { + + Element configItem = settings.createElement(TAG_CONFIG_ITEM); + configItem.setAttribute(ATTRIBUTE_CONFIG_NAME, attribute); + configItem.setAttribute(ATTRIBUTE_CONFIG_TYPE, type); + + configItem.appendChild(settings.createTextNode(value)); + + root.appendChild(configItem); + } + + /** + * Writes out a settings.xml entry for this SheetSettings object + * + * @param settings a <code>Document</code> object representing the settings.xml + * @param root the root xml node to add to + */ + public void writeNode(org.w3c.dom.Document settings, Node root) { + + this.settings = settings; + Element configItemMapEntry = (Element) settings.createElement(TAG_CONFIG_ITEM_MAP_ENTRY); + configItemMapEntry.setAttribute(ATTRIBUTE_CONFIG_NAME, getSheetName()); + addConfigItem(configItemMapEntry, "CursorPositionX", "int", Integer.toString(cursorX)); + addConfigItem(configItemMapEntry, "CursorPositionY", "int", Integer.toString(cursorY)); + + String splitMode = Integer.toString(splitTypeX); + if(splitPointX==0) { + splitMode = "0"; + } + addConfigItem(configItemMapEntry, "HorizontalSplitMode", "short", splitMode); + + splitMode = Integer.toString(splitTypeY); + if(splitPointY==0) { + splitMode = "0"; + } + addConfigItem(configItemMapEntry, "VerticalSplitMode", "short", splitMode); + + addConfigItem(configItemMapEntry, "HorizontalSplitPosition", "int", Integer.toString(splitPointX)); + addConfigItem(configItemMapEntry, "VerticalSplitPosition", "int", Integer.toString(splitPointY)); + addConfigItem(configItemMapEntry, "ActiveSplitRange", "short", Integer.toString(paneNumber)); + + addConfigItem(configItemMapEntry, "PositionLeft", "int", "0"); + addConfigItem(configItemMapEntry, "PositionRight", "int", Integer.toString(posLeft)); + addConfigItem(configItemMapEntry, "PositionTop", "int", "0"); + addConfigItem(configItemMapEntry, "PositionBottom", "int", Integer.toString(posTop)); + root.appendChild(configItemMapEntry); + } + + /** + * Sets a variable based on a String value read from XML + * + * @param name xml name of the attribute to set + * @param value String value fo the attribute + */ + public void addAttribute(String name, String value) { + + if(name.equals("CursorPositionX")) { + cursorX = Integer.parseInt(value); + } else if(name.equals("CursorPositionY")) { + cursorY = Integer.parseInt(value); + + } else if(name.equals("HorizontalSplitPosition")) { + splitPointX = Integer.parseInt(value); + } else if(name.equals("VerticalSplitPosition")) { + splitPointY = Integer.parseInt(value); + } else if(name.equals("ActiveSplitRange")) { + paneNumber = Integer.parseInt(value); + + } else if(name.equals("PositionRight")) { + posLeft = Integer.parseInt(value); + } else if(name.equals("PositionBottom")) { + posTop = Integer.parseInt(value); + + } else if(name.equals("HorizontalSplitMode")) { + splitTypeX = Integer.parseInt(value); + } else if(name.equals("VerticalSplitMode")) { + splitTypeY = Integer.parseInt(value); + } + } + + /** + * Reads document settings from xml and inits SheetSettings variables + * + * @param root XML Node to read from + */ + public void readNode(Node root) { + + NamedNodeMap sheetAtt = root.getAttributes(); + + Node sheetNameNode = sheetAtt.getNamedItem(ATTRIBUTE_CONFIG_NAME); + + sheetName = sheetNameNode.getNodeValue(); + + if (root.hasChildNodes()) { + + NodeList nodeList = root.getChildNodes(); + int len = nodeList.getLength(); + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_CONFIG_ITEM)) { + + NamedNodeMap cellAtt = child.getAttributes(); + + Node configNameNode = + cellAtt.getNamedItem(ATTRIBUTE_CONFIG_NAME); + + String name = configNameNode.getNodeValue(); + NodeList nodeList2 = child.getChildNodes(); + int len2 = nodeList2.getLength(); + String s = ""; + for (int j = 0; j < len2; j++) { + Node child2 = nodeList2.item(j); + if (child2.getNodeType() == Node.TEXT_NODE) { + s = child2.getNodeValue(); + } + } + addAttribute(name, s); + } + } + } + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SpreadsheetDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SpreadsheetDecoder.java new file mode 100644 index 000000000000..5a6408ba6694 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SpreadsheetDecoder.java @@ -0,0 +1,184 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SpreadsheetDecoder.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; + +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.ConvertData; + +/** + * This class is a abstract class for encoding a "Device" + * <code>Document</code> format into an alternative spreadsheet format. + * + * @author Mark Murnane + */ +public abstract class SpreadsheetDecoder { + + /** + * Constructor for creating new <code>SpreadsheetDecoder</code>. + */ + public SpreadsheetDecoder(String name, String password) throws IOException { + } + + /** + * Returns the total number of sheets in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public abstract int getNumberOfSheets(); + + /** + * Returns an Enumeration to a Vector of <code>NameDefinition</code>. + * + * @return The Enumeration + */ + public abstract Enumeration getNameDefinitions(); + + /** + * Returns an <code>BookSettings</code> + * + * @return The Enumeration + */ + public abstract BookSettings getSettings(); + + /** + * Returns an Enumeration to a Vector of <code>ColumnRowInfo</code>. + * + * @return The Enumeration + */ + public abstract Enumeration getColumnRowInfos(); + + /** + * Returns the number of populated rows in the current WorkSheet. + * + * @return the number of populated rows in the current WorkSheet. + */ + public abstract int getNumberOfRows(); + + + /** + * Returns the number of populated columns in the current WorkSheet. + * + * @return The number of populated columns in the current WorkSheet. + */ + public abstract int getNumberOfColumns(); + + + /** + * Returns the name of the current WorkSheet. + * + * @return Name of the current WorkSheet. + */ + public abstract String getSheetName(); + + + /** + * Returns the number of the active column. + * + * @return The number of the active column. + */ + public abstract int getColNumber(); + + + /** + * Returns the number of the active row. + * + * @return The number of the active row. + */ + public abstract int getRowNumber(); + + + /** + * Sets the active WorkSheet. + * + * @param sheetIndex The index of the sheet to be made active. + * + * @throws IOException If any I/O error occurs. + */ + public abstract void setWorksheet(int sheetIndex) throws IOException; + + + /** + * Move on the next populated cell in the current WorkSheet. + * + * @return true if successful, false otherwise. + * + * @throws IOException If any I/O error occurs. + */ + public abstract boolean goToNextCell() throws IOException; + + + /** + * Return the contents of the active cell. + * + * @return The cell contents. + */ + public abstract String getCellContents(); + + /** + * Return the value of the active cell. Used in the case of Formula where + * the cell contents and the cell value are not the same thing. + * + * @return The cell value. + */ + public abstract String getCellValue(); + + /** + * Return the data type of the active cell. + * + * @return The cell data type. + */ + public abstract String getCellDataType(); + + + /** + * Return a <code>Format</code> object describing the active cells + * formatting. + * + * @return <code>Format</code> object for the cell. + */ + public abstract Format getCellFormat(); + + + /** + * Add the contents of a <code>ConvertData</code> to the workbook. + * + * @param cd The <code>ConvertData</code> containing the + * content. + * + * @throws IOException If any I/O error occurs. + */ + public abstract void addDeviceContent(ConvertData cd) throws IOException; +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SpreadsheetEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SpreadsheetEncoder.java new file mode 100644 index 000000000000..81e6914b1bfe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SpreadsheetEncoder.java @@ -0,0 +1,134 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SpreadsheetEncoder.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.io.IOException; +import java.util.Vector; + +import org.openoffice.xmerge.util.IntArrayList; + +/** + * <p>This class is a abstract class for encoding an SXC into an + * alternative spreadsheet format.</p> + * + * <p>TODO - Add appropriate exceptions to each of the methods.</p> + * + * @author Mark Murnane + */ +public abstract class SpreadsheetEncoder { + + + /** + * Creates new SpreadsheetEncoder. + * + * @param name The name of the WorkBook to be created. + * @param password An optional password for the WorkBook. + * + * @throws IOException If any I/O error occurs. + */ + public SpreadsheetEncoder(String name, String password) throws IOException { }; + + + /** + * Create a new WorkSheet within the WorkBook. + * + * @param sheetName The name of the WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public abstract void createWorksheet(String sheetName) throws IOException; + + + /** + * Set a cell's formatting options via a separately create + * <code>Format</code> object. + * + * @param row The row number of the cell to be changed + * @param column The column number of the cell to be changed + * @param fmt Object containing formatting settings for this cell. + */ + public abstract void setCellFormat(int row, int column, Format fmt); + + + /** + * Add a cell to the current WorkSheet. + * + * @param row The row number of the cell + * @param column The column number of the cell + * @param fmt The <code>Format</code> object describing the + * appearance of this cell. + * @param cellContents The text or formula of the cell's contents. + */ + public abstract void addCell(int row, int column, + Format fmt, String cellContents) throws IOException; + + + /** + * Get the number of sheets in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public abstract int getNumberOfSheets(); + + + /** + * Get the names of the sheets in the WorkBook. + * + * @param sheet The required sheet. + */ + public abstract String getSheetName(int sheet); + + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public abstract void setColumnRows(Vector columnRows) throws IOException; + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public abstract void setNameDefinition(NameDefinition nd) throws IOException; + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public abstract void addSettings(BookSettings s) throws IOException; +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcConstants.java new file mode 100644 index 000000000000..793fe47bfc23 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcConstants.java @@ -0,0 +1,53 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcConstants.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc; + + +/** + * Interface defining constants for Sxc attributes. + * + * @author Martin Maher + */ +public interface SxcConstants { + + /** Family name for column styles. */ + public static final String COLUMN_STYLE_FAMILY = "table-column"; + + /** Family name for row styles. */ + public static final String ROW_STYLE_FAMILY = "table-row"; + + /** Family name for table-cell styles. */ + public static final String TABLE_CELL_STYLE_FAMILY = "table-cell"; + + /** Name of the default style. */ + public static final String DEFAULT_STYLE = "Default"; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocument.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocument.java new file mode 100644 index 000000000000..8a76b4260fc5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocument.java @@ -0,0 +1,96 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocument.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import org.w3c.dom.Document; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * This class is an implementation of <code>OfficeDocument</code> for + * the SXC format. + */ +public class SxcDocument extends OfficeDocument { + + /** + * Constructor with arguments to set <code>name</code>. + * + * @param name The name of the <code>Document</code> + */ + public SxcDocument(String name) { + super(name); + } + + + /** + * Constructor with arguments to set <code>name</code>, the + * <code>namespaceAware</code> flag, and the <code>validating</code> + * flag. + * + * @param name The name of the <code>Document</code>. + * @param namespaceAware The value of the <code>namespaceAware</code> + * flag. + * @param validating The value of the <code>validating</code> flag. + */ + public SxcDocument(String name, boolean namespaceAware, boolean validating) { + + super(name, namespaceAware, validating); + } + + /** + * Returns the Office file extension for the SXC format. + * + * @return The Office file extension for the SXC format. + */ + protected String getFileExtension() { + return OfficeConstants.SXC_FILE_EXTENSION; + } + + /** + * Returns the Office attribute for the SXC format. + * + * @return The Office attribute for the SXC format. + */ + protected String getOfficeClassAttribute() { + return OfficeConstants.SXC_TYPE; + } + + /** + * Method to return the MIME type of the document. + * + * @return String The document's MIME type. + */ + protected final String getDocumentMimeType() { + return OfficeConstants.SXC_MIME_TYPE; + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocumentDeserializer.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocumentDeserializer.java new file mode 100644 index 000000000000..01e9987172b4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocumentDeserializer.java @@ -0,0 +1,797 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocumentDeserializer.java,v $ + * $Revision: 1.14 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; + +import java.awt.Point; +import java.io.IOException; +import java.util.Enumeration; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocument; +import org.openoffice.xmerge.converter.xml.sxc.BookSettings; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; +import org.openoffice.xmerge.converter.xml.sxc.NameDefinition; +import org.openoffice.xmerge.converter.xml.sxc.CellStyle; +import org.openoffice.xmerge.converter.xml.Style; +import org.openoffice.xmerge.converter.xml.StyleCatalog; +import org.openoffice.xmerge.util.Debug; + +/** + * <p>General spreadsheet implementation of <code>DocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcPluginFactory + * SxcPluginFactory}. Used with SXC <code>Document</code> objects.</p> + * + * <p>The <code>deserialize</code> method uses a <code>DocDecoder</code> + * to read the device spreadsheet format into a <code>String</code> + * object, then it calls <code>buildDocument</code> to create a + * <code>SxcDocument</code> object from it.</p> + * + * @author Paul Rank + * @author Mark Murnane + * @author Martin Maher + */ +public abstract class SxcDocumentDeserializer implements OfficeConstants, + DocumentDeserializer { + + /** + * A <code>SpreadsheetDecoder</code> object for decoding from + * device formats. + */ + private SpreadsheetDecoder decoder = null; + + /** A w3c <code>Document</code>. */ + private org.w3c.dom.Document settings = null; + + /** A w3c <code>Document</code>. */ + private org.w3c.dom.Document doc = null; + + /** An <code>ConvertData</code> object assigned to this object. */ + private ConvertData cd = null; + + /** A style catalog for the workbook */ + private StyleCatalog styleCat = null; + + private int textStyles = 1; + private int colStyles = 1; + private int rowStyles = 1; + + /** + * Constructor. + * + * @param cd <code>ConvertData</code> consisting of a + * device content object. + */ + public SxcDocumentDeserializer(ConvertData cd) { + this.cd = cd; + } + + + /** + * This abstract method will be implemented by concrete subclasses + * and will return an application-specific Decoder. + * + * @param workbook The WorkBook to read. + * @param password The WorkBook password. + * + * @return The appropriate <code>SpreadSheetDecoder</code>. + * + * @throws IOException If any I/O error occurs. + */ + public abstract SpreadsheetDecoder createDecoder(String workbook, String[] worksheetNames, String password) + throws IOException; + + + /** + * <p>This method will return the name of the WorkBook from the + * <code>ConvertData</code>. Allows for situations where the + * WorkBook name differs from the Device Content name.</p> + * + * <p>Implemented in the Deserializer as the Decoder's constructor requires + * a name.</p> + * + * @param cd The <code>ConvertData</code> containing the Device + * content. + * + * @return The WorkBook name. + */ + protected abstract String getWorkbookName(ConvertData cd) throws IOException; + + + /** + * This method will return the name of the WorkSheet from the + * <code>ConvertData</code>. + * + * @param cd The <code>ConvertData</code> containing the Device + * content. + * + * @return The WorkSheet names. + */ + protected abstract String[] getWorksheetNames(ConvertData cd) throws IOException; + + + /** + * <p>Method to convert a set of "Device" + * <code>Document</code> objects into a <code>SxcDocument</code> + * object and returns it as a <code>Document</code>.</p> + * + * <p>This method is not thread safe for performance reasons. + * This method should not be called from within two threads. + * It would be best to call this method only once per object + * instance.</p> + * + * @return document An <code>SxcDocument</code> consisting + * of the data converted from the input + * stream. + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public Document deserialize() throws ConvertException, + IOException { + + // Get the name of the WorkBook from the ConvertData. + String[] worksheetNames = getWorksheetNames(cd); + String workbookName = getWorkbookName(cd); + + // Create a document + SxcDocument sxcDoc = new SxcDocument(workbookName); + sxcDoc.initContentDOM(); + sxcDoc.initSettingsDOM(); + + // Default to an initial 5 entries in the catalog. + styleCat = new StyleCatalog(5); + + doc = sxcDoc.getContentDOM(); + settings = sxcDoc.getSettingsDOM(); + initFontTable(); + // Little fact for the curious reader: workbookName should + // be the name of the StarCalc file minus the file extension suffix. + + // Create a Decoder to decode the DeviceContent to a spreadsheet document + // TODO - we aren't using a password in StarCalc, so we can + // use any value for password here. If StarCalc XML supports + // passwords in the future, we should try to get the correct + // password value here. + // + decoder = createDecoder(workbookName, worksheetNames, "password"); + + Debug.log(Debug.TRACE, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + Debug.log(Debug.TRACE, "<DEBUGLOG>"); + + decoder.addDeviceContent(cd); + decode(); + + Debug.log(Debug.TRACE, "</DEBUGLOG>"); + + return sxcDoc; + } + + /** + * This initializes a font table so we can imclude some basic font + * support for spreadsheets. + * + */ + private void initFontTable() { + + String fontTable[]= new String[] { "Tahoma", "Tahoma", "swiss", "variable", + "Courier New", "'Courier New'", "modern", "fixed"}; + // Traverse to the office:body element. + // There should only be one. + NodeList list = doc.getElementsByTagName(TAG_OFFICE_FONT_DECLS); + Node root = list.item(0); + + for(int i=0;i<fontTable.length;) { + + // Create an element node for the table + Element tableElement = (Element) doc.createElement(TAG_STYLE_FONT_DECL); + + tableElement.setAttribute(ATTRIBUTE_STYLE_NAME, fontTable[i++]); + tableElement.setAttribute(ATTRIBUTE_FO_FONT_FAMILY, fontTable[i++]); + tableElement.setAttribute(ATTRIBUTE_FO_FONT_FAMILY_GENERIC, fontTable[i++]); + tableElement.setAttribute(ATTRIBUTE_STYLE_FONT_PITCH, fontTable[i++]); + + root.appendChild(tableElement); + } + + } + + /** + * Outer level method used to decode a WorkBook + * into a <code>Document</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void decode() throws IOException { + + // Get number of worksheets + int numSheets = decoder.getNumberOfSheets(); + // #i33702# - check for an Empty InputStream. + if(numSheets == 0) + { + System.err.println("Error decoding invalid Input stream"); + return; + } + + // Traverse to the office:body element. + // There should only be one. + NodeList list = doc.getElementsByTagName(TAG_OFFICE_BODY); + Node node = list.item(0); + + for (int i = 0; i < numSheets; i++) { + + // Set the decoder to the correct worksheet + decoder.setWorksheet(i); + + int len = list.getLength(); + + if (len > 0) { + + // Process the spreadsheet + processTable(node); + } + } + + // Add the Defined Name table if there is one + Enumeration nameDefinitionTable = decoder.getNameDefinitions(); + if(nameDefinitionTable.hasMoreElements()) { + processNameDefinition(node, nameDefinitionTable); + } + + // add settings + NodeList settingsList = settings.getElementsByTagName(TAG_OFFICE_SETTINGS); + Node settingsNode = settingsList.item(0);; + processSettings(settingsNode); + + } + + + + /** + * This method process the settings portion + * of the <code>Document</code>. + * + * @param root The root <code>Node</code> of the + * <code>Document</code> we are building. This + * <code>Node</code> should be a TAG_OFFICE_SETTINGS + * tag. + */ + protected void processSettings(Node root) { + + Element configItemSetEntry = (Element) settings.createElement(TAG_CONFIG_ITEM_SET); + configItemSetEntry.setAttribute(ATTRIBUTE_CONFIG_NAME, "view-settings"); + Element configItemMapIndexed = (Element) settings.createElement(TAG_CONFIG_ITEM_MAP_INDEXED); + configItemMapIndexed.setAttribute(ATTRIBUTE_CONFIG_NAME, "Views"); + Element configItemMapEntry = (Element) settings.createElement(TAG_CONFIG_ITEM_MAP_ENTRY); + BookSettings bs = (BookSettings) decoder.getSettings(); + bs.writeNode(settings, configItemMapEntry); + + configItemMapIndexed.appendChild(configItemMapEntry); + configItemSetEntry.appendChild(configItemMapIndexed); + root.appendChild(configItemSetEntry); + } + + /** + * This method process a Name Definition Table and generates a portion + * of the <code>Document</code>. + * + * @param root The root <code>Node</code> of the + * <code>Document</code> we are building. This + * <code>Node</code> should be a TAG_OFFICE_BODY + * tag. + * + * @throws IOException If any I/O error occurs. + */ + protected void processNameDefinition(Node root, Enumeration eNameDefinitions) throws IOException { + + Debug.log(Debug.TRACE, "<NAMED-EXPRESSIONS>"); + + Element namedExpressionsElement = (Element) doc.createElement(TAG_NAMED_EXPRESSIONS); + + while(eNameDefinitions.hasMoreElements()) { + + NameDefinition tableEntry = (NameDefinition) eNameDefinitions.nextElement(); + tableEntry.writeNode(doc, namedExpressionsElement); + } + + root.appendChild(namedExpressionsElement); + + Debug.log(Debug.TRACE, "</NAMED-EXPRESSIONS>"); + } + + /** + * This method process a WorkSheet and generates a portion + * of the <code>Document</code>. A spreadsheet is represented + * as a table Node in StarOffice XML format. + * + * @param root The root <code>Node</code> of the + * <code>Document</code> we are building. This + * <code>Node</code> should be a TAG_OFFICE_BODY + * tag. + * + * @throws IOException If any I/O error occurs. + */ + protected void processTable(Node root) throws IOException { + + Debug.log(Debug.TRACE, "<TABLE>"); + + // Create an element node for the table + Element tableElement = (Element) doc.createElement(TAG_TABLE); + + // Get the sheet name + String sheetName = decoder.getSheetName(); + + // Set the table name attribute + tableElement.setAttribute(ATTRIBUTE_TABLE_NAME, sheetName); + + // TODO - style currently hardcoded - get real value + // Set table style-name attribute + tableElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, "Default"); + + // Append the table element to the root node + root.appendChild(tableElement); + + Debug.log(Debug.TRACE, "<SheetName>" + sheetName + "</SheetName>"); + + // add the various different table-columns + processColumns(tableElement); + + // Get each cell and add to doc + processCells(tableElement); + + Debug.log(Debug.TRACE, "</TABLE>"); + } + + /** + * <p>This method process the cells in a <code>Document</code> + * and generates a portion of the <code>Document</code>.</p> + * + * <p>This method assumes that records are sorted by + * row and then column.</p> + * + * @param root The <code>Node</code> of the <code>Document</code> + * we are building that we will append our cell + * <code>Node</code> objects. This <code>Node</code> + * should be a TAG_TABLE tag. + * + * @throws IOException If any I/O error occurs. + */ + protected void processColumns(Node root) throws IOException { + + for(Enumeration e = decoder.getColumnRowInfos();e.hasMoreElements();) { + + ColumnRowInfo ci = (ColumnRowInfo) e.nextElement(); + if(ci.isColumn()) { + ColumnStyle cStyle = new ColumnStyle("Default",SxcConstants.COLUMN_STYLE_FAMILY, + SxcConstants.DEFAULT_STYLE, ci.getSize(), null); + + Style result[] = (Style[]) styleCat.getMatching(cStyle); + String styleName; + if(result.length==0) { + + cStyle.setName("co" + colStyles++); + styleName = cStyle.getName(); + Debug.log(Debug.TRACE,"No existing style found, adding " + styleName); + styleCat.add(cStyle); + } else { + ColumnStyle existingStyle = (ColumnStyle) result[0]; + styleName = existingStyle.getName(); + Debug.log(Debug.TRACE,"Existing style found : " + styleName); + } + + // Create an element node for the new row + Element colElement = (Element) doc.createElement(TAG_TABLE_COLUMN); + colElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, styleName); + if(ci.getRepeated()!=1) { + String repeatStr = String.valueOf(ci.getRepeated()); + colElement.setAttribute(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED, repeatStr); + } + root.appendChild(colElement); + } + } + } + + /** + * <p>This method process the cells in a <code>Document</code> + * and generates a portion of the <code>Document</code>.</p> + * + * <p>This method assumes that records are sorted by + * row and then column.</p> + * + * @param root The <code>Node</code> of the <code>Document</code> + * we are building that we will append our cell + * <code>Node</code> objects. This <code>Node</code> + * should be a TAG_TABLE tag. + * + * @throws IOException If any I/O error occurs. + */ + protected void processCells(Node root) throws IOException { + + // The current row element + Element rowElement = null; + + // The current cell element + Element cellElement = null; + + // The row number - we may not have any rows (empty sheet) + // so set to zero. + int row = 0; + + // The column number - This is the expected column number of + // the next cell we are reading. + int col = 1; + + // The number of columns in the spreadsheet + int lastColumn = decoder.getNumberOfColumns(); + + // + Node autoStylesNode = null; + + // Loop over all cells in the spreadsheet + while (decoder.goToNextCell()) { + + // Get the row number + int newRow = decoder.getRowNumber(); + + // Is the cell in a new row, or part of the current row? + if (newRow != row) { + + // Make sure that all the cells in the previous row + // have been entered. + if (col <= lastColumn && rowElement != null) { + int numSkippedCells = lastColumn - col + 1; + addEmptyCells(numSkippedCells, rowElement); + } + + // log an end row - if we already have a row + if (row != 0) { + Debug.log(Debug.TRACE, "</tr>"); + } + + // How far is the new row from the last row? + int deltaRows = newRow - row; + + // Check if we have skipped any rows + if (deltaRows > 1) { + // Add in empty rows + addEmptyRows(deltaRows-1, root, lastColumn); + } + + // Re-initialize column (since we are in a new row) + col = 1; + + // Create an element node for the new row + rowElement = (Element) doc.createElement(TAG_TABLE_ROW); + + + for(Enumeration e = decoder.getColumnRowInfos();e.hasMoreElements();) { + ColumnRowInfo cri = (ColumnRowInfo) e.nextElement(); + if(cri.isRow() && cri.getRepeated()==newRow-1) { + // We have the correct Row BIFFRecord for this row + RowStyle rStyle = new RowStyle("Default",SxcConstants.ROW_STYLE_FAMILY, + SxcConstants.DEFAULT_STYLE, cri.getSize(), null); + + Style result[] = (Style[]) styleCat.getMatching(rStyle); + String styleName; + if(result.length==0) { + + rStyle.setName("ro" + rowStyles++); + styleName = rStyle.getName(); + Debug.log(Debug.TRACE,"No existing style found, adding " + styleName); + styleCat.add(rStyle); + } else { + RowStyle existingStyle = (RowStyle) result[0]; + styleName = existingStyle.getName(); + Debug.log(Debug.TRACE,"Existing style found : " + styleName); + } + rowElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, styleName); + // For now we will not use the repeat column attribute + } + } + + // Append the row element to the root node + root.appendChild(rowElement); + + // Update row number + row = newRow; + + Debug.log(Debug.TRACE, "<tr>"); + } + + // Get the column number of the current cell + int newCol = decoder.getColNumber(); + + // Check to see if some columns were skipped + if (newCol != col) { + + // How many columns have we skipped? + int numColsSkipped = newCol - col; + + addEmptyCells(numColsSkipped, rowElement); + + // Update the column number to account for the + // skipped cells + col = newCol; + } + + // Lets start dealing with the cell data + Debug.log(Debug.TRACE, "<td>"); + + // Get the cell's contents + String cellContents = decoder.getCellContents(); + + // Get the type of the data in the cell + String cellType = decoder.getCellDataType(); + + // Get the cell format + Format fmt = decoder.getCellFormat(); + + // Create an element node for the cell + cellElement = (Element) doc.createElement(TAG_TABLE_CELL); + + Node bodyNode = doc.getElementsByTagName(TAG_OFFICE_BODY).item(0); + + // Not every document has an automatic style tag + autoStylesNode = doc.getElementsByTagName( + TAG_OFFICE_AUTOMATIC_STYLES).item(0); + + if (autoStylesNode == null) { + autoStylesNode = doc.createElement(TAG_OFFICE_AUTOMATIC_STYLES); + doc.insertBefore(autoStylesNode, bodyNode); + } + + CellStyle tStyle = new + CellStyle( "Default",SxcConstants.TABLE_CELL_STYLE_FAMILY, + SxcConstants.DEFAULT_STYLE, fmt, null); + String styleName; + Style result[] = (Style[]) styleCat.getMatching(tStyle); + if(result.length==0) { + + tStyle.setName("ce" + textStyles++); + styleName = tStyle.getName(); + Debug.log(Debug.TRACE,"No existing style found, adding " + styleName); + styleCat.add(tStyle); + } else { + CellStyle existingStyle = (CellStyle) result[0]; + styleName = existingStyle.getName(); + Debug.log(Debug.TRACE,"Existing style found : " + styleName); + } + + cellElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, styleName); + + // Store the cell data into the appropriate attributes + processCellData(cellElement, cellType, cellContents); + + // Append the cell element to the row node + rowElement.appendChild(cellElement); + + // Append the cellContents as a text node + Element textElement = (Element) doc.createElement(TAG_PARAGRAPH); + cellElement.appendChild(textElement); + textElement.appendChild(doc.createTextNode(cellContents)); + + Debug.log(Debug.TRACE, cellContents); + Debug.log(Debug.TRACE, "</td>"); + + // Increment to the column number of the next expected cell + col++; + } + + // Make sure that the last row is padded correctly + if (col <= lastColumn && rowElement != null) { + int numSkippedCells = lastColumn - col + 1; + addEmptyCells(numSkippedCells, rowElement); + } + + // Now write the style catalog to the document + if(autoStylesNode!=null) { + Debug.log(Debug.TRACE,"Well the autostyle node was found!!!"); + NodeList nl = styleCat.writeNode(doc, "dummy").getChildNodes(); + int nlLen = nl.getLength(); // nl.item reduces the length + for (int i = 0; i < nlLen; i++) { + autoStylesNode.appendChild(nl.item(0)); + } + } + + if (row != 0) { + + // The sheet does have rows, so write out a /tr + Debug.log(Debug.TRACE, "</tr>"); + } + } + + + /** + * This method will add empty rows to the <code>Document</code>. + * It is called when the conversion process encounters + * a row (or rows) that do not contain any data in its cells. + * + * @param numEmptyRows The number of empty rows that we + * need to add to the <code>Document</code>. + * @param root The <code>Node</code> of the + * <code>Document</code> we are building + * that we will append our empty row + * <code>Node</code> objects. This + * <code>Node</code> should be a TAG_TABLE + * tag. + * @param numEmptyCells The number of empty cells in the + * empty row. + */ + protected void addEmptyRows(int numEmptyRows, Node root, int numEmptyCells) { + + // Create an element node for the row + Element rowElement = (Element) doc.createElement(TAG_TABLE_ROW); + + // TODO - style currently hardcoded - get real value + // Set row style-name attribute + rowElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, "Default"); + + // Set cell number-rows-repeated attribute + rowElement.setAttribute(ATTRIBUTE_TABLE_NUM_ROWS_REPEATED, + Integer.toString(numEmptyRows)); + + // Append the row element to the root node + root.appendChild(rowElement); + + // Open Office requires the empty row to have an empty cell (or cells) + addEmptyCells(numEmptyCells, rowElement); + + // Write empty rows to the log + for (int i = 0; i < numEmptyRows; i++) { + Debug.log(Debug.TRACE, "<tr />"); + } + + } + + + /** + * This method will add empty cells to the <code>Document</code>. + * It is called when the conversion process encounters a row + * that contains some cells without data. + * + * @param numColsSkipped The number of empty cells + * that we need to add to the + * current row. + * @param row The <code>Node</code> of the + * <code>Document</code> we + * are building that we will + * append our empty cell + * <code>Node</code> objects. + * This <code>Node</code> should + * be a TAG_TABLE_ROW tag. + */ + protected void addEmptyCells(int numColsSkipped, Node row) { + + // Create an empty cellElement + Element cellElement = (Element) doc.createElement(TAG_TABLE_CELL); + + // TODO - style currently hardcoded - get real value + // Set cell style-name attribute + cellElement.setAttribute(ATTRIBUTE_TABLE_STYLE_NAME, "Default"); + + // If we skipped more than 1 cell, we must set the + // appropriate attribute + if (numColsSkipped > 1) { + + // Set cell number-columns-repeated attribute + cellElement.setAttribute(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED, + Integer.toString(numColsSkipped)); + } + + // Append the empty cell element to the row node + row.appendChild(cellElement); + + // Write empty cells to the log + for (int i = 0; i < numColsSkipped; i++) { + Debug.log(Debug.TRACE, "<td />"); + } + } + + + /** + * This method process the data in a cell and sets + * the appropriate attributes on the cell <code>Element</code>. + * + * @param cellElement A TAG_TABLE_CELL <code>Element</code> + * that we will be adding attributes to + * based on the type of data in the cell. + * @param type The type of data contained in the cell. + * @param contents The contents of the data contained in + * the cell. + */ + protected void processCellData(Element cellElement, String type, + String contents) { + + // Set cell value-type attribute + cellElement.setAttribute(ATTRIBUTE_TABLE_VALUE_TYPE, type); + + // Does the cell contain a formula? + if (contents.startsWith("=")) { + + cellElement.setAttribute(ATTRIBUTE_TABLE_FORMULA, contents); + + cellElement.setAttribute(ATTRIBUTE_TABLE_VALUE, decoder.getCellValue()); + // String data does not require any additional attributes + } else if (!type.equals(CELLTYPE_STRING)) { + + if (type.equals(CELLTYPE_TIME)) { + + // Data returned in StarOffice XML format, so store in + // attribute + cellElement.setAttribute(ATTRIBUTE_TABLE_TIME_VALUE, + contents); + + } else if (type.equals(CELLTYPE_DATE)) { + + // Data returned in StarOffice XML format, so store in + // attribute + cellElement.setAttribute(ATTRIBUTE_TABLE_DATE_VALUE, + contents); + + } else if (type.equals(CELLTYPE_BOOLEAN)) { + + // StarOffice XML format requires stored boolean value + // to be in lower case + cellElement.setAttribute(ATTRIBUTE_TABLE_BOOLEAN_VALUE, + contents.toLowerCase()); + + } else if (type.equals(CELLTYPE_CURRENCY)) { + // TODO - StarOffice XML format requires a correct style to + // display currencies correctly. Need to implement styles. + // TODO - USD is for US currencies. Need to pick up + // the correct currency location from the source file. + cellElement.setAttribute(ATTRIBUTE_TABLE_CURRENCY, "USD"); + + // Data comes stripped of currency symbols + cellElement.setAttribute(ATTRIBUTE_TABLE_VALUE, contents); + + } else if (type.equals(CELLTYPE_PERCENT)) { + // Data comes stripped of percent signs + cellElement.setAttribute(ATTRIBUTE_TABLE_VALUE, contents); + + } else { + // Remaining data types use table-value attribute + + cellElement.setAttribute(ATTRIBUTE_TABLE_VALUE, contents); + } + } + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocumentSerializer.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocumentSerializer.java new file mode 100644 index 000000000000..bf0516c5345c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcDocumentSerializer.java @@ -0,0 +1,995 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocumentSerializer.java,v $ + * $Revision: 1.22 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.awt.Color; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import java.io.IOException; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentSerializer; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocument; +import org.openoffice.xmerge.converter.xml.ParaStyle; +import org.openoffice.xmerge.converter.xml.sxc.CellStyle; +import org.openoffice.xmerge.converter.xml.StyleCatalog; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.XmlUtil; + +/** + * <p>General spreadsheet implementation of <code>DocumentSerializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcPluginFactory + * SxcPluginFactory}. Used with SXC <code>Document</code> objects.</p> + * + * <p>The <code>serialize</code> method traverses the DOM + * <code>Document</code> from the given <code>Document</code> object. + * It uses a <code>DocEncoder</code> object for the actual conversion + * of contents to the device spreadsheet format.</p> + * + * @author Paul Rank + * @author Mark Murnane + */ +public abstract class SxcDocumentSerializer implements OfficeConstants, + DocumentSerializer { + + /** The cell foreground <code>Color</code>. */ + private Color foreground = Color.black; + + /** The cell background <code>Color</code>. */ + private Color background = Color.white; + + /** The cell format. */ + private long format = 0; + + /** <code>Format</code> object describing the cell. */ + private Format fmt = null; + + /** The row number. */ + private int rowID = 1; + + /** The column number. */ + private int colID = 1; + + /** The number of times the current row is repeated. */ + private int rowsRepeated = 1; + + /** The number of times the current column is repeated. */ + private int colsRepeated = 1; + + /** The number of times the current column is repeated. */ + private StyleCatalog styleCat = null; + /** + * An array of column widths of the current worksheet. Width is + * measured in number of characters. + */ + private Vector ColumnRowList; + + /** Width, in characters, of the current cell display data. */ + private int displayWidth = 0; + + /** + * A <code>SpreadsheetEncoder</code> object for encoding to + * appropriate format. + */ + protected SpreadsheetEncoder encoder = null; + + /** <code>SxcDocument</code> object that this converter processes. */ + protected SxcDocument sxcDoc = null; + + + /** + * Constructor. + * + * @param document Input <code>SxcDocument</code> + * <code>Document</code>. + */ + public SxcDocumentSerializer(Document document) { + fmt = new Format(); + sxcDoc = (SxcDocument) document; + } + + + /** + * <p>Method to convert a DOM <code>Document</code> into + * "Device" <code>Document</code> objects.</p> + * + * <p>This method is not thread safe for performance reasons. + * This method should not be called from within two threads. + * It would be best to call this method only once per object + * instance.</p> + * + * @return <code>ConvertData</code> containing "Device" + * <code>Document</code> objects. + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public abstract ConvertData serialize() throws ConvertException, + IOException; + + + /** + * This method traverses <i>office:settings</i> <code>Element</code>. + * + * @param node <i>office:settings</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + public void traverseSettings(Node node) throws IOException { + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_CONFIG_ITEM_SET)) { + + traverseSettings(child); + + } else if (nodeName.equals(TAG_CONFIG_ITEM_MAP_INDEXED)) { + + traverseSettings(child); + + } else if (nodeName.equals(TAG_CONFIG_ITEM_MAP_ENTRY)) { + + BookSettings bs = new BookSettings(child); + encoder.addSettings(bs); + + } else { + + Debug.log(Debug.TRACE, "<OTHERS " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + } + + /* + * Handles the loading of defined styles from the style.xml file as well + * as automatic styles from the content.xml file. + * + * Any change to a defined style, such as a short bold section, falls into + * the latter category. + */ + protected void loadStyles(SxcDocument sxcDoc) { + + org.w3c.dom.Document contentDom = sxcDoc.getContentDOM(); + + styleCat = new StyleCatalog(25); + + NodeList nl = null; + String families[] = new String[] { SxcConstants.COLUMN_STYLE_FAMILY, + SxcConstants.ROW_STYLE_FAMILY, + SxcConstants.TABLE_CELL_STYLE_FAMILY }; + Class classes[] = new Class[] { ColumnStyle.class, + RowStyle.class, + CellStyle.class}; + + /* + * Process the content XML for any other style info. + * Should only be automatic types here. + */ + nl = contentDom.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + if (nl.getLength() != 0) { + styleCat.add(nl.item(0), families, classes, null, false); + } + } + + /** + * This method traverses <i>office:body</i> <code>Element</code>. + * + * @param node <i>office:body</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void traverseBody(Node node) throws IOException { + + Debug.log(Debug.TRACE, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + Debug.log(Debug.TRACE, "<DEBUGLOG>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + Node searchNode = nodeList.item(i); + if (searchNode.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = searchNode.getNodeName(); + + if (nodeName.equals(TAG_NAMED_EXPRESSIONS)) { + + traverseNamedExpressions(searchNode); + + } else { + + Debug.log(Debug.TRACE, "Skipping " + XmlUtil.getNodeInfo(searchNode) + " />"); + } + } + } + + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_TABLE)) { + + traverseTable(child); + + } else { + + Debug.log(Debug.TRACE, "<OTHERS " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + Debug.log(Debug.TRACE, "</DEBUGLOG>"); + } + + + /** + * This method traverses the <i>table:table</i> element + * <code>Node</code>. + * + * @param node A <i>table:table</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void traverseNamedExpressions(Node node) throws IOException { + + Debug.log(Debug.TRACE, "<NAMED:EXPRESSIONS>"); + + NamedNodeMap att = node.getAttributes(); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + NameDefinition nd = new NameDefinition(child); + encoder.setNameDefinition(nd); + } + } + } + + Debug.log(Debug.TRACE, "</NAMED:EXPRESSIONS>"); + } + + /** + * This method traverses the <i>table:table</i> element + * <code>Node</code>. + * + * @param node A <i>table:table</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void traverseTable(Node node) throws IOException { + + Debug.log(Debug.TRACE, "<TABLE>"); + + ColumnRowList = new Vector(); + + // Get table attributes + // TODO - extract style from attribute + + NamedNodeMap att = node.getAttributes(); + + String tableName = + att.getNamedItem(ATTRIBUTE_TABLE_NAME).getNodeValue(); + + rowID = 1; + + encoder.createWorksheet(tableName); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_TABLE_ROW)) { + // TODO - handle all the possible rows + // spelled out in the entities + + traverseTableRow(child); + + } else if (nodeName.equals(TAG_TABLE_COLUMN)) { + + traverseTableColumn(child); + + } else if (nodeName.equals(TAG_TABLE_SCENARIO)) { + + // TODO + + } else { + + Debug.log(Debug.TRACE, "<OTHERS " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + // Add column width info to the current sheet + encoder.setColumnRows(ColumnRowList); + + Debug.log(Debug.TRACE, "</TABLE>"); + } + + /** + * This method traverses the <i>table:table-row</i> element + * <code>Node</code>. + * + * @param node A <i>table:table-row</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void traverseTableRow(Node node) throws IOException { + + // Get the attributes of the row + NamedNodeMap cellAtt = node.getAttributes(); + + if (cellAtt != null) { + + Node rowStyle = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_STYLE_NAME); + + Node tableNumRowRepeatingNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_NUM_ROWS_REPEATED); + int repeatedRows = 1; + + if(tableNumRowRepeatingNode!=null) { + String repeatStr = tableNumRowRepeatingNode.getNodeValue(); + Debug.log(Debug.TRACE, "traverseTableRow() repeated-rows : " + repeatStr); + repeatedRows = Integer.parseInt(repeatStr); + } + + String styleName = new String(""); + + if ( rowStyle != null) { + styleName = rowStyle.getNodeValue(); + } + if(styleName.equalsIgnoreCase("Default") || styleName.length()==0) { + + Debug.log(Debug.TRACE, "No defined Row Style Attribute was found"); + + } else { + + RowStyle rStyle = ( RowStyle)styleCat.lookup(styleName, + SxcConstants.ROW_STYLE_FAMILY, null, + RowStyle.class); + + int rowHeight = rStyle.getRowHeight(); + + Debug.log(Debug.TRACE, "traverseTableRow() Row Height : " + rowHeight); + ColumnRowInfo ri = new ColumnRowInfo( rowHeight, + repeatedRows, + ColumnRowInfo.ROW, + rowHeight!=0); + ColumnRowList.add(ri); + } + + // Get the attribute representing the number of rows repeated + Node rowsRepeatedNode = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_NUM_ROWS_REPEATED); + + // There is a number of rows repeated attribute: + if (rowsRepeatedNode != null) { + + // Get the number of times the row is repeated + String rowsRepeatedString = rowsRepeatedNode.getNodeValue(); + + Integer rowsRepeatedInt = new Integer(rowsRepeatedString); + + rowsRepeated = rowsRepeatedInt.intValue(); + + } else { + + // The row is not repeated + rowsRepeated = 1; + } + } + + Debug.log(Debug.TRACE, "<TR>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_TABLE_CELL)) { + + traverseCell(child); + + } else { + + Debug.log(Debug.TRACE, "<OTHERS " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + // Increase the row counter by the number of rows which are repeated + rowID += rowsRepeated; + + // Re-initialize number of rows repeated before processing the next + // row data. + rowsRepeated = 1; + + // When starting a new row, set the column counter back to the + // first column. + colID = 1; + + // Re-initialize number of columns repeated before processing + // the next row data. + colsRepeated = 1; + + Debug.log(Debug.TRACE, "</TR>"); + } + + + /** + * This method traverses the <i>table:table-column</i> + * <code>Node</code>. Not yet implemented. + * + * @param node A <i>table:table-column</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void traverseTableColumn(Node node) throws IOException { + + Debug.log(Debug.TRACE, "traverseColumn() : "); + NamedNodeMap cellAtt = node.getAttributes(); + Node tableStyleNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STYLE_NAME); + Node tableNumColRepeatingNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED); + Node tableDefaultCellStyle = cellAtt.getNamedItem(ATTRIBUTE_DEFAULT_CELL_STYLE); + + int repeatedColumns = 1; + int columnWidth = 0; + ColumnRowInfo col = new ColumnRowInfo(ColumnRowInfo.COLUMN); + + if(tableNumColRepeatingNode!=null) { + Debug.log(Debug.TRACE, "traverseColumn() repeated-cols : " + tableNumColRepeatingNode.getNodeValue()); + repeatedColumns = Integer.parseInt(tableNumColRepeatingNode.getNodeValue()); + col.setRepeated(repeatedColumns); + } + + String cellStyleName = new String(""); + + if(tableDefaultCellStyle!=null) { + cellStyleName = tableDefaultCellStyle.getNodeValue(); + + Debug.log(Debug.TRACE, "traverseColumn() default-cell-style : " + cellStyleName); + } + + if(cellStyleName.equalsIgnoreCase("Default") || cellStyleName.length()==0) { + + Debug.log(Debug.TRACE, "No default cell Style Attribute was found"); + + } else { + + CellStyle cellStyle = (CellStyle)styleCat.lookup(cellStyleName, + SxcConstants.TABLE_CELL_STYLE_FAMILY, null, + CellStyle.class); + Format defaultFmt = new Format(cellStyle.getFormat()); + col.setFormat(defaultFmt); + } + + String styleName = new String(""); + + if(tableStyleNode!=null) { + styleName = tableStyleNode.getNodeValue(); + } + + if(styleName.equalsIgnoreCase("Default") || styleName.length()==0) { + + Debug.log(Debug.TRACE, "No defined Style Attribute was found"); + + } else { + + ColumnStyle cStyle = (ColumnStyle)styleCat.lookup(styleName, + SxcConstants.COLUMN_STYLE_FAMILY, null, + ColumnStyle.class); + + columnWidth = cStyle.getColWidth(); + col.setSize(columnWidth); + Debug.log(Debug.TRACE, "traverseColumn() Column Width : " + columnWidth); + + } + ColumnRowList.add(col); + } + + /** + * This method traverses a <i>table:table-cell</i> element + * <code>Node</code>. + * + * @param node a <i>table:table-cell</i> <code>Node</code>. + * + * @throws IOException if any I/O error occurs. + */ + protected void traverseCell(Node node) throws IOException { + + NamedNodeMap cellAtt = node.getAttributes(); + + int debug_i=0; + Node debug_attrib = null; + fmt.clearFormatting(); + if (cellAtt == null || cellAtt.item(0) == null) + { + Debug.log(Debug.INFO, "No Cell Attributes\n"); + // return; + } + else + { + while ((debug_attrib = cellAtt.item(debug_i++)) != null) + { + Debug.log(Debug.INFO, "Cell Attribute " + debug_i + + ": " + debug_attrib.getNodeName() + " : " + + debug_attrib.getNodeValue() + "\n"); + } + } + + // Get the type of data in the cell + Node tableValueTypeNode = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE_TYPE); + + // Get the number of columns this cell is repeated + Node colsRepeatedNode = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED); + + // Get the style type + Node tableStyleNode = + cellAtt.getNamedItem(ATTRIBUTE_TABLE_STYLE_NAME); + + String styleName = new String(""); + + if(tableStyleNode!=null) { + styleName = tableStyleNode.getNodeValue(); + } + + if(styleName.equalsIgnoreCase("Default")) { + + Debug.log(Debug.TRACE, "No defined Style Attribute was found"); + + } else if(styleName.length()!=0) { + + CellStyle cStyle = (CellStyle)styleCat.lookup(styleName, + SxcConstants.TABLE_CELL_STYLE_FAMILY, null, + CellStyle.class); + + Format definedFormat = cStyle.getFormat(); + fmt = new Format(definedFormat); + } + + // There is a number of cols repeated attribute + if (colsRepeatedNode != null) { + + // Get the number of times the cell is repeated + String colsRepeatedString = colsRepeatedNode.getNodeValue(); + + Integer colsRepeatedInt = new Integer(colsRepeatedString); + colsRepeated = colsRepeatedInt.intValue(); + } else { + + // The cell is not repeated + colsRepeated = 1; + } + + + // if there is no style we need to check to see if there is a default + // cell style defined in the table-column's + + if (fmt.isDefault() && styleName.length()==0) { + int index = 1; + for(Enumeration e = ColumnRowList.elements();e.hasMoreElements();) { + ColumnRowInfo cri = (ColumnRowInfo) e.nextElement(); + if(cri.isColumn()) { + if(colID>=index && colID<(index+cri.getRepeated())) { + fmt = new Format(cri.getFormat()); + } + index += cri.getRepeated(); + } + } + } + + + // for (int j = 0; j < colsRepeated; j++) { + + + if (tableValueTypeNode != null) { + + // Make sure we initialize to 0 the width of the current cell + displayWidth = 0; + + String cellType = + tableValueTypeNode.getNodeValue(); + + if (cellType.equalsIgnoreCase(CELLTYPE_STRING)) { + + // has text:p tag + fmt.setCategory(CELLTYPE_STRING); + Node tableStringValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STRING_VALUE); + Debug.log(Debug.TRACE,"Cell Type String : " + tableStringValueNode); + if(tableStringValueNode != null) { + fmt.setValue(tableStringValueNode.getNodeValue()); + } + + } else if (cellType.equalsIgnoreCase(CELLTYPE_FLOAT)) { + + // has table:value attribute + // has text:p tag + + // Determine the number of decimal places StarCalc + // is displaying for this floating point output. + fmt.setCategory(CELLTYPE_FLOAT); + fmt.setDecimalPlaces(getDecimalPlaces(node)); + Node tableValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE); + fmt.setValue(tableValueNode.getNodeValue()); + + + } else if (cellType.equalsIgnoreCase(CELLTYPE_TIME)) { + + // has table:time-value attribute + // has text:p tag - which is the value we convert + + fmt.setCategory(CELLTYPE_TIME); + Node tableTimeNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_TIME_VALUE); + fmt.setValue(tableTimeNode.getNodeValue()); + + } else if (cellType.equalsIgnoreCase(CELLTYPE_DATE)) { + + // has table:date-value attribute + // has text:p tag - which is the value we convert + + fmt.setCategory(CELLTYPE_DATE); + Node tableDateNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_DATE_VALUE); + fmt.setValue(tableDateNode.getNodeValue()); + + } else if (cellType.equalsIgnoreCase(CELLTYPE_CURRENCY)) { + + // has table:currency + // has table:value attribute + // has text:p tag + + fmt.setCategory(CELLTYPE_CURRENCY); + fmt.setDecimalPlaces(getDecimalPlaces(node)); + Node tableValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE); + fmt.setValue(tableValueNode.getNodeValue()); + + } else if (cellType.equalsIgnoreCase(CELLTYPE_BOOLEAN)) { + + // has table:boolean-value attribute + // has text:p tag - which is the value we convert + + fmt.setCategory(CELLTYPE_BOOLEAN); + Node tableBooleanNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_BOOLEAN_VALUE); + fmt.setValue(tableBooleanNode.getNodeValue()); + + } else if (cellType.equalsIgnoreCase(CELLTYPE_PERCENT)) { + + // has table:value attribute + // has text:p tag + + fmt.setCategory(CELLTYPE_PERCENT); + fmt.setDecimalPlaces(getDecimalPlaces(node)); + Node tableValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_VALUE); + fmt.setValue(tableValueNode.getNodeValue()); + + } else { + + Debug.log(Debug.TRACE,"No defined value type" + cellType); + // Should never get here + + } + } + + Node tableFormulaNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_FORMULA); + + if(tableFormulaNode != null) + { + if(tableValueTypeNode == null) { // If there is no value-type Node we must assume string-value + fmt.setCategory(CELLTYPE_STRING); + Node tableStringValueNode = cellAtt.getNamedItem(ATTRIBUTE_TABLE_STRING_VALUE); + fmt.setValue(tableStringValueNode.getNodeValue()); + } + String cellFormula = tableFormulaNode.getNodeValue(); + addCell(cellFormula); + } else { + + // Text node, Date node, or Time node + // + Debug.log(Debug.INFO, + "TextNode, DateNode, TimeNode or BooleanNode\n"); + // This handles the case where we have style information but no content + if (node.hasChildNodes()) { + NodeList childList = node.getChildNodes(); + int len = childList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = childList.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + String childName = child.getNodeName(); + if (childName.equals(TAG_PARAGRAPH)) { + traverseParagraph(child); + } + } + } + } else if(!fmt.isDefault()) { + addCell(""); + } + } + + // Clear out format for current cell after it is written + format = 0; + + // Increase the column counter by the number of times the + // last cell was repeated. + colID += colsRepeated; + + // Re-initialize the number of columns repeated before processing + // the next cell data. + colsRepeated = 1; + + } + + + /** + * This method traverses the <i>text:p</i> element <code>Node</code>. + * + * @param node A <i>text:p</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void traverseParagraph(Node node) throws IOException { + + NamedNodeMap cellAtt = node.getAttributes(); + + int debug_i=0; + Node debug_attrib = null; + if (cellAtt == null || cellAtt.item(0) == null) + { + Debug.log(Debug.INFO, "No Paragraph Attributes\n"); + } + else + { + while ((debug_attrib = cellAtt.item(debug_i++)) != null) + { + Debug.log(Debug.INFO, "Paragraph Attribute " + debug_i + + ": " + debug_attrib.getNodeName() + " : " + + debug_attrib.getNodeValue() + "\n"); + } + } + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + + int len = nodeList.getLength(); + + StringBuffer buffer = new StringBuffer(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + // TODO: need to handle space/tabs/newline nodes later + short nodeType = child.getNodeType(); + + switch (nodeType) { + + case Node.TEXT_NODE: + buffer.append(child.getNodeValue()); + break; + + case Node.ENTITY_REFERENCE_NODE: + + NodeList nodeList2 = child.getChildNodes(); + int len2 = nodeList2.getLength(); + + for (int j = 0; j < len2; j++) { + Node child2 = nodeList2.item(j); + + if (child2.getNodeType() == Node.TEXT_NODE) { + buffer.append(child2.getNodeValue()); + } + } + + break; + } + } + + String s = buffer.toString(); + // displayWidth = calculateContentWidth(s); + addCell(s); + + } + } + + + /** + * This method will take the input cell value and add + * it to the spreadsheet <code>Document</code> we are currently + * encoding. This method correctly handles cells that are + * repeated in either the row, cell, or both directions. + * + * @param cellValue The contents of the cell we want to add + * to the spreadsheet <code>Document</code>. + * + * @throws IOException If any I/O error occurs. + */ + protected void addCell(String cellValue) throws IOException { + + int col = colID; + int row = rowID; + + for (int i = 0; i < rowsRepeated; i++) { + + // Log the columns when there are rowsRepeated. + if (i > 0) { + Debug.log(Debug.TRACE, "</TR>"); + Debug.log(Debug.TRACE, "<TR>"); + } + + col = colID; + + for (int j = 0; j < colsRepeated; j++) { + + Debug.log(Debug.TRACE, "<TD>"); + + + // Add the cell data to the encoded spreadsheet document + encoder.addCell(row, col, fmt, cellValue); + + Debug.log(Debug.TRACE, cellValue); + Debug.log(Debug.TRACE, "</TD>"); + + col++; + } + + row++; + + } + + } + + + + /** + * This method takes a <i>table:table-cell</i> <code>Node</code> + * and traverses down to the <i>text:p</i> tag. The value is + * extracted from the <i>text:p</i> tag and the number of decimal + * places is calculated. + * + * @param node A <i>table:table-cell</i> <code>Node</code>. + * + * @return The number of decimal places in the display + * string of the data in the input <code>Node</code>. + */ + protected int getDecimalPlaces(Node node) { + + int decimals = 0; + + Element element = null; + + // cast org.w3c.dom.Node to org.w3c.dom.Element + if (node instanceof Element) { + element = (Element) node; + } else { + return decimals; + } + + // Traverse to the text:p element, there should only be one. + NodeList list = element.getElementsByTagName(TAG_PARAGRAPH); + + if (list.getLength() != 1) { + return decimals; + } + + Node paragraph = list.item(0); + + if (paragraph.hasChildNodes()) { + + NodeList nodeList = paragraph.getChildNodes(); + + int len = nodeList.getLength(); + + for (int j = 0; j < len; j++) { + + Node child = nodeList.item(j); + + if (child.getNodeType() == Node.TEXT_NODE) { + + String s = child.getNodeValue(); + + // displayWidth = calculateContentWidth(s); + + int k = s.lastIndexOf("."); + if (k > 0) { + s = s.substring(k+1); + decimals = s.length(); + } + } + } + } + + return decimals; + } + + /* + * Utility method to retrieve a Node attribute. + */ + private String getAttribute (Node node, String attribute) { + NamedNodeMap attrNodes = node.getAttributes(); + + if (attrNodes != null) { + Node attr = attrNodes.getNamedItem(attribute); + if (attr != null) { + return attr.getNodeValue(); + } + } + return null; + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcPluginFactory.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcPluginFactory.java new file mode 100644 index 000000000000..5ad490f332dc --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/SxcPluginFactory.java @@ -0,0 +1,86 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcPluginFactory.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc; + +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.registry.ConverterInfo; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.PluginFactory; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentMergerFactory; + + +/** + * General implementation of the <code>PluginFactory</code> interface + * for SXC <code>Document</code> objects. + * + * @see org.openoffice.xmerge.DocumentDeserializer + * @see org.openoffice.xmerge.DocumentMerger + * @see org.openoffice.xmerge.DocumentSerializer + */ +public abstract class SxcPluginFactory + extends PluginFactory implements DocumentMergerFactory { + + + /** + * Constructor that caches the <code>ConvertInfo</code> that + * corresponds to the registry information for this plug-in. + * + * @param ci <code>ConvertInfo</code> object. + */ + public SxcPluginFactory(ConverterInfo ci) { + super(ci); + } + + + public Document createOfficeDocument(String name, InputStream is) + throws IOException { + + // read zipped XML stream + // + SxcDocument doc = new SxcDocument(name); + doc.read(is); + return doc; + } + + public Document createOfficeDocument(String name, InputStream is,boolean isZip) + throws IOException { + + // read zipped XML stream + // + SxcDocument doc = new SxcDocument(name); + doc.read(is,isZip); + return doc; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/build.xml new file mode 100644 index 000000000000..d8219c1f46a5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/build.xml @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.9 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcx_sxc" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcx_sxc"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxc"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/CellStyle.java"/> + <include name="${package}/ColumnStyle.java"/> + <include name="${package}/ColumnRowInfo.java"/> + <include name="${package}/RowStyle.java"/> + <include name="${package}/SxcConstants.java"/> + <include name="${package}/SxcDocument.java"/> + <include name="${package}/Format.java"/> + <include name="${package}/BookSettings.java"/> + <include name="${package}/SheetSettings.java"/> + <include name="${package}/NameDefinition.java"/> + <include name="${package}/SpreadsheetDecoder.java"/> + <include name="${package}/SpreadsheetEncoder.java"/> + <include name="${package}/SxcDocumentDeserializer.java"/> + <include name="${package}/SxcDocumentSerializer.java"/> + <include name="${package}/DocumentMergerImpl.java"/> + <include name="${package}/SxcPluginFactory.java"/> + + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/makefile.mk new file mode 100644 index 000000000000..1c2e06d1ef57 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcx_sxc +PRJ=../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/ConverterCapabilitiesImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..54ce2e236a4d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/ConverterCapabilitiesImpl.java @@ -0,0 +1,116 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterCapabilitiesImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + + +/** + * <p>MiniCalc implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarCalc SXC to/from MiniCalc conversions. The + * <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE_ROW.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE_COLUMN.equals(tag)) + return false; + // TODO - we currently do not handle the table column tag + else if (OfficeConstants.TAG_TABLE_SCENARIO.equals(tag)) + return false; + // TODO - we currently do not handle the table scenario tag + else if (OfficeConstants.TAG_TABLE_CELL.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_TABLE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_NAME.equals(attribute)) + return true; + + } else if (OfficeConstants.TAG_TABLE_CELL.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_VALUE_TYPE.equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_FORMULA. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_VALUE.equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_BOOLEAN_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_CURRENCY. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_TIME_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_DATE_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED. + equals(attribute)) + return true; + + } else if (OfficeConstants.TAG_TABLE_ROW.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_NUM_ROWS_REPEATED. + equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcConstants.java new file mode 100644 index 000000000000..c14178ee96e1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcConstants.java @@ -0,0 +1,48 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: MinicalcConstants.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.converter.palm.PdbUtil; + +/** + * Constants used for encoding and decoding the MiniCalc format. + * + * @author Herbie Ong + */ +interface MinicalcConstants { + + /** Creator ID. */ + public static final int CREATOR_ID = PdbUtil.intID("PiMC"); + + /** Type ID. */ + public static final int TYPE_ID = PdbUtil.intID("Data"); +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java new file mode 100644 index 000000000000..77bfe75539b8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java @@ -0,0 +1,548 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: MinicalcDataString.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +/** + * This class is used by <code>MinicalcDecoder</code> to manipulate a + * <code>String</code> containing MiniCalc cell data. + * + * @author Paul Rank + */ +public class MinicalcDataString { + + /** The String representation of the MiniCalc data. */ + private String data = null; + + + /** + * Constructor stores the MiniCalc data <code>String</code>. + * + * @param data A <code>String</code> containing MiniCalc + * cell data. + */ + public MinicalcDataString(String data) { + this.data = data; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>formula</i>. + * + * @return true if the MiniCalc data <code>String</code> is a + * <i>formula</i>, false if the MiniCalc data <code>String</code> + * is not a <i>formula</i>. + */ + public boolean isFormula() { + + if (data.startsWith("=")) { + return true; + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>percentage</i>. + * + * @return true if the MiniCalc data <code>String</code> is a + * <i>percentage</i>, false if the MiniCalc data + * <code>String</code> is not a <i>percentage</i>. + */ + public boolean isPercent() { + + if (data.endsWith("%")) { + return true; + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a + * <i>boolean</i> value. + * + * @return true if the MiniCalc data <code>String</code> is + * a <i>boolean</i>, false if the MiniCalc data + * <code>String</code> is not a <i>boolean</i>. + */ + public boolean isBoolean() { + + if (data.equalsIgnoreCase("false") || + data.equalsIgnoreCase("true")) { + return true; + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>date</i>. + * + * @return true if the MiniCalc data <code>String</code> is + * a <i>date</i>, false if the MiniCalc data <code>String</code> + * is not a <i>date</i>. + */ + public boolean isDate() { + + // Starting index into the date string - month + int start = 0; + + // Search for "/", which separates month from day + int end = data.indexOf("/"); + + // Separator was found + if (end > 0) { + + String monthString = data.substring(start, end); + + try { + Float f = Float.valueOf(monthString); + if ((f.intValue() < 0) || (f.intValue() > 12)) { + return false; + } + } + catch (NumberFormatException e) { + + // no, it is not a currency type + return false; + } + + // start is now the starting index of day + start = end+1; + + // Search for "/", which separates day from year + end = data.indexOf("/", start); + + // Separator was found + if (end > 0) { + + String dayString = data.substring(start, end); + + try { + Float f = Float.valueOf(dayString); + if ((f.intValue() < 0) || (f.intValue() > 31)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a currency type + return false; + } + } else { + return false; + } + + // start is now at the starting index of the year + start = end + 1; + + String yearString = data.substring(start); + try { + Float f = Float.valueOf(yearString); + if (f.intValue() < 0) { + return false; + } + } + catch (NumberFormatException e) { + // no, it is not a currency type + return false; + } + + } else { + return false; + } + + return true; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>time</i>. + * + * @return true if the MiniCalc data <code>String</code> + * is a <i>time</i>, false if the MiniCalc data + * <code>String</code> is not a <i>time</i>. + */ + public boolean isTime() { + + // Starting index into the time string - hour + int start = 0; + + // Search for ":", which separates hour from minute + int end = data.indexOf(":"); + + + // Separator was found + if (end > 0) { + + String hourString = data.substring(start, end); + try { + Float f = Float.valueOf(hourString); + if ((f.intValue() < 0) || (f.intValue() > 24)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a time type + return false; + } + + // start is now the starting index of minute + start = end+1; + + // Search for ":", which separates minute from second + end = data.indexOf(":", start); + + // Separator was found + if (end > 0) { + + String minuteString = data.substring(start, end); + + try { + Float f = Float.valueOf(minuteString); + if ((f.intValue() < 0) || (f.intValue() > 60)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a time type + return false; + } + + // start is now at the starting index of the seconds + start = end+1; + + // The seconds are in the string + if (data.length() > start) { + + String secondString = data.substring(start); + + + try { + Float f = Float.valueOf(secondString); + if ((f.intValue() < 0) || (f.intValue() > 60)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a time type + return false; + } + } + + } + + return true; + + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>currency</i> + * value. + * + * @return true if the MiniCalc data <code>String</code> is + * a <i>currency</i>, false if the MiniCalc data + * <code>String</code> is not a <i>currency</i>. + */ + public boolean isCurrency() { + + boolean result = false; + + // TODO - we currently only check for US currencies + + if (data.endsWith("$")) { + String number = data.substring(0, data.length()-1); + try { + Float f = Float.valueOf(number); + result = true; + } + catch (NumberFormatException e) { + // no, it is not a currency type + result = false; + } + } + + else if (data.startsWith("$")) { + String number = data.substring(1, data.length()); + try { + Float f = Float.valueOf(number); + result = true; + } + catch (NumberFormatException e) { + // no, it is not a currency type + result = false; + } + } + + return result; + + } + + + /** + * This method removes the percent sign from the MiniCalc data + * <code>String</code>. If the percent sign is not the last + * character of the MiniCalc data <code>String</code>, the + * MiniCalc data <code>String</code> is returned. + * + * @return The MiniCalc data <code>String</code> minus the + * percent sign. If the MiniCalc data <code>String</code> + * does not begin with a percent sign, the MiniCalc data + * <code>String</code> is returned. + */ + public String percentRemoveSign() { + + String number = data; + + if (data.endsWith("%")) { + // "%" is the last character, so remove + number = data.substring(0, data.length()-1); + + try { + Float f = Float.valueOf(number); + float f1 = f.floatValue()/100f; + Float f2 = new Float(f1); + number = f2.toString(); + } + catch (NumberFormatException e) { + // no, it is not a float type + } + } + + return number; + } + + + /** + * This method removes the currency sign from the MiniCalc data + * <code>String</code>. If the currency sign is not the first or + * last character of the MiniCalc data <code>String</code>, the + * MiniCalc data <code>String</code> is returned. + * + * @return The MiniCalc data <code>String</code> minus the currency + * sign. If the MiniCalc data <code>String</code> does not + * begin or end with a currency sign, the MiniCalc + * data <code>String</code> is returned. + */ + public String currencyRemoveSign() { + + String number = data; + + // TODO - only works with US currencies + + if (data.endsWith("$")) { + + number = data.substring(0, data.length()-1); + + } else if (data.startsWith("$")) { + + number = data.substring(1, data.length()); + } + + return number; + + } + + + /** + * <p>This method converts a MiniCalc date from MiniCalc + * format to StarOffice XML format.</p> + * + * <p>MiniCalc format:</p> + * + * <p><blockquote> + * MM/DD/YY or MM/DD/YYYY + * </blockquote></p> + * + * <p>StarOffice XML format:</p> + * + * <p><blockquote> + * YYYY-MM-DD + * </blockquote></p> + * + * @return The MiniCalc date converted to StarOffice XML + * format. + */ + public String convertToStarDate() { + + // The output date string + String out; + + String monthString = "01"; + String dayString = "01"; + String yearString = "1900"; + + // Starting index into the date string - month + int start = 0; + + // Search for "/", which separates month from day + int end = data.indexOf("/"); + + // Separator was found + if (end > 0) { + + monthString = data.substring(start, end); + + Integer monthInt = new Integer(monthString); + + // Make sure month is 2 digits + if (monthInt.intValue() < 10) { + monthString = "0" + monthString; + } + + // start is now the starting index of day + start = end+1; + + // Search for "/", which separates day from year + end = data.indexOf("/", start); + + // Separator was found + if (end > 0) { + + dayString = data.substring(start, end); + + Integer dayInt = new Integer(dayString); + + // Make sure day is 2 digits + if (dayInt.intValue() < 10) { + dayString = "0" + dayString; + } + + // start is now at the starting index of the year + start = end + 1; + + // The year is in the string + if (data.length() > start) { + + yearString = data.substring(start); + + Integer yearInt = new Integer(yearString); + int year = yearInt.intValue(); + + if (year < 31) { + + // MiniCalc years between 0 and 30 correspond to + // 2000 - 2030 + year += 2000; + + } else if (year < 100) { + + // MiniCalc years between 31 and 99 correspond + // to 1931 - 1999 + year += 1900; + } + + yearString = Integer.toString(year); + } + } + } + + // Set out to StarOffice XML date format + out = yearString + "-" + monthString + "-" + dayString; + + return out; + } + + + /** + * This method converts the MiniCalc time from MiniCalc + * format to StarOffice XML format. + * + * <p>MiniCalc format:</p> + * + * <p><blockquote> + * hh:mm:ss + * </blockquote></p> + * + * <p>StarOffice XML format:</p> + * + * <p><blockquote> + * PThhHmmMssS + * </blockquote></p> + * + * @return The MiniCalc time converted to StarOffice XML + * format. + */ + public String convertToStarTime() { + + // The output time string + String out; + + String hourString = "00"; + String minuteString = "00"; + String secondString = "00"; + + // Starting index into the time string - hour + int start = 0; + + // Search for ":", which separates hour from minute + int end = data.indexOf(":"); + + // Separator was found + if (end > 0) { + + hourString = data.substring(start, end); + + // start is now the starting index of minute + start = end+1; + + // Search for ":", which separates minute from second + end = data.indexOf(":", start); + + // Separator was found + if (end > 0) { + + minuteString = data.substring(start, end); + + // start is now at the starting index of the seconds + start = end+1; + + // The seconds are in the string + if (data.length() > start) { + + secondString = data.substring(start); + } + + } + } + + // TODO - PT is for pacific time, where can we get the + // localized value from? + + // Set to StarOffice XML time format + out = "PT"+hourString+"H"+minuteString+"M"+secondString+"S"; + + return out; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java new file mode 100644 index 000000000000..1df98ae65455 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java @@ -0,0 +1,747 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: MinicalcDecoder.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import jmc.Workbook; +import jmc.Worksheet; +import jmc.CellAttributes; +import jmc.CellDescriptor; +import jmc.JMCconstants; +import jmc.JMCException; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializer; +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetDecoder; +import org.openoffice.xmerge.converter.xml.sxc.Format; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializerImpl} + * SxcDocumentDeserializerImpl} to decode the MiniCalc format. + * + * @author Paul Rank + */ +final class MinicalcDecoder extends SpreadsheetDecoder { + + /** MiniCalc WorkBook to store sheets. */ + private Workbook wb; + + /** MiniCalc sheet - only one sheet can be open at a time. */ + private Worksheet ws; + + /** The current cell - only one cell can be active at a time. */ + private CellDescriptor cell = null; + + /** Format object describing the current cell. */ + private Format fmt = null; + + /** The password for the WorkBook. */ + private String password = null; + + /** The number of rows in the current WorkSheet. */ + private int maxRows = 0; + + /** The number of columns in the current WorkSheet. */ + private int maxCols = 0; + + /** The names of the worksheets. */ + private String[] worksheetNames = null; + + /** + * Constructor creates a MiniCalc WorkBook. + * + * @param name The name of the WorkBook. + * @param password The password for the workBook. + * + * @throws IOException If any I/O error occurs. + */ + MinicalcDecoder(String name, String[] worksheetNames, String password) throws IOException { + + super(name, password); + + fmt = new Format(); + + this.password = password; + this.worksheetNames = worksheetNames; + + try { + + wb = new Workbook(name, password); + + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.constructor:" + e.getMessage()); + + throw new IOException(e.getMessage()); + // e.printStackTrace(); + + } + } + + + /** + * This method takes a <code>ConvertData</code> as input and + * converts it into a MiniCalc WorkSheet. The WorkSheet is then + * added to the WorkBook. + * + * @param InputStream An <code>ConvertData</code> containing a + * MiniCalc WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public void addDeviceContent(ConvertData cd) throws IOException { + + try { + PalmDocument palmDoc; + int j = 0; + + Enumeration e = cd.getDocumentEnumeration(); + while(e.hasMoreElements()) { + + palmDoc = (PalmDocument) e.nextElement(); + // Convert PDB to WorkBook/WorkSheet format + PalmDB pdb = palmDoc.getPdb(); + + // This will be done at least once + String sheetName = worksheetNames[j]; + + // Get number of records in the pdb + int numRecords = pdb.getRecordCount(); + + // sheetName does not contain the WorkBook name, but we need the + // full name. + String fullSheetName = new String(wb.getWorkbookName() + "-" + sheetName); + + // Create a new (empty) WorkSheet + ws = new Worksheet(); + + // Initialize the WorkSheet + ws.initWorksheet(fullSheetName, numRecords); + + // Loop over the number of records in the PDB + for (int i = 0; i < numRecords; i++) { + + // Read record i from the PDB + Record rec = pdb.getRecord(i); + + byte cBytes[] = rec.getBytes(); + + // Create an InputStream + ByteArrayInputStream bis = new ByteArrayInputStream(cBytes); + + // Get the size of the stream + int bisSize = cBytes.length; + + // Add each record to the WorkSheet + ws.readNextRecord(bis, bisSize); + } + + + // Add the WorkSheet to the WorkBook + wb.addWorksheet(ws); + j++; + } + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.addPDB:" + e.getMessage()); + + throw new IOException(e.getMessage()); + } + } + + + /** + * This method returns the number of spreadsheets + * stored in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public int getNumberOfSheets() { + + return wb.getNumberOfSheets(); + } + + + /** + * This method gets the requested WorkSheet from the + * WorkBook and sets it as the selected WorkSheet. All + * other "get" methods will now get data from this WorkSheet. + * + * @param sheetIndex The index number of the sheet to open. + * + * @throws IOException If any I/O error occurs. + */ + public void setWorksheet(int sheetIndex) throws IOException { + + try { + + ws = wb.getWorksheet(sheetIndex); + + // Initialize access to the WorkSheet so that we can calculate + // the number of rows and columns + ws.initAccess(password); + + maxRows = 0; + maxCols = 0; + + while (goToNextCell()) { + maxRows = Math.max(maxRows, cell.getRowNumber()); + maxCols = Math.max(maxCols, cell.getColNumber()); + } + + // Re-initialize access to the WorkSheet + ws.initAccess(password); + + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.setWorksheet:" + e.getMessage()); + + throw new IOException(e.getMessage()); + // e.printStackTrace(); + + } + } + + + /** + * This method returns the name of the current spreadsheet. + * + * @return The name of the current WorkSheet. + */ + public String getSheetName() { + + String sheetName = ws.getName(); + + return sheetName; + } + + + /** + * This method gets the next cell from the WorkSheet + * and sets it as the selected cell. All other "get" + * methods will now get data from this cell. + * + * @return True if we were able to go to another cell + * in the sheet, false if there were no cells + * left. + * + * @throws IOException If any I/O error occurs. + */ + public boolean goToNextCell() throws IOException { + + boolean gotCell = false; + + try { + cell = ws.getNextCell(); + + if (cell != null) { + gotCell = true; + } + + // As we read each cell, get its formatting info + readCellFormat(); + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.goToNextCell:" + e.getMessage()); + + throw new IOException(e.getMessage()); + // e.printStackTrace(); + + } + + return gotCell; + } + + + /** + * This method returns the row number of the current cell. + * + * @return The row number of the current cell. Returns + * -1 if no cell is currently selected. + */ + public int getRowNumber() { + + int row = -1; + + if (cell != null) { + + row = cell.getRowNumber(); + } + + return row; + } + + /** + * This method returns the number of rows in the current sheet. + * + * @return The number of rows in the current sheet. + */ + public int getNumberOfRows() { + + return maxRows; + } + + /** + * This method returns the number of columns in the current sheet. + * + * @return The number of columns in the current sheet. + */ + public int getNumberOfColumns() { + return maxCols; + } + + + /** + * This method returns the col number of the current cell. + * + * @return The col number of the current cell. Returns + * -1 if no cell is currently selected. + */ + public int getColNumber() { + + int col = -1; + + if (cell != null) { + + col = cell.getColNumber(); + } + + return col; + } + + + /** + * This method returns the contents of the current cell. + * + * @return The contents of the current cell. Returns + * null if no cell is currently selected. + */ + public String getCellContents() { + + String contents = null; + + if (cell != null) { + contents = cell.getCellContents(); + + // Active cell, but no content + if (contents == null) + return new String(""); + + // Does the cell contain a formula? + if (contents.startsWith("=")) { + contents = parseFormula(contents); + } + // Make sure that any MiniCalc peculiarities are stripped off + if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_CURRENCY)) { + contents = currencyRemoveSign(contents); + } + else if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_PERCENT)) { + contents = percentRemoveSign(contents); + } + else if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_DATE)) { + contents = convertToStarDate(contents); + } + else if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_TIME)) { + contents = convertToStarTime(contents); + } + } + + return contents; + } + + /** + * This method is meant to return the value of the formula cell. However + * in minicalc this value is not used so hence the stubbed function + * + * @return the value fo the formula cell + */ + public String getCellValue() { + return null; + } + + /** + * <p>This method takes a formula and parses it into + * StarOffice XML formula format.</p> + * + * <p>Many spreadsheets use ',' as a separator. + * StarOffice XML format uses ';' as a separator instead.</p> + * + * <p>Many spreadsheets use '!' as a separator when refencing + * a cell in a different sheet.</p> + * + * <blockquote> + * Example: =sheet1!A1 + * </blockquote> + * + * <p>StarOffice XML format uses '.' as a separator instead.</p> + * + * <blockquote> + * Example: =sheet1.A1 + * </blockquote> + * + * @param formula A formula string. + * + * @return A StarOffice XML format formula string. + */ + protected String parseFormula(String formula) { + + formula = formula.replace(',', ';'); + formula = formula.replace('!', '.'); + + return formula; + } + + /** + * <p>This method returns the type of the data in the current cell.</p> + * + * <p>Possible Data Types:</p> + * + * <ul><li> + * Percent - MiniCalc can store as a number or as a string. + * + * When stored as a string, the % sign is stored in the + * string . The MiniCalc format is "string". + * Example 10.1% is stored as the string "10.1%" + * + * When stored as a number, the decimal representation + * is stored. The MiniCalc format is "percentage". + * Example: 10.1% is stored as "0.101" + * </li><li> + * Currency - MiniCalc stores currency as a number with the format + * set to "currency". + * A user can also enter a value with a dollar sign + * (example $18.56) into MiniCalc and not set the format + * as currency. We treat this type of data as a + * currency data type. + * </li><li> + * Boolean - MiniCalc stores in a string as "true" or "false" + * </li><li> + * + * Date - MiniCalc stores a date in a string as either + * MM/DD/YY or MM/DD/YYYY. Any variation from the above + * format will not be considered a date. + * </li><li> + * Time - MiniCalc stores a time in a string as hh:mm:ss. Any + * variation from this format will not be considered a time. + * </li><li> + * Float - MiniCalc stores as a number and it is not percent + * or currency. + * </li><li> + * String - MiniCalc stores as a string (surprise). Doesn't parse + * to any of the other data types. + * </li><li> + * @return The type of the data in the current cell. + * </li></ul> + */ + public String getCellDataType() { + + boolean isNumber = false; + + // Get format value set on the cell in MiniCalc + String format = getCellFormatType(); + + // Initialize the data type to the format + String type = format; + + String contents = getCellContents(); + + if (contents != null) { + + MinicalcDataString data = new MinicalcDataString(contents); + + // Check if it is a formula + if (data.isFormula()) { + Debug.log(Debug.INFO, " " + contents + " Is a Function Format = " + + format + "\n"); + return type; + } + + try { + // Check to see if it is a number + Double d = Double.valueOf(contents); + isNumber = true; + Debug.log(Debug.INFO, " " + contents + " Is a Number Format = " + format); + + } catch (NumberFormatException e) { + Debug.log(Debug.INFO, " " + contents + " Not a Number Format= " + format); + // no, it is not a number + isNumber = false; + } + + + if (isNumber) { + + // Numbers are Float, Currency, and Percent + if (format.equals(OfficeConstants.CELLTYPE_CURRENCY)) { + + type = OfficeConstants.CELLTYPE_CURRENCY; + + } else if (format.equals(OfficeConstants.CELLTYPE_PERCENT)) { + + type = OfficeConstants.CELLTYPE_PERCENT; + + } else { + + type = OfficeConstants.CELLTYPE_FLOAT; + } + + } else if (data.isBoolean()) { + + // Data is a Boolean type + type = OfficeConstants.CELLTYPE_BOOLEAN; + + } else if (data.isDate()) { + + // Data is a Date type + type = OfficeConstants.CELLTYPE_DATE; + + } else if (data.isTime()) { + + // Data is a Time type + type = OfficeConstants.CELLTYPE_TIME; + + } else if (data.isPercent()) { + + // Data is percent + type = OfficeConstants.CELLTYPE_PERCENT; + + } else if (data.isCurrency()) { + + // Data is a Currency type + type = OfficeConstants.CELLTYPE_CURRENCY; + + } else { + + // Data can't be float, since it isn't a number + + // We've already tried parsing it as all other data + // types, the only remaining option is a string + type = OfficeConstants.CELLTYPE_STRING; + } + } + + Debug.log(Debug.INFO, " TYPE = " + type + "\n"); + + return type; + } + + + /** + * This method returns the format of the data in the current cell. + * + * @return The format of the data in the current cell. + */ + String getCellFormatType() { + + // Set type to default data type + String type = OfficeConstants.CELLTYPE_FLOAT; + + if (cell != null) { + + // Get the attributes for the current cell + CellAttributes att = cell.getCellAttributes(); + + if (att != null) { + + // Extract the format info from the attributes + long format = att.getFormat(); + + // The cell type is stored in bits 5-8 + long cellType = format & 0x000000F0L; + + // The number of decimal places is stored in bits 1-4 + long decimals = format & 0x0000000FL; + + if (cellType == JMCconstants.FF_FORMAT_GENERIC) { + + // MiniCalc stores both Strings and Booleans + // in the generic type. We must check the contents + // to differentiate between the two. + + // Get cell's contents + String contents = getCellContents(); + + if (contents.equalsIgnoreCase("false") || + contents.equalsIgnoreCase("true")) { + + type = OfficeConstants.CELLTYPE_BOOLEAN; + + + } else { + + type = OfficeConstants.CELLTYPE_STRING; + + } + + } else if (cellType == JMCconstants.FF_FORMAT_DECIMAL) { + + type = OfficeConstants.CELLTYPE_FLOAT; + + } else if (cellType == JMCconstants.FF_FORMAT_TIME) { + + type = OfficeConstants.CELLTYPE_TIME; + + } else if (cellType == JMCconstants.FF_FORMAT_DATE) { + + type = OfficeConstants.CELLTYPE_DATE; + + } else if (cellType == JMCconstants.FF_FORMAT_CURRENCY) { + + type = OfficeConstants.CELLTYPE_CURRENCY; + + } else if (cellType == JMCconstants.FF_FORMAT_PERCENT) { + + type = OfficeConstants.CELLTYPE_PERCENT; + } + + } + } + + return type; + } + + + /** + * This method takes a <code>String</code> that contains a + * currency value and removes the $ from the <code>String</code>. + * If the dollar sign is not the first or last character of the + * input <code>String</code>, the input <code>String</code> is + * simply returned. + * + * @param contents The input <code>String</code> from which to + * remove the dollar sign. + * + * @return The input <code>String</code> minus the dollar sign. + * If the input <code>String</code> did not begin or end + * with a dollar sign, contents is returned. + */ + private String currencyRemoveSign(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String currencyString = mcString.currencyRemoveSign(); + return currencyString; + } + + + /** + * This method takes a <code>String</code> that contains a percent + * value and removes the % from the <code>String</code>. If the + * percent sign is not the last character of the input + * <code>String</code>, the input <code>String</code> is simply + * returned. + * + * @param contents The input String from which to remove the + * percent sign. + * + * @return The input <code>String</code> minus the percent sign. + * If the input <code>String</code> did not begin with + * a percent sign, contents is returned. + */ + private String percentRemoveSign(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String percentString = mcString.percentRemoveSign(); + return percentString; + } + + + /** + * This method returns takes a <code>String</code> that contains + * a time value and converts it from MiniCalc format to StarOffice + * XML time format. + * + * @param contents The input <code>String</code> containing a + * MiniCalc time. + * + * @return The input <code>String</code> converted to StarOffice + * XML time format. + */ + private String convertToStarTime(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String timeString = mcString.convertToStarTime(); + return timeString; + } + + /** + * This method returns takes a <code>String</code> that contains + * a date value and converts it from MiniCalc format to StarOffice + * XML date format. + * + * @param contents The input <code>String</code> containing a + * MiniCalc date. + * + * @return The input <code>String</code> converted to StarOffice + * XML date format. + */ + private String convertToStarDate(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String dateString = mcString.convertToStarDate(); + return dateString; + } + + + /** + * Return the Format object describing the active cell formatting. + * + * @return The Format object describing the active cell formatting. + */ + public Format getCellFormat() { + return new Format(fmt); + } + + + /** + * Create the format data for the new cell. + */ + private void readCellFormat() { + // Make sure there are no remnants from the last time + fmt.clearFormatting(); + + fmt.setCategory(getCellFormatType()); + + // TODO - Get any more formatting data here + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcEncoder.java new file mode 100644 index 000000000000..60f68474554d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcEncoder.java @@ -0,0 +1,585 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: MinicalcEncoder.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import jmc.Workbook; +import jmc.Worksheet; +import jmc.CellAttributes; +import jmc.CellDescriptor; +import jmc.JMCconstants; +import jmc.JMCException; + +import java.awt.Color; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.IntArrayList; + +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetEncoder; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocumentSerializerImpl + * SxcDocumentSerializerImpl} to encode the MiniCalc format. + * + * @author Paul Rank + */ +final class MinicalcEncoder extends SpreadsheetEncoder { + + /** MiniCalc WorkBook to store sheets. */ + private Workbook wb; + + /** MiniCalc sheet - only one sheet can be open at a time. */ + private Worksheet ws; + + /** + * Estimate of the number of Palm pixels per character. Used for + * estimating the width of a cell on a Palm device. + */ + private final static int pixelsPerChar = 6; + + /** + * The minimum width (in pixels) that we allow a column to be set to + * on a Palm device. + */ + private final static int minWidth = 10; + + /** + * The maximum width (in pixels) that we allow a column to be set to + * on a Palm device. + */ + private final static int maxWidth = 80; + + + /** + * Constructor creates a MiniCalc WorkBook. + * + * @param log Log object for logging. + * @param name The name of the WorkBook. + * @param password The password for the WorkBook. + * + * @throws IOException If any I/O error occurs. + */ + MinicalcEncoder(String name, String password) throws IOException { + + super(name, password); + + try { + wb = new Workbook(name, password); + } + catch (JMCException e) { + Debug.log(Debug.ERROR, "new Workbook threw exception:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + } + + + /** + * This method creates a WorkSheet belonging to the + * WorkBook. + * + * @param sheetName The name of the WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public void createWorksheet(String sheetName) throws IOException { + + try { + ws = wb.createWorksheet(sheetName); + } + catch (JMCException e) { + Debug.log(Debug.ERROR, "wb.createWorksheet threw exception:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + } + + + /** + * This method gets the number of sheets in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public int getNumberOfSheets() { + + int numSheets = wb.getNumberOfSheets(); + return numSheets; + } + + + /** + * This method encodes the MiniCalc WorkBook information + * into an palm <code>Record</code> array in MiniCalc + * database format. + * + * @return Array of <code>Record</code> holding MiniCalc + * contents. + * + * @throws IOException If any I/O error occurs. + */ + public Record[] getRecords(int sheetID) throws IOException { + + // Get the WorkSheet for the input sheetID + ws = wb.getWorksheet(sheetID); + + // Need to call ws.initWrite() before we start querying the WorkSheet + try { + ws.initWrite(); + } + catch (JMCException e) { + Debug.log(Debug.ERROR, "ws.initWrite in getRecords:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + + // Get the number of records in the WorkSheet + int numRecords = ws.getNumberOfRecords(); + + // Create the Record array + Record[] allRecords = new Record[numRecords]; + + + // Get each record from the WorkSheet and store in allRecords[] + try { + for (int i = 0; i < allRecords.length; i++) { + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + int length = ws.writeNextRecord(bos); + + byte cBytes[] = bos.toByteArray(); + + allRecords[i] = new Record(cBytes); + } + } + catch (Exception e) { + Debug.log(Debug.ERROR, "ws.writeNextRecord in getRecords:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + + return allRecords; + } + + + /** + * A cell reference in a StarOffice formula looks like + * [.C2] (for cell C2). MiniCalc is expecting cell references + * to look like C2. This method strips out the braces and + * the period. + * + * @param formula A StarOffice formula <code>String</code>. + * + * @return A MiniCalc formula <code>String</code>. + */ + protected String parseFormula(String formula) { + + StringBuffer inFormula = new StringBuffer(formula); + StringBuffer outFormula = new StringBuffer(); + + boolean inBrace = false; + boolean firstCharAfterBrace = false; + boolean firstCharAfterColon = false; + + int len = inFormula.length(); + + for (int in = 0; in < len; in++) { + switch (inFormula.charAt(in)) { + case '[': + // We are now inside a StarOffice cell reference. + // We also need to strip out the '[' + inBrace = true; + + // If the next character is a '.', we want to strip it out + firstCharAfterBrace = true; + break; + + case ']': + // We are exiting a StarOffice cell reference + // We are stripping out the ']' + inBrace = false; + break; + + case ':': + // We have a cell range reference. + // May need to strip out the leading '.' + if (inBrace) + firstCharAfterColon = true; + outFormula.append(inFormula.charAt(in)); + break; + + case '.': + if (inBrace == true) { + if (firstCharAfterBrace == false && + firstCharAfterColon == false) { + // Not the first character after the open brace. + // We have hit a separator between a sheet reference + // and a cell reference. MiniCalc uses a ! as + // this type of separator. + outFormula.append('!'); + } + else { + firstCharAfterBrace = false; + firstCharAfterColon = false; + // Since we are in a StarOffice cell reference, + // and we are the first character, we need to + // strip out the '.' + } + break; + } else { + // We hit valid data, lets add it to the formula string + outFormula.append(inFormula.charAt(in)); + break; + } + + case ';': + // StarOffice XML format uses ';' as a separator. MiniCalc (and + // many spreadsheets) use ',' as a separator instead. + outFormula.append(','); + break; + + default: + // We hit valid data, lets add it to the formula string + outFormula.append(inFormula.charAt(in)); + + // Need to make sure that firstCharAfterBrace is not true. + firstCharAfterBrace = false; + break; + } + } + + return outFormula.toString(); + } + + /** + * Add a cell to the current WorkSheet. + * + * @param row The row number of the cell. + * @param column The column number of the cell. + * @param fmt The <code>Format</code> object describing + * the appearance of this cell. + * @param cellContents The text or formula of the cell's contents. + * + * @throws IOException If any I/O error occurs. + */ + public void addCell(int row, int column, Format fmt, String cellContents) throws IOException { + + CellAttributes ca = new CellAttributes(getFormat(fmt), + fmt.getForeground(), + fmt.getBackground()); + if (cellContents.startsWith("=")) { + cellContents = parseFormula(cellContents); + Debug.log(Debug.INFO, "YAHOO Found Formula" + cellContents); + } + + CellDescriptor cellDes = new CellDescriptor(row, column, ca, cellContents); + + try { + ws.putCell(cellDes); + } + catch (JMCException jmce) { + Debug.log(Debug.ERROR, "ws.putCell threw exception: " + jmce.getMessage()); + throw new IOException(jmce.getMessage()); + } + } + + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public void setColumnWidths(IntArrayList columnWidths) throws IOException { + // Get the number of columns + int numColumns = columnWidths.size(); + + // Return if there are no columns in the listr + if (numColumns == 0) { + return; + } + + // Need to set the FORM_FLAGS_NONDEFAULT flag for the column widths + // to be used in MiniCalc + long format = JMCconstants.FORM_FLAGS_NONDEFAULT; + + CellAttributes ca = new CellAttributes(format); + + try { + for (int i = 0; i < numColumns; i++) { + // Get the column width in Palm pixels + int width = columnWidths.get(i) * pixelsPerChar; + + // Check limits on column width + if (width < minWidth) { + width = minWidth; + } else if (width > maxWidth) { + width = maxWidth; + } + + // Add the column descriptor to the WorkSheet + ws.putColumn(i + 1, width, ca); + } + } + catch (JMCException jmce) { + Debug.log(Debug.ERROR, "ws.putColumn threw exception: " + jmce.getMessage()); + throw new IOException(jmce.getMessage()); + } + } + + + /** + * This method sets the format of a cell to <i>string</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatString(long format) { + + format = clearCellFormatType(format); + + // Set format to generic, since MiniCalc does not have a string type. + format = format | JMCconstants.FF_FORMAT_GENERIC; + + return format; + } + + + /** + * This method sets the format of a cell to <i>floating point</i>. + * + * @param format The cell format. May already contain + * display info, such as alignment or + * font type. + * @param decimalPlaces The number of decimal places to + * set in the floating point number. + * + * @return The updated format of the cell. + */ + private long setFormatFloat(long format, int decimalPlaces) { + + format = clearCellFormatType(format); + + // Set format to floating point with correct number of decimal places + format = format | JMCconstants.FF_FORMAT_DECIMAL | decimalPlaces; + + return format; + } + + + /** + * This method sets the format of a cell to <i>time</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatTime(long format) { + + format = clearCellFormatType(format); + + // Set format to time. + format = format | JMCconstants.FF_FORMAT_TIME; + + return format; + } + + + /** + * This method sets the format of a cell to <i>date</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatDate(long format) { + + format = clearCellFormatType(format); + + // Set format to date. + format = format | JMCconstants.FF_FORMAT_DATE; + + return format; + } + + + /** + * This method sets the format of a cell to <i>currency</i>. + * + * @param format The cell format-may already contain + * display info, such as alignment or + * font type. + * @param decimalPlaces The number of decimal places to set. + * + * @return The updated format of the cell. + */ + private long setFormatCurrency(long format, int decimalPlaces) { + + format = clearCellFormatType(format); + + // Set format to Currency with correct number of decimal places + format = format | JMCconstants.FF_FORMAT_CURRENCY | decimalPlaces; + + return format; + } + + + /** + * This method sets the format of a cell to <i>boolean</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatBoolean(long format) { + + format = clearCellFormatType(format); + + // Set format to generic, since MiniCalc does not have a Boolean type. + format = format | JMCconstants.FF_FORMAT_GENERIC; + + return format; + } + + + /** + * This method sets the format of a cell to <i>percent</i>. + * + * @param format The cell format-may already contain + * display info, such as alignment or + * font type. + * @param decimalPlaces The number of decimal places to set. + * + * @return The updated format of the cell. + */ + private long setFormatPercent(long format, int decimalPlaces) { + + format = clearCellFormatType(format); + + // Set format to Percent with correct number of decimal places + format = format | JMCconstants.FF_FORMAT_PERCENT | decimalPlaces; + + return format; + } + + + /** + * This method clears out the format bits associated with + * the type of data (<i>float</i>, <i>time</i>, etc...) in + * a cell. + * + * @param format The original format for the cell. + * + * @return The updated cell format with the bits associated + * with the type of data (float, time, etc...) + * zeroed out. + */ + private long clearCellFormatType(long format) { + + // First 4 bits are for the number of decimal places + // bits 5-8 are for the data format (float, time, etc...) + + // Clear out first 8 bits + format = format & 0xFFFFFFFFFFFFFF00L; + + return format; + } + + + /** + * Set a cell's formatting options via a separately create + * <code>Format</code> object. + * + * @param row The row number of the cell to be changed. + * @param column The column number of the cell to be changed. + * @param fmt Object containing formatting settings for + * this cell. + */ + public void setCellFormat(int row, int column, Format fmt) { + } + + + /** + * Get the names of the sheets in the WorkBook. + * + * @param sheet The required sheet. + */ + public String getSheetName(int sheet) { + return wb.getWorksheet(sheet).getName(); + } + + + /* + * This method returns a MiniCalc style format from the + * <code>Format</code> object. + */ + private long getFormat(Format fmt) + { + String category = fmt.getCategory(); + + if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_BOOLEAN)) { + return setFormatBoolean(0); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_CURRENCY)) { + return setFormatCurrency(0, fmt.getDecimalPlaces()); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_DATE)) { + return setFormatDate(0); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_FLOAT)) { + return setFormatFloat(0, fmt.getDecimalPlaces()); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_PERCENT)) { + return setFormatPercent(0, fmt.getDecimalPlaces()); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_STRING)) { + return setFormatString(0); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_TIME)) { + return setFormatTime(0); + } + else { + // Should never get here, but just in case + System.out.println("XXXXX Formatting information not found"); + return 0; + } + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/PluginFactoryImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/PluginFactoryImpl.java new file mode 100644 index 000000000000..a3b1d53abaff --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/PluginFactoryImpl.java @@ -0,0 +1,132 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PluginFactoryImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxc.DocumentMergerImpl; +import org.openoffice.xmerge.converter.xml.sxc.SxcPluginFactory; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.registry.ConverterInfo; +import java.io.IOException; +import java.io.InputStream; + +/** + * <p>MiniCalc implementation of the <code>PluginFactory</code>. + * This encapsulates conversion of StarCalc XML format to and from + * MiniCalc format.</p> + * + * <p>The superclass produces a particular + * {@link org.openoffice.xmerge.Document Document} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocument + * SxcDocument} that the converters in this class works with. Thus, + * this class only implements the methods that produces the converters, + * i.e. {@link + * org.openoffice.xmerge.DocumentSerializer + * DocumentSerializer} and {@link + * org.openoffice.xmerge.DocumentDeserializer + * DocumentDeserializer}; + * as well as the {@link + * org.openoffice.xmerge.ConverterCapabilities + * ConverterCapabilities} object that is specific to this format + * conversion. That superclass also produces a {@link + * org.openoffice.xmerge.DocumentMerger DocumentMerger} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxc.DocumentMergerImpl + * DocumentMergerImpl} which this class derives the functionality.</p> + */ +public final class PluginFactoryImpl extends SxcPluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory { + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + public PluginFactoryImpl(ConverterInfo ci) { + super(ci); + } + + + /** + * Returns an instance of <code>DocumentSerializerImpl</code>, + * which is an implementation of <code>DocumentSerializer</code> + * interface. + * + * @param doc <code>Document</code> object to be + * converted/serialized. + * + * @return A <code>DocumentSerializerImpl</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + + return new SxcDocumentSerializerImpl(doc); + } + + + /** + * Returns an instance of <code>DocumentDeserializerImpl</code>, + * which is an implementation of <code>DocumentDeserializer</code> + * interface. + * + * @param cd <code>ConvertData</code> object for reading data + * which will be converted back to a + * <code>Document</code> object. + * + * @return A <code>DocumentDeserializerImpl</code> object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + + return new SxcDocumentDeserializerImpl(cd); + } + + + public Document createDeviceDocument(String name, InputStream is) + throws IOException { + + PalmDocument palmDoc = new PalmDocument(is); + return palmDoc; + } + + public DocumentMerger createDocumentMerger(Document doc) { + + DocumentMergerImpl merger = new DocumentMergerImpl(doc, converterCap); + return merger; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentDeserializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentDeserializerImpl.java new file mode 100644 index 000000000000..1161b5522ca1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentDeserializerImpl.java @@ -0,0 +1,141 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocumentDeserializerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializer; +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetDecoder; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.converter.palm.PalmDocument; + +import java.io.IOException; +import java.util.Enumeration; + +/** + * <p>MiniCalc implementation of <code>DocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts a set of files in MiniCalc PDB format to a StarOffice DOM.</p> + * + * @author Mark Murnane + */ +public final class SxcDocumentDeserializerImpl extends SxcDocumentDeserializer { + + /** + * Creates new <code>SxcDocumentDeserializerImpl</code>. + * + * @param cd <code>ConvertData</code> Input data to convert. + */ + public SxcDocumentDeserializerImpl(ConvertData cd) { + super(cd); + } + + + /** + * This method will be implemented by concrete subclasses and will + * return an application-specific decoder. + * + * @param workbook The WorkBook name. + * @param worksheetNames An array of WorkSheet names. + * @param password The password. + * + * @return An application-specific <code>SpreadsheetDecoder</code>. + */ + public SpreadsheetDecoder createDecoder(String workbook, + String[] worksheetNames, String password) throws IOException { + + return new MinicalcDecoder(workbook, worksheetNames, password); + } + + + /** + * This method will return the name of the WorkBook from the + * <code>ConvertData</code>. Allows for situations where the + * WorkBook name differs from the PDB name. + * + * Implemented in the Deserializer as the Decoder's constructor + * requires a name. + * + * @param cd The <code>ConvertData</code>. + * + * @return The name of the WorkBook. + */ + protected String getWorkbookName(ConvertData cd) + throws IOException { + + Enumeration e = cd.getDocumentEnumeration(); + PalmDocument palmDoc = (PalmDocument) e.nextElement(); + String workbookName = palmDoc.getName(); + + // Search for "-", which separates workbook from worksheet + int end = workbookName.indexOf("-"); + + if (end > 0) { + workbookName = workbookName.substring(0, end); + } + + return workbookName; + } + + + /** + * This method will return an array of WorkSheet names from the + * <code>ConvertData</code>. + * + * @param cd The <code>ConvertData</code>. + * + * @return The name of the WorkSheet. + */ + protected String[] getWorksheetNames(ConvertData cd) + throws IOException { + int numberOfPDBs = cd.getNumDocuments(); + String worksheetName[] = new String[numberOfPDBs]; + int i=0; + Enumeration e = cd.getDocumentEnumeration(); + while (e.hasMoreElements()) { + PalmDocument palmDoc = (PalmDocument) e.nextElement(); + worksheetName[i] = palmDoc.getName(); + + // Search for the "-", which seperates workbook from worksheet + int start = worksheetName[i].indexOf("-"); + + if (start != -1) { + worksheetName[i] = worksheetName[i].substring(start + 1); + } + i++; + } + + return worksheetName; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentSerializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentSerializerImpl.java new file mode 100644 index 000000000000..69b584fadf09 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentSerializerImpl.java @@ -0,0 +1,144 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocumentSerializerImpl.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import java.awt.Color; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import java.io.IOException; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PalmDocument; + +import jmc.JMCconstants; + +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentSerializer; + +/** + * <p>MiniCalc implementation of <code>SxcDocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts StarOffice XML format to a set of files in + * MiniCalc PDB format.</p> + * + * @author Paul Rank + * @author Mark Murnane + */ +public final class SxcDocumentSerializerImpl extends SxcDocumentSerializer { + + + /** + * Constructor. + * + * @param document The <code>Document</code> to convert. + */ + public SxcDocumentSerializerImpl(Document document) { + super(document); + } + + + public ConvertData serialize() throws ConvertException, IOException { + + + // Get the server side document name. This value should not + // contain a path or the file extension. + String docName = sxcDoc.getName(); + + // TODO - get real values for password when implemnted in XML + // Passwords are not currently stored in StarCalc XML format. + String password = null; + + encoder = new MinicalcEncoder(docName, password); + + // get dom document + org.w3c.dom.Document domDoc = sxcDoc.getContentDOM(); + + // Traverse to the office:body element. + // There should only be one. + NodeList list = domDoc.getElementsByTagName(TAG_OFFICE_BODY); + int len = list.getLength(); + + if (len > 0) { + Node node = list.item(0); + traverseBody(node); + } + + // Get the number of sheets in the workbook + // This will equal the number of PDBs we need + ConvertData cd = new ConvertData(); + int numSheets = encoder.getNumberOfSheets(); + + for (int i = 0; i < numSheets; i++) { + + // Get records for sheet i + Record records[] = ((MinicalcEncoder) encoder).getRecords(i); + + // Get the sheet name for sheet i + String fullSheetName = new String(docName + + "-" + + encoder.getSheetName(i)); + + // Create a PalmDB object + PalmDocument palmDoc = new PalmDocument(fullSheetName, + MinicalcConstants.CREATOR_ID, + MinicalcConstants.TYPE_ID, JMCconstants.AppVersion, + PalmDB.PDB_HEADER_ATTR_BACKUP, records); + + cd.addDocument(palmDoc); + } + + + // OutputStream os = new FileOutputStream(docName); + + //pdbSet.write(os); + //os.flush(); + + //ConvertDataEntry cde = new ConvertDataOutputStream(os, docName); + //cd.addCDE(cde); + + return cd; + } + + + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/build.xml new file mode 100644 index 000000000000..c1898c2fa3d5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/build.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxs_minicalc" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxs_minicalc"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxc/minicalc"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + <pathelement location="${solar.jar}/jmc.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/MinicalcConstants.java"/> + <include name="${package}/MinicalcDecoder.java"/> + <include name="${package}/MinicalcEncoder.java"/> + <include name="${package}/MinicalcDataString.java"/> + <include name="${package}/SxcDocumentDeserializerImpl.java"/> + <include name="${package}/SxcDocumentSerializerImpl.java"/> + <include name="${package}/ConverterCapabilitiesImpl.java"/> + <include name="${package}/PluginFactoryImpl.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/converter.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/converter.xml new file mode 100644 index 000000000000..263021fa324d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/converter.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: converter.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<converters> + <converter type="staroffice/sxc" version="1.0"> + <converter-display-name> + Minicalc 6.4 + </converter-display-name> + <converter-description> + StarCalc XML to/from Minicalc 6.4 conversion + </converter-description> + <converter-vendor>OpenOffice.org</converter-vendor> + <converter-class-impl> + org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + </converter-class-impl> + <converter-target type="application/x-minicalc" /> + </converter> +</converters> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/makefile.mk new file mode 100644 index 000000000000..78d4211e162d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcxs_minicalc +PRJ=../../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/package.html new file mode 100644 index 000000000000..191ed77ec344 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/package.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxc.minicalc package</title> +</head> + +<body bgcolor="white"> + +<p>Provides the tools for doing the conversion of StarWriter XML to +and from MiniCalc format.</p> + +<p>It follows the {@link org.openoffice.xmerge} framework for the conversion process.</p> + +<p>Since it converts to/from a Palm application format, these converters +follow the <a href=../../../../converter/palm/package-summary.html#streamformat> +PalmDB stream format</a> for writing out to the Palm sync client or reading +in from the Palm sync client.</p> + +<p>Note that <code>PluginFactoryImpl</code> also provides a +<code>DocumentMerger</code> object, i.e. {@link org.openoffice.xmerge.converter.xml.sxw.aportisdoc.DocumentMergerImpl DocumentMergerImpl}. +This functionality was derived from its superclass +{@link org.openoffice.xmerge.converter.xml.sxw.SxwPluginFactory SxwPluginFactory}.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/package.html new file mode 100644 index 000000000000..258d0158af1d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/package.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxc package</title> +</head> + +<body bgcolor="white"> +<p>Provides base implementation of StarCalc XML conversion to and from +different "Device" <code>Document</code> formats.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/ConverterCapabilitiesImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..2e51ee685e21 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/ConverterCapabilitiesImpl.java @@ -0,0 +1,116 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterCapabilitiesImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + + +/** + * <p>Pocket Excel implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxc.pexcel.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarCalc SXC to/from Pocket Excel conversions. The + * <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE_ROW.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE_COLUMN.equals(tag)) + return false; + // TODO - we currently do not handle the table column tag + else if (OfficeConstants.TAG_TABLE_SCENARIO.equals(tag)) + return false; + // TODO - we currently do not handle the table scenario tag + else if (OfficeConstants.TAG_TABLE_CELL.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_TABLE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_NAME.equals(attribute)) + return true; + + } else if (OfficeConstants.TAG_TABLE_CELL.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_VALUE_TYPE.equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_FORMULA. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_VALUE.equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_BOOLEAN_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_CURRENCY. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_TIME_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_DATE_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED. + equals(attribute)) + return true; + + } else if (OfficeConstants.TAG_TABLE_ROW.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_NUM_ROWS_REPEATED. + equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PluginFactoryImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PluginFactoryImpl.java new file mode 100644 index 000000000000..389b0169e49b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PluginFactoryImpl.java @@ -0,0 +1,133 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PluginFactoryImpl.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + +import java.io.IOException; +import java.io.InputStream; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxc.DocumentMergerImpl; +import org.openoffice.xmerge.converter.xml.sxc.SxcPluginFactory; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; +import org.openoffice.xmerge.util.registry.ConverterInfo; + +/** + * <p>Pocket Excel implementation of the <code>PluginFactory</code>. + * This encapsulates conversion of StarCalc XML format to and from + * Pocket Excel format.</p> + * + * <p>The superclass produces a particular + * {@link org.openoffice.xmerge.Document Document} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocument + * SxcDocument} that the converters in this class works with. Thus, + * this class only implements the methods that produces the converters, + * i.e. {@link + * org.openoffice.xmerge.DocumentSerializer + * DocumentSerializer} and {@link + * org.openoffice.xmerge.DocumentDeserializer + * DocumentDeserializer}; + * as well as the {@link + * org.openoffice.xmerge.ConverterCapabilities + * ConverterCapabilities} object that is specific to this format + * conversion. That superclass also produces a {@link + * org.openoffice.xmerge.DocumentMerger DocumentMerger} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxc.DocumentMergerImpl + * DocumentMergerImpl} which this class derives the functionality.</p> + */ +public final class PluginFactoryImpl extends SxcPluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory { + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + public PluginFactoryImpl(ConverterInfo ci) { + super(ci); + } + + + /** + * Returns an instance of <code>DocumentSerializerImpl</code>, + * which is an implementation of <code>DocumentSerializer</code> + * interface. + * + * @param doc <code>Document</code> object to be + * converted/serialized. + * + * @return A <code>DocumentSerializerImpl</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + + return new SxcDocumentSerializerImpl(doc); + } + + + /** + * Returns an instance of <code>DocumentDeserializerImpl</code>, + * which is an implementation of <code>DocumentDeserializer</code> + * interface. + * + * @param cd <code>ConvertData</code> object for reading data + * which will be converted back to a + * <code>Document</code> object. + * + * @return A <code>DocumentDeserializerImpl</code> object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + + return new SxcDocumentDeserializerImpl(cd); + } + + + public Document createDeviceDocument(String name, InputStream is) + throws IOException { + + Workbook wb = new Workbook(name, is); + return wb; + } + + public DocumentMerger createDocumentMerger(Document doc) { + + DocumentMergerImpl merger = new DocumentMergerImpl(doc, converterCap); + return merger; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelConstants.java new file mode 100644 index 000000000000..22382e0faf8c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelConstants.java @@ -0,0 +1,71 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PocketExcelConstants.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + + +/** + * Interface defining constants for Pocket Excel attributes. + * + * @author Martin Maher + */ +public interface PocketExcelConstants { + /** File extension for Pocket Word files. */ + public static final String FILE_EXTENSION = ".pxl"; + + /** Constants for pexcel BIFF records */ + public static final int BLANK_CELL = 0x01; + public static final int NUMBER_CELL = 0x03; + public static final int LABEL_CELL = 0x04; + public static final int BOOLERR_CELL = 0x05; + public static final int FORMULA_CELL = 0x06; + public static final int FORMULA_STRING = 0x07; + public static final int ROW_DESCRIPTION = 0x08; + public static final int BOF_RECORD = 0x09; + public static final int EOF_MARKER = 0x0A; + public static final int DEFINED_NAME = 0x18; + public static final int CURRENT_SELECTION = 0x1D; + public static final int NUMBER_FORMAT = 0x1E; + public static final int DEFAULT_ROW_HEIGHT = 0x25; + public static final int FONT_DESCRIPTION = 0x31; + public static final int WINDOW_INFO = 0x3D; + public static final int SHEET_WINDOW_INFO = 0x3E; + public static final int PANE_INFO = 0x41; + public static final int CODEPAGE = 0x42; + public static final int DEF_COL_WIDTH = 0x55; + public static final int COLINFO = 0x7D; + public static final int BOUND_SHEET = 0x85; + public static final int EXTENDED_FORMAT = 0xE0; + + /** Colour lookup table for mapping pexcel color values + (See util/ColourConverter.java */ + public short cLookup[] = { 0, 14, 15, 1, 2, 3, 4, 7, 6, 5, 8, 9, 10, 13, 12, 11 }; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelDecoder.java new file mode 100644 index 000000000000..c5f263766da2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelDecoder.java @@ -0,0 +1,449 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PocketExcelDecoder.java,v $ + * $Revision: 1.23 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Stack; +import java.util.LinkedList; +import java.util.Vector; +import java.util.Enumeration; +import java.util.NoSuchElementException; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; +import org.openoffice.xmerge.converter.xml.sxc.BookSettings; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializer; +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetDecoder; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.NameDefinition; +import org.openoffice.xmerge.converter.xml.sxc.ColumnRowInfo; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.*; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializerImpl} + * SxcDocumentDeserializerImpl} to decode the Pocket Excel format. + * + * @author Paul Rank + */ +final class PocketExcelDecoder extends SpreadsheetDecoder { + + private Workbook wb; + private Worksheet ws; + private CellValue cell; + private int maxRows = 0; + private int maxCols = 0; + private int wsIndex; + private Enumeration cellValue; + private Format fmt = null; + + /** + * Constructor creates a Pocket Excel WorkBook. + * + * @param name The name of the WorkBook. + * @param worksheetNames set of Strings equivalent to the worksheets + * contained in the workbook + * @param password The password for the workBook. + * + * @throws IOException If any I/O error occurs. + */ + PocketExcelDecoder(String name, String[] worksheetNames, String password) throws IOException { + super(name, password); + + fmt = new Format(); + } + + + /** + * This method takes a <code>ConvertData</code> as input and + * converts it into a PocketWord WorkSheet. The WorkSheet is then + * added to the WorkBook. + * + * @param InputStream An <code>ConvertData</code> containing a + * Pocket Excel WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public void addDeviceContent(ConvertData cd) throws IOException { + + Enumeration e = cd.getDocumentEnumeration(); + wb = (Workbook) e.nextElement(); + } + + + /** + * This method returns the number of spreadsheets + * stored in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public int getNumberOfSheets() { + + Vector v = wb.getWorksheetNames(); + Debug.log(Debug.TRACE,"Total Number of Sheets : " + v.size()); + return (v.size()); + } + + /** + * This method returns the number of spreadsheets + * stored in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public Enumeration getNameDefinitions() { + + Enumeration e = wb.getDefinedNames(); + Vector nameDefinitionVector = new Vector(); + while(e.hasMoreElements()) { + DefinedName dn = (DefinedName)e.nextElement(); + NameDefinition nameDefinitionEntry = dn.getNameDefinition(); + nameDefinitionVector.add(nameDefinitionEntry); + } + Debug.log(Debug.TRACE,"Getting " + nameDefinitionVector.size() + " DefinedName records"); + return (nameDefinitionVector.elements()); + } + + /** + * This method returns an enumeration of Settings object(s), + * one for each worksheet + * + * @return An enumerattion of <code>Settings</code> + */ + public BookSettings getSettings() { + + return (wb.getSettings()); + } + /** + * This method returns the number of spreadsheets + * stored in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public Enumeration getColumnRowInfos() { + + Vector colRowVector = new Vector(); + + // Collect Columns from worksheet and add them to the vector + for(Enumeration e = ws.getColInfos();e.hasMoreElements();) { + ColInfo ci = (ColInfo)e.nextElement(); + int repeated = ci.getLast() - ci.getFirst() + 1; + ColumnRowInfo colInfo = new ColumnRowInfo( ci.getColWidth(), + repeated, + ColumnRowInfo.COLUMN); + colRowVector.add(colInfo); + } + + // Collect Rows from worksheet and add them to the vector + for(Enumeration e = ws.getRows();e.hasMoreElements();) { + Row rw = (Row)e.nextElement(); + // We will use the repeat field for number (unlike columns rows + // cannot be repeated, we have unique record for each row in pxl + int repeated = rw.getRowNumber(); + ColumnRowInfo rowInfo = new ColumnRowInfo( rw.getRowHeight(), + repeated, + ColumnRowInfo.ROW); + colRowVector.add(rowInfo); + } + Debug.log(Debug.TRACE,"Getting " + colRowVector.size() + " ColRowInfo records"); + return (colRowVector.elements()); + } + + /** + * This method gets the requested WorkSheet from the + * WorkBook and sets it as the selected WorkSheet. All + * other "get" methods will now get data from this WorkSheet. + * + * @param sheetIndex The index number of the sheet to open. + * + * @throws IOException If any I/O error occurs. + */ + public void setWorksheet(int sheetIndex) throws IOException { + Debug.log(Debug.TRACE,"Setting to worksheet : " + sheetIndex); + ws = wb.getWorksheet(sheetIndex); + cellValue = ws.getCellEnumerator(); + wsIndex = sheetIndex; + while(goToNextCell()) { + maxRows = Math.max(maxRows, cell.getRow()); + maxCols = Math.max(maxCols, cell.getCol()); + } + cellValue = ws.getCellEnumerator(); + Debug.log(Debug.TRACE,"Max Cols : " + maxCols + " MaxRows : " + maxRows); + } + + + /** + * This method returns the name of the current spreadsheet. + * + * @return The name of the current WorkSheet. + */ + public String getSheetName() { + + String wsName = wb.getSheetName(wsIndex); + Debug.log(Debug.TRACE,"The name of the current Worksheet is : " + wsName); + return wsName; + } + + + /** + * This method gets the next cell from the WorkSheet + * and sets it as the selected cell. All other "get" + * methods will now get data from this cell. + * + * @return True if we were able to go to another cell + * in the sheet, false if there were no cells + * left. + * + * @throws IOException If any I/O error occurs. + */ + public boolean goToNextCell() throws IOException { + + boolean success = false; + + try { + cell = (CellValue) cellValue.nextElement(); + Debug.log(Debug.TRACE,"Current Cell : " + cell.getString()); + readCellFormat(); + success = true; + } catch (NoSuchElementException e) { + Debug.log(Debug.TRACE,"Could't find current cell"); + } + + return success; + } + + + /** + * This method returns the row number of the current cell. + * + * @return The row number of the current cell. Returns + * -1 if no cell is currently selected. + */ + public int getRowNumber() { + + int row = -1; + + if (cell != null) { + row = cell.getRow(); + Debug.log(Debug.TRACE,"cell row is " + row); + } + return (row); + } + + /** + * This method returns the number of rows in the current sheet. + * + * @return The number of rows in the current sheet. + */ + public int getNumberOfRows() { + return maxRows; + } + + /** + * This method returns the number of columns in the current sheet. + * + * @return The number of columns in the current sheet. + */ + public int getNumberOfColumns() { + return maxCols; + } + + + /** + * This method returns the col number of the current cell. + * + * @return The col number of the current cell. Returns + * -1 if no cell is currently selected. + */ + public int getColNumber() { + + int col = -1; + + if (cell != null) { + col = cell.getCol(); + Debug.log(Debug.TRACE,"cell col is " + col); + } + return (col); + } + + /** + * This method returns the contents of the current cell. + * + * @return The contents of the current cell. Returns + * null if no cell is currently selected. + */ + public String getCellContents() { + + String contents = new String(""); + + if (cell != null) { + try { + contents = cell.getString(); + if (contents.startsWith("=")) { + contents = parseFormula(contents); + } + } + catch (IOException e) { + System.err.println("Could Not retrieve Cell contents"); + System.err.println("Setting contents of cell(" + cell.getRow() + + "," + cell.getCol() + ") to an empty string"); + System.err.println("Error msg: " + e.getMessage()); + } + } + + return contents; + } + + /** + * <p>This method takes a formula and parses it into + * StarOffice XML formula format.</p> + * + * <p>Many spreadsheets use ',' as a separator. + * StarOffice XML format uses ';' as a separator instead.</p> + * + * <p>Many spreadsheets use '!' as a separator when refencing + * a cell in a different sheet.</p> + * + * <blockquote> + * Example: =sheet1!A1 + * </blockquote> + * + * <p>StarOffice XML format uses '.' as a separator instead.</p> + * + * <blockquote> + * Example: =sheet1.A1 + * </blockquote> + * + * @param formula A formula string. + * + * @return A StarOffice XML format formula string. + */ + protected String parseFormula(String formula) { + + formula = formula.replace(',', ';'); + formula = formula.replace('!', '.'); + + return formula; + } + + /** + * This method returns the contents of the current cell. + * + * @return The contents of the current cell. Returns + * null if no cell is currently selected. + */ + public String getCellValue() { + + String contents = new String(""); + + if (cell != null) { + try { + contents = ((Formula)cell).getValue(); + } + catch (IOException e) { + System.err.println("Could Not retrieve Cell value"); + System.err.println("Setting value of cell(" + cell.getRow() + + "," + cell.getCol() + ") to an empty string"); + System.err.println("Error msg: " + e.getMessage()); + } + } + return contents; + } + + /** + * <p>This method returns the type of the data in the current cell. + * Currently the only type supported is String.</p> + * + * @return The type of the data in the current cell. + */ + public String getCellDataType() { + + String type = OfficeConstants.CELLTYPE_STRING; + + if(cell instanceof FloatNumber) + type = OfficeConstants.CELLTYPE_FLOAT; + if(cell instanceof Formula) + type = OfficeConstants.CELLTYPE_FLOAT; + + return type; + } + + + /** + * Return the Format object describing the active cell formatting. + * + * @return The Format object describing the active cell formatting. + */ + public Format getCellFormat() { + return new Format(fmt); + } + + + /** + * Create the format data for the new cell. + */ + private void readCellFormat() throws IOException { + + fmt.clearFormatting(); + + Debug.log(Debug.TRACE," ixfe for Current Cell " + cell.getIxfe()); + ExtendedFormat xf = wb.getExtendedFormat(cell.getIxfe()); + Debug.log(Debug.TRACE," ixfnt for Current Cell " + xf.getFontIndex()); + FontDescription fd = wb.getFontDescription(xf.getFontIndex()); + + fmt.setAttribute(Format.ITALIC, fd.isItalic()); + fmt.setAttribute(Format.BOLD, fd.isBold()); + fmt.setAttribute(Format.UNDERLINE, fd.isUnderline()); + fmt.setForeground(fd.getForeground()); + + fmt.setBackground(xf.getBackground()); + fmt.setAlign(xf.getAlign()); + fmt.setVertAlign(xf.getVertAlign()); + fmt.setAttribute(Format.WORD_WRAP, xf.isWordWrap()); + + fmt.setAttribute(Format.TOP_BORDER, xf.isBorder(ExtendedFormat.TOP_BORDER)); + fmt.setAttribute(Format.BOTTOM_BORDER, xf.isBorder(ExtendedFormat.BOTTOM_BORDER)); + fmt.setAttribute(Format.RIGHT_BORDER, xf.isBorder(ExtendedFormat.RIGHT_BORDER)); + fmt.setAttribute(Format.LEFT_BORDER, xf.isBorder(ExtendedFormat.LEFT_BORDER)); + + fmt.setFontName(fd.getFont()); + fmt.setFontSize(fd.getFontSize()); + + fmt.setCategory(getCellDataType()); + + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelEncoder.java new file mode 100644 index 000000000000..44e9de76394d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/PocketExcelEncoder.java @@ -0,0 +1,298 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PocketExcelEncoder.java,v $ + * $Revision: 1.17 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Vector; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.IntArrayList; + +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetEncoder; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.BookSettings; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; +import org.openoffice.xmerge.converter.xml.sxc.NameDefinition; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocumentSerializerImpl + * SxcDocumentSerializerImpl} to encode the Pocket Excel format. + * + * @author Martin Maher + */ +final class PocketExcelEncoder extends SpreadsheetEncoder { + + private Workbook wb; + + /** + * Constructor creates a Pocket Excel WorkBook. + * + * @param name The name of the WorkBook. + * @param password The password for the WorkBook. + * + * @throws IOException If any I/O error occurs. + */ + PocketExcelEncoder(String name, String password) throws IOException { + + super(name, password); + wb = new Workbook(name); + + } + + + /** + * This method creates a WorkSheet belonging to the + * WorkBook. + * + * @param sheetName The name of the WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public void createWorksheet(String sheetName) throws IOException { + + wb.addWorksheet(sheetName); + } + + + /** + * This method gets the number of sheets in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public int getNumberOfSheets() { + + Vector v = wb.getWorksheetNames(); + return (v.size()); + } + + + /** + * This method returns the Workbook created. + * + * @return Returns a <code>Workbook</code> + * + * @throws IOException If any I/O error occurs. + */ + public Workbook getWorkbook() throws IOException { + + return wb; + } + + /** + * This method converts a String containing a formula in infix notation + * to a String in Reverse Polish Notation (RPN) + * + * @return a parsed pexcel formula in RPN + */ + protected String parseFormula(String formula) { + + Debug.log(Debug.TRACE,"Strip Formula (Before) : " + formula); + + StringBuffer inFormula = new StringBuffer(formula); + StringBuffer outFormula = new StringBuffer(); + + boolean inBrace = false; + boolean firstCharAfterBrace = false; + boolean firstCharAfterColon = false; + + int len = inFormula.length(); + + for (int in = 0; in < len; in++) { + switch (inFormula.charAt(in)) { + case '[': + // We are now inside a StarOffice cell reference. + // We also need to strip out the '[' + Debug.log(Debug.TRACE,"brace Found"); + inBrace = true; + + // If the next character is a '.', we want to strip it out + firstCharAfterBrace = true; + break; + + case ']': + // We are exiting a StarOffice cell reference + // We are stripping out the ']' + inBrace = false; + break; + case '.': + if (inBrace == true && (firstCharAfterBrace == true || + firstCharAfterColon == true) ) { + + Debug.log(Debug.TRACE,"dot Found and in brace"); + // Since we are in a StarOffice cell reference, + // and we are the first character, we need to + // strip out the '.' + firstCharAfterBrace = false; + firstCharAfterColon = false; + + } else if(firstCharAfterColon == true) { + firstCharAfterColon = false; + } else { + outFormula.append(inFormula.charAt(in)); + } + break; + + case ':': + // We have a cell range reference. + // May need to strip out the leading '.' + firstCharAfterColon = true; + outFormula.append(inFormula.charAt(in)); + break; + + case ';': + // StarOffice XML format uses ';' as a separator. MiniCalc (and + // many spreadsheets) use ',' as a separator instead. + outFormula.append(','); + break; + + default: + // We hit valid data, lets add it to the formula string + outFormula.append(inFormula.charAt(in)); + + // Need to make sure that firstCharAfterBrace is not true. + firstCharAfterBrace = false; + break; + } + } + + Debug.log(Debug.TRACE,"Strip Formula (After) : " + outFormula); + return outFormula.toString(); + } + + /** + * Add a cell to the current WorkSheet. + * + * @param row The row number of the cell. + * @param column The column number of the cell. + * @param fmt The <code>Format</code> object describing + * the appearance of this cell. + * @param cellContents The text or formula of the cell's contents. + * + * @throws IOException If any I/O error occurs. + */ + public void addCell(int row, int column, Format fmt, String cellContents) throws IOException { + + if (cellContents.startsWith("=")) { + cellContents = parseFormula(cellContents); + Debug.log(Debug.TRACE,"Parsing Formula " + cellContents); + } + wb.addCell(row, column, fmt, cellContents); + } + + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public void setColumnRows(Vector columnRows) throws IOException { + + wb.addColInfo(columnRows); + } + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public void setNameDefinition(NameDefinition nd) throws IOException { + + String parsedName = nd.getDefinition(); + nd.setDefinition(parseFormula(parsedName)); + + wb.addNameDefinition(nd); + } + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public void addSettings(BookSettings s) throws IOException { + + wb.addSettings(s); + } + + /** + * This method sets the format of a cell to <i>string</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatString(long format) { + + return 0; + } + + + /** + * Set a cell's formatting options via a separately create + * <code>Format</code> object. + * + * @param row The row number of the cell to be changed. + * @param column The column number of the cell to be changed. + * @param fmt Object containing formatting settings for + * this cell. + */ + public void setCellFormat(int row, int column, Format fmt) { + Debug.log(Debug.TRACE,"bold : " + fmt.getAttribute(Format.BOLD) + + ",Italic : " + fmt.getAttribute(Format.ITALIC) + + ",Underline : " + fmt.getAttribute(Format.UNDERLINE)); + } + + + /** + * Get the names of the sheets in the WorkBook. + * + * @param sheet The required sheet. + */ + public String getSheetName(int sheet) { + + Vector v = wb.getWorksheetNames(); + String wsName = (String) (v.elementAt(sheet)); + + return wsName; + } + + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/SxcDocumentDeserializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/SxcDocumentDeserializerImpl.java new file mode 100644 index 000000000000..5bca66b92b92 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/SxcDocumentDeserializerImpl.java @@ -0,0 +1,132 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocumentDeserializerImpl.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetDecoder; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializer; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelDecoder; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; + + +/** + * <p>Pocket Excel implementation of <code>DocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.pexcel.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts a set of files in Pocket Excel PXL format to a StarOffice DOM.</p> + * + * @author Mark Murnane + */ +public final class SxcDocumentDeserializerImpl extends SxcDocumentDeserializer { + + /** + * Creates new <code>SxcDocumentDeserializerImpl</code>. + * + * @param cd <code>ConvertData</code> Input data to convert. + */ + public SxcDocumentDeserializerImpl(ConvertData cd) { + super(cd); + } + + + /** + * This method will be implemented by concrete subclasses and will + * return an application-specific decoder. + * + * @param workbook The WorkBook name. + * @param worksheetNames An array of WorkSheet names. + * @param password The password. + * + * @return An application-specific <code>SpreadsheetDecoder</code>. + */ + public SpreadsheetDecoder createDecoder(String workbook, + String[] worksheetNames, String password) throws IOException { + + return new PocketExcelDecoder(workbook, worksheetNames, password); + } + + + /** + * This method will return the name of the WorkBook from the + * <code>ConvertData</code>. Allows for situations where the + * WorkBook name differs from the PDB name. + * + * Implemented in the Deserializer as the Decoder's constructor + * requires a name. + * + * @param cd The <code>ConvertData</code>. + * + * @return The name of the WorkBook. + */ + protected String getWorkbookName(ConvertData cd) + throws IOException { + + Enumeration e = cd.getDocumentEnumeration(); + Workbook wb = (Workbook) e.nextElement(); + + String workbookName = wb.getName(); + return workbookName; + } + + + /** + * This method will return an array of WorkSheet names from the + * <code>ConvertData</code>. + * + * @param cd The <code>ConvertData</code>. + * + * @return The name of the WorkSheet. + */ + protected String[] getWorksheetNames(ConvertData cd) + throws IOException { + + Enumeration e = cd.getDocumentEnumeration(); + Workbook wb = (Workbook) e.nextElement(); + Vector v = wb.getWorksheetNames(); + e = v.elements(); + String worksheetNames[] = new String[v.size()]; + int i = 0; + while(e.hasMoreElements()) { + worksheetNames[i] = (String) e.nextElement(); + Debug.log(Debug.TRACE,"Worksheet Name : " + worksheetNames[i]); + i++; + } + return worksheetNames; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/SxcDocumentSerializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/SxcDocumentSerializerImpl.java new file mode 100644 index 000000000000..ff3de98c3478 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/SxcDocumentSerializerImpl.java @@ -0,0 +1,139 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxcDocumentSerializerImpl.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel; + +import java.awt.Color; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import java.io.IOException; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentSerializer; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; +import org.openoffice.xmerge.converter.xml.StyleCatalog; + +/** + * <p>Pocket Excel implementation of <code>SxcDocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.pexcel.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts StarOffice XML format to a set of files in + * Pocket Excel PXL format.</p> + * + * @author Paul Rank + * @author Mark Murnane + */ +public final class SxcDocumentSerializerImpl extends SxcDocumentSerializer { + + + /** + * Constructor. + * + * @param document The <code>Document</code> to convert. + */ + public SxcDocumentSerializerImpl(Document document) { + super(document); + } + + + public ConvertData serialize() throws ConvertException, IOException { + + // Get the server side document name. This value should not + // contain a path or the file extension. + String docName = sxcDoc.getName(); + + // TODO - get real values for password when implemnted in XML + // Passwords are not currently stored in StarCalc XML format. + String password = null; + + encoder = new PocketExcelEncoder(docName, password); + + // get dom document + org.w3c.dom.Document domDoc = sxcDoc.getContentDOM(); + + // load the styles + loadStyles(sxcDoc); + // Traverse to the office:body element. + // There should only be one. + NodeList list = domDoc.getElementsByTagName(TAG_OFFICE_BODY); + int len = list.getLength(); + + if (len > 0) { + Node node = list.item(0); + traverseBody(node); + } + + // get settings for this document + org.w3c.dom.Document settingsDoc = sxcDoc.getSettingsDOM(); + if(settingsDoc!=null) { + NodeList settingsList = settingsDoc.getElementsByTagName(TAG_OFFICE_SETTINGS); + int slen = settingsList.getLength(); + + if (slen > 0) { + Node settingsNode = settingsList.item(0); + traverseSettings(settingsNode); + } + } + + // Get the number of sheets in the workbook + // This will equal the number of PDBs we need + ConvertData cd = new ConvertData(); + Workbook wb = ((PocketExcelEncoder) encoder).getWorkbook(); + cd.addDocument(wb); + + return cd; + } + + + /** + * A cell reference in a StarOffice formula looks like + * [.C2] (for cell C2). MiniCalc is expecting cell references + * to look like C2. This method strips out the braces and + * the period. + * + * @param formula A StarOffice formula <code>String</code>. + * + * @return A MiniCalc formula <code>String</code>. + */ + protected String parseFormula(String formula) { + + return null; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/build.xml new file mode 100644 index 000000000000..02c1e44a9ea7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/build.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.5 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxs_pexcel" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxs_pexcel"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxc/pexcel"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/PocketExcelConstants.java"/> + <include name="${package}/PocketExcelDecoder.java"/> + <include name="${package}/PocketExcelEncoder.java"/> + <include name="${package}/SxcDocumentDeserializerImpl.java"/> + <include name="${package}/SxcDocumentSerializerImpl.java"/> + <include name="${package}/ConverterCapabilitiesImpl.java"/> + <include name="${package}/PluginFactoryImpl.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/converter.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/converter.xml new file mode 100644 index 000000000000..1d6627afe49c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/converter.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: converter.xml,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<converters> + <converter type="staroffice/sxc" version="1.0"> + <converter-display-name> + Pocket Excel 2.0 + </converter-display-name> + <converter-description> + StarCalc XML to/from Pocket Excel 2.0 conversion + </converter-description> + <converter-vendor>OpenOffice.org</converter-vendor> + <converter-class-impl> + org.openoffice.xmerge.converter.xml.sxc.pexcel.PluginFactoryImpl + </converter-class-impl> + <converter-target type="application/x-pocket-excel" /> + </converter> +</converters> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/makefile.mk new file mode 100644 index 000000000000..c8d22159c375 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcxs_pexcel +PRJ=../../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/package.html new file mode 100644 index 000000000000..c7da1abfbc56 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/package.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxc.pexcel package</title> +</head> + +<body bgcolor="white"> + +<p>Provides the tools for doing the conversion of StarWriter XML to +and from Pocket Excel format.</p> + +<p>It follows the {@link org.openoffice.xmerge} framework for the conversion process.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BIFFRecord.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BIFFRecord.java new file mode 100644 index 000000000000..685d6153c621 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BIFFRecord.java @@ -0,0 +1,65 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BIFFRecord.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + + public interface BIFFRecord { + + /** + * Get the type of the record. In the BIFF file format each record has a type + * designated with a byte value. See @link PocketExcelBiffConstants + * for a list of the BIFF constants and what they mean. + * + * @return byte The BIFF record value. + */ + public short getBiffType(); + + /** + * Read from the input stream <b>NB</b>The input stream is assumed to be in + * Little Endian format. The Biff identifier is expected to be in the stream. + * + * @param input The InputStream to read from. + * @return The number of bytes that were read in. + */ + public int read(InputStream input) throws IOException; + + /** + * Writes the record, including the BIFF record byte to the outputstream + * @param output The output stream to write to in LittleEndian format. + */ + public void write(OutputStream output) throws IOException; + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BeginningOfFile.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BeginningOfFile.java new file mode 100644 index 000000000000..a7b328f6cf8a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BeginningOfFile.java @@ -0,0 +1,119 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BeginningOfFile.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * This class describes the beginning of file. It is the + * the Biff record that marks the beginning of a a worbook + * or the beginning of worksheets in the workbook + * + */ +public class BeginningOfFile implements BIFFRecord { + + private byte[] version = new byte[2]; + private byte[] subStream = new byte[2]; + + /** + * Constructor that initializes the member values. + * + * @param ver Version Number + * Substream type (workbook = 0x05, worksheet = 0x10) + */ + public BeginningOfFile(boolean global) { + setVersion((short) 271); + if(global) + setSubStreamWBGlobal(); + else + setSubStreamWorkSheet(); + // this.subStream = EndianConverter.writeShort(dt); + } + + public BeginningOfFile(InputStream is) throws IOException { + read(is); + } + + private void setVersion(short version) { + this.version = EndianConverter.writeShort(version); + } + + int getVersion() { + return EndianConverter.readShort(version); + } + + private void setSubStreamWBGlobal() { + // subStream = new byte[] {0x05}; + subStream = EndianConverter.writeShort((short) 0x05); + } + + private void setSubStreamWorkSheet() { + // subStream = new byte[] {0x10}; + subStream = EndianConverter.writeShort((short) 0x10); + } + + int getSubStreamType() { + return EndianConverter.readShort(subStream); + } + + public int read(InputStream input) throws IOException { + int numBytesRead = input.read(version); + numBytesRead += input.read(subStream); + Debug.log(Debug.TRACE,"\tVersion : "+ EndianConverter.readShort(version) + + " Stream : " + EndianConverter.readShort(subStream)); + + return numBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(version); + output.write(subStream); + + Debug.log(Debug.TRACE, "Writing BeginningOfFile record"); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>BeginningOfFile</code> + */ + public short getBiffType() { + return PocketExcelConstants.BOF_RECORD; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BlankCell.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BlankCell.java new file mode 100644 index 000000000000..3bd70f0c7a91 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BlankCell.java @@ -0,0 +1,119 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BlankCell.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF Record that describes a blank cell + */ +public class BlankCell extends CellValue { + + /** + * Constructs a BlankCell <code>InputStream</code> + * + * @param is InputStream containing a BlankCell. + */ + public BlankCell(InputStream is) throws IOException { + read(is); + } + + /** + * Constructs a <code>BlankCell</code> using specified attributes + * + * @param row row number + * @param col column number + * @param cellContents contents of the cell + * @param ixfe font index + */ + public BlankCell(int row, int column, int ixfe) throws IOException { + + setRow(row); + setCol(column); + setIxfe(ixfe); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>BlankCell</code> + */ + public short getBiffType() { + return PocketExcelConstants.BLANK_CELL; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(rw); + output.write(col); + output.write(ixfe); + + Debug.log(Debug.TRACE, "Writing BlankCell record"); + + } + + /** + * Reads a BlankCell <code>InputStream</code> + * + * @param is InputStream containing a BlankCell. + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(rw); + numOfBytesRead++; + col += input.read(); + numOfBytesRead += input.read(ixfe); + + Debug.log(Debug.TRACE, "\tRow : "+ EndianConverter.readShort(rw) + + " Column : " + col + + " ixfe : " + EndianConverter.readShort(ixfe)); + + return numOfBytesRead; + } + + /** + * Gets the <code>String</code> representing the cells contents + * + * @return the <code>String</code> representing the cells contents + */ + public String getString() throws IOException { + + return (new String("")); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BoolErrCell.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BoolErrCell.java new file mode 100644 index 000000000000..6fca4ddd57d2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BoolErrCell.java @@ -0,0 +1,130 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BoolErrCell.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF Record that describes a Boolean or Error value + */ +public class BoolErrCell extends CellValue { + + private byte bBoolErr; + private byte fError; + + /** + * Constructs a BoolErrCell from arguments + * + * @param row row number + * @param col column number + * @param ixfe font index + * @param bBoolErr Boolean value or error value + * @param fError Boolean error flag + */ + public BoolErrCell(int row, int column, int ixfe, int bBoolErr, int fError) throws IOException { + + setIxfe(ixfe); + this.bBoolErr = (byte)bBoolErr; + this.fError = (byte)fError; + setRow(row); + setCol(column); + } + + /** + * Constructs a BoolErrCell from the <code>InputStream</code> + * + * @param is InputStream containing a BoolErrCell + */ + public BoolErrCell(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>BoolErrCEll</code> + */ + public short getBiffType() { + return PocketExcelConstants.BOOLERR_CELL; + } + + /** + * Writes a <code>BoolErrCell</code> to the specified <code>Outputstream</code> + * + * @param os the <code>OutputStream</code> to write to + */ + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + + super.write(output); + + output.write(bBoolErr); + output.write(fError); + + Debug.log(Debug.TRACE,"Writing BoolErrCell record"); + } + + /** + * Reads a BoolErrCell from the <code>InputStream</code> + * + * @param is InputStream containing a BoolErrCell + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = super.read(input); + + bBoolErr = (byte) input.read(); + fError = (byte) input.read(); + numOfBytesRead += 2; + + Debug.log(Debug.TRACE, " bBoolErr : " + bBoolErr + + " fError : " + fError); + return numOfBytesRead; + } + + /** + * Gets the <code>String</code> representing the cells contents + * + * @return the <code>String</code> representing the cells contents + */ + public String getString() throws IOException { + return ("Error Cell"); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BoundSheet.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BoundSheet.java new file mode 100644 index 000000000000..db34aa600fb9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/BoundSheet.java @@ -0,0 +1,140 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BoundSheet.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.io.OutputStream; +import java.io.InputStream; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BoundSheet Record which describes the name of a worksheet + */ +public class BoundSheet implements BIFFRecord { + + private byte reserved; + private byte cch; + private byte[] sheetName; + + /** + * Constructs a pocket Excel Document assigns it the document name passed in + * + * @param name name of the worksheet represented + */ + public BoundSheet(String name) throws IOException { + setSheetName(name); + reserved = 0; + } + + /** + * Constructs a pocket Excel Document from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public BoundSheet(InputStream is) throws IOException { + read(is); + } + + /** + * Sets the worksheet name. The sheetname length must be doubled as the + * String is stored in unicode format. + * + * @param sheetname worksheet name + */ + void setSheetName(String sheetName) throws IOException { + this.cch = (byte) sheetName.length(); + this.sheetName = new byte[cch*2]; + this.sheetName = sheetName.getBytes("UTF-16LE"); + } + + public String getSheetName() { + String name; + + try { + name = new String(sheetName, "UTF-16LE"); + } catch (UnsupportedEncodingException e){ + name = "unknown"; + } + return name; + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>BoundSheet</code> + */ + public short getBiffType() { + return PocketExcelConstants.BOUND_SHEET; + } + + /** + * Write this particular <code>BIFFRecord</code> to the <code>OutputStream</code> + * + * @param ouput the <code>OutputStream</code> + */ + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(reserved); + output.write(cch); + output.write(sheetName); + + Debug.log(Debug.TRACE,"Writing BoundSheet record"); + } + + /** + * Reads a BoundSheet from the <code>InputStream</code> The byte array + * must be twice the size of the String as it uses unicode. + * + * @param is InputStream containing the record data + */ + public int read(InputStream input) throws IOException { + + reserved = (byte) input.read(); + cch = (byte) input.read(); + int numOfBytesRead = 2; + int strLen = cch*2; + sheetName = new byte[strLen]; + numOfBytesRead += input.read(sheetName, 0, strLen); + + Debug.log(Debug.TRACE,"\tReserved : "+ reserved + + " cch : " + cch + + " sheetName : " + new String(sheetName,"UTF-16LE")); + + return numOfBytesRead; + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/CellValue.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/CellValue.java new file mode 100644 index 000000000000..2bb22b35666f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/CellValue.java @@ -0,0 +1,141 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CellValue.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +public abstract class CellValue implements BIFFRecord { + + protected byte[] rw = new byte[2]; + protected byte col; + protected byte[] ixfe = new byte[2]; + + /** + * Get the row number of this cell + * + * @return the row number of this cell + */ + public int getRow() { + return EndianConverter.readShort(rw) + 1; + } + + /** + * Set the row number of this cell + * + * @param row sets the row number for this cell + */ + public void setRow(int row) { + this.rw = EndianConverter.writeShort((short) (row - 1)); + } + /** + * Get the Index to the <code>ExtendedFormat</code> + * + * @return the index number of this cell's <code>ExtendedFormat</code> + */ + public int getIxfe() { + return EndianConverter.readShort(ixfe); + } + + /** + * Sets the Index to the <code>ExtendedFormat</code> + * + * @param ixfe sets the index number for this cell's <code>ExtendedFormat</code> + */ + public void setIxfe(int ixfe) { + this.ixfe = EndianConverter.writeShort((short) (ixfe)); + } + + /** + * Get the column number of this cell + * + * @return the column number of this cell + */ + public int getCol() { + return col + 1; // The cols start at 1 + } + + /** + * Set the row number of this cell + * + * @param col sets the row number for this cell + */ + public void setCol(int col) { + this.col = (byte) (col - 1); // The cols start at 1 + } + + /** + * Writes basic cell value attributes to the specified <code>Outputstream</code> + * + * @param os the <code>OutputStream</code> to write to + */ + public void write(OutputStream output) throws IOException { + + output.write(rw); + output.write(col); + output.write(ixfe); + } + + /** + * Writes a<code>LabelCell</code> to the specified <code>Outputstream</code> + * + * @param os the <code>OutputStream</code> to write to + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(rw); + col += input.read(); + numOfBytesRead++; + numOfBytesRead += input.read(ixfe); + + Debug.log(Debug.TRACE, "\tRow : "+ EndianConverter.readShort(rw) + + " Column : " + col + + " ixfe : " + EndianConverter.readShort(ixfe)); + + return numOfBytesRead; + } + + + /** + * Returns the contents of the cell as a String + * + * @return the contents of the cell + */ + abstract public String getString() throws IOException; + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/CodePage.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/CodePage.java new file mode 100644 index 000000000000..55184582ebdb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/CodePage.java @@ -0,0 +1,111 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CodePage.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents the codepage for the document. There is a number of unknown + * fields which are hardcoded at construction + */ +public class CodePage implements BIFFRecord { + + private byte[] codepage = new byte[2]; + private byte[] unknown1 = new byte[2]; + private byte[] unknown2 = new byte[2]; + private byte unknown3; + + /** + * Constructs a pocket Excel Codepage + */ + public CodePage() { + codepage = new byte[] {(byte)0xE4, (byte)0x04}; + unknown1 = new byte[] {(byte)0x8C, (byte)0x01}; + unknown2 = new byte[] {(byte)0x00, (byte)0x01}; + unknown3 = 0x00; + } + + /** + * Constructs a pocket Excel Codepage from the<code>InputStream</code> + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public CodePage(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>BoundSheet</code> + */ + public short getBiffType() { + return PocketExcelConstants.CODEPAGE; + } + + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(codepage); + numOfBytesRead += input.read(unknown1); + numOfBytesRead += input.read(unknown2); + // numOfBytesRead += input.read(unknown3); + unknown3 = (byte) input.read(); + numOfBytesRead++; + + Debug.log(Debug.TRACE,"\tcodepage : "+ EndianConverter.readShort(codepage) + + " unknown1 : " + EndianConverter.readShort(unknown1) + + " unknown2 : " + EndianConverter.readShort(unknown2) + + " unknown3 : " + unknown3); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(codepage); + output.write(unknown1); + output.write(unknown2); + output.write(unknown3); + + Debug.log(Debug.TRACE,"Writing CodePage record"); + + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/ColInfo.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/ColInfo.java new file mode 100644 index 000000000000..d3e61e1b4fec --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/ColInfo.java @@ -0,0 +1,161 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ColInfo.java,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.IOException; +import java.io.DataInputStream; +import java.io.InputStream; +import java.io.OutputStream; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * ColInfo describes the formatting for a column + * + */ +public class ColInfo implements BIFFRecord { + + private byte[] colFirst = new byte[2]; // first column this formatting applies to + private byte[] colLast = new byte[2]; // last column this formatting applies to + private byte[] colDX = new byte[2]; // column width + private byte[] ixfe = new byte[2]; // index for formatting + private byte grbit; // options flags + private float scale = (float) 2.5; // 1.798; + + /** + * Constructs a pocket Excel Document from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param colFirst the first column this formatting applies to + * @param colLast last column this formatting applies to + * @param coldx column width + * @param grbit options flags + */ + public ColInfo(int colFirst, int colLast, int colDX, int ixfe) { + this.colFirst = EndianConverter.writeShort((short)colFirst); + this.colLast = EndianConverter.writeShort((short)colLast); + colDX *= scale; + this.colDX = EndianConverter.writeShort((short)colDX); + this.ixfe = EndianConverter.writeShort((short)ixfe); + this.grbit = 0x00; + } + + /** + * Construct a ColInfo from the InputStream + * + * @param is the <code>Inputstream</code> to read from + */ + public ColInfo(InputStream is) throws IOException { + read(is); + } + + /** + * Reads ColInfo record from the InputStream + * + * @param input the InputStream to read from + * @return the number of bytes read + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(colFirst); + numOfBytesRead += input.read(colLast); + numOfBytesRead += input.read(colDX); + short scaledDX = (short) (EndianConverter.readShort(colDX) / scale); + colDX = EndianConverter.writeShort(scaledDX); + numOfBytesRead += input.read(ixfe); + grbit = (byte) input.read(); + numOfBytesRead ++; + + Debug.log(Debug.TRACE,"\tcolFirst : "+ EndianConverter.readShort(colFirst) + + " colLast : " + EndianConverter.readShort(colLast) + + " colDX : " + EndianConverter.readShort(colDX) + + " ixfe : " + EndianConverter.readShort(ixfe) + + " grbit : " + grbit); + + return numOfBytesRead; + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>ColInfo</code> + */ + public short getBiffType() { + return PocketExcelConstants.COLINFO; + } + /** + * Get the width of this column + * + * @return the width of this column + */ + public short getColWidth() { + return EndianConverter.readShort(colDX); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>ColInfo</code> + */ + public short getFirst() { + return EndianConverter.readShort(colFirst); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>ColInfo</code> + */ + public short getLast() { + return EndianConverter.readShort(colLast); + } + + /** + * Writes a ColInfo to the specified <code>Outputstream</code> + * + * @param os the <code>OutputStream</code> to write to + */ + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(colFirst); + output.write(colLast); + output.write(colDX); + output.write(ixfe); + output.write(grbit); + + Debug.log(Debug.TRACE,"Writing ColInfo record"); + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefColWidth.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefColWidth.java new file mode 100644 index 000000000000..12a451334386 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefColWidth.java @@ -0,0 +1,98 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DefColWidth.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF record defiuning the defualt column width + */ +public class DefColWidth implements BIFFRecord { + + private byte[] grbit = new byte[2]; + private byte[] coldx = new byte[2]; + private byte[] ixfe = new byte[2]; + +/** + * Constructs a pocket Excel Document from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public DefColWidth() { + grbit = new byte[] {0x00, 0x00}; + coldx = new byte[] {0x00, 0x09}; + ixfe = new byte[] {0x00, 0x00}; + } + + public DefColWidth(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>DefColWidth</code> + */ + public short getBiffType() { + return PocketExcelConstants.DEF_COL_WIDTH; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(grbit); + output.write(coldx); + output.write(ixfe); + + Debug.log(Debug.TRACE, "Writing DefColWidth record"); + } + + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(grbit); + numOfBytesRead += input.read(coldx); + numOfBytesRead += input.read(ixfe); + + Debug.log(Debug.TRACE,"\tgrbit : "+ EndianConverter.readShort(grbit) + + " coldx : " + EndianConverter.readShort(coldx) + + " ixfe : " + EndianConverter.readShort(ixfe)); + return 0; + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefRowHeight.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefRowHeight.java new file mode 100644 index 000000000000..d924f339fe37 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefRowHeight.java @@ -0,0 +1,100 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DefRowHeight.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF record defiuning the default row height + */ +public class DefRowHeight implements BIFFRecord { + + private byte[] unknown1 = new byte[2]; + private byte[] unknown2 = new byte[2]; + + /** + * Constructs a pocket Excel Document from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public DefRowHeight() { + unknown1 = new byte[] {(byte)0x00, (byte)0x00}; + unknown2 = new byte[] {(byte)0xFF, (byte)0x00}; + } + + /** + * Constructs a DefRowHeight from the <code>InputStream</code> + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public DefRowHeight(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>DefRowHeight</code> + */ + public short getBiffType() { + return PocketExcelConstants.DEFAULT_ROW_HEIGHT; + } + + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(unknown1); + numOfBytesRead += input.read(unknown2); + + Debug.log(Debug.TRACE,"\tunknown1 : "+ EndianConverter.readShort(unknown1) + + " unknown2 : " + EndianConverter.readShort(unknown2)); + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(unknown1); + output.write(unknown2); + + Debug.log(Debug.TRACE,"Writing DefRowHeight record"); + + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefinedName.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefinedName.java new file mode 100644 index 000000000000..3fad2410162e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/DefinedName.java @@ -0,0 +1,230 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DefinedName.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula.FormulaHelper; +import org.openoffice.xmerge.converter.xml.sxc.NameDefinition; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF Record representing a defined name in the workbook + */ +public class DefinedName implements BIFFRecord { + + private byte[] grbit = new byte[2]; + private byte cch; + private byte[] cce = new byte[2]; + private byte[] ixals = new byte[2]; + private byte[] rgch; + private byte[] rgce; + private FormulaHelper fh = new FormulaHelper(); + private String definition = new String(""); + private Workbook wb; + + /** + * Constructs a Defined Name from the <code>InputStream</code> + * + * @param is InputStream containing the record data + */ + public DefinedName(NameDefinition nd, Workbook wb) throws IOException { + + fh.setWorkbook(wb); + this.wb = wb; + String name = nd.getName(); + + // we have to insert an = to stop the formulaParser throwing an exception + definition = "=" + nd.getDefinition(); + + cch = (byte)name.length(); + rgch = new byte[cch*2]; + rgch = name.getBytes("UTF-16LE"); + grbit = EndianConverter.writeShort((short)0); + ixals[0] = (byte)0xFF;ixals[1] = (byte)0xFF; + } + /** + * Constructs a Defined Name from the <code>InputStream</code> + * + * @param is InputStream containing the record data + */ + public DefinedName(InputStream is, Workbook wb) throws IOException { + + read(is); + fh.setWorkbook(wb); + this.wb = wb; + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>DefinedName</code> + */ + public short getBiffType() { + return PocketExcelConstants.DEFINED_NAME; + } + + /** + * Reads a Defined Name from the <code>InputStream</code> The byte array + * must be twice the size of the String as it uses unicode. + * + * @param is InputStream containing the record data + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(grbit); + cch = (byte) input.read(); + numOfBytesRead++; + numOfBytesRead += input.read(cce); + numOfBytesRead += input.read(ixals); + + rgch = new byte[cch*2]; + input.read(rgch, 0, cch*2); + + rgce = new byte[EndianConverter.readShort(cce)]; + input.read(rgce, 0, EndianConverter.readShort(cce)); + + + + Debug.log(Debug.TRACE, "\tgrbit : "+ EndianConverter.readShort(grbit) + + " cch : " + cch + + " cce : " + EndianConverter.readShort(cce) + + " ixals : " + EndianConverter.readShort(ixals) + + "\n\trgch : " + rgch + + " rgce : " + rgce); + + return numOfBytesRead; + } + + /** + * Write this particular <code>BIFFRecord</code> to the <code>OutputStream</code> + * + * @param ouput the <code>OutputStream</code> + */ + public void write(OutputStream output) throws IOException { + + try { + Debug.log(Debug.TRACE,"Writing out " + definition); + rgce = fh.convertCalcToPXL(definition); + cce = EndianConverter.writeShort((short) rgce.length); + } catch(Exception e) { + Debug.log(Debug.TRACE,"Error in Parsing Name Definition"); + cce = EndianConverter.writeShort((short) 0); + } + + + output.write(getBiffType()); + output.write(grbit); + output.write(cch); + output.write(cce); + output.write(ixals); + output.write(rgch); + if(rgce.length!=0) + output.write(rgce); + + Debug.log(Debug.TRACE,"Writing DefinedName record"); + } + + /** + * Returns definition name. This is public because the + * <code>TokenDecoder</code> has to substitue the Name token with this + * String when writing out to sxc + * + * @return the <code>String</code> containing the name + */ + public String getName() { + String name; + + try { + name = new String(rgch, "UTF-16LE"); + } catch (UnsupportedEncodingException e){ + name = "unknown"; + } + return name; + } + + /** + * Returns a definition table which can be used by the pocket excel + * decoder to build a complete definitions table for writing to the sxc + * document + */ + public NameDefinition getNameDefinition() { + + String baseCellAddress; + getDefinition(); // This must be called first so we know the type + + baseCellAddress = "$" + wb.getSheetName(0) + ".A1"; + + NameDefinition nd = new NameDefinition(getName(),definition, baseCellAddress, isRangeType(), isExpressionType()); + return nd; + } + + /** + * Returns the definition + * + * @return the <code>String</code> containing the definition + */ + private String getDefinition() { + // pexcel sometimes creates Name definition with no defintion, bug?? + if(EndianConverter.readShort(cce)!=0) { + definition = fh.convertPXLToCalc(rgce); + definition = definition.substring(1); // remove the '=' + definition = definition.replace(',', ';'); + } + return definition; + } + + /** + * Returns the defintion + * + * @return the <code>String</code> containing the definition + */ + private boolean isRangeType() { + + return fh.isRangeType(); + } + /** + * Returns the defintion + * + * @return the <code>String</code> containing the definition + */ + private boolean isExpressionType() { + + return fh.isExpressionType(); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Eof.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Eof.java new file mode 100644 index 000000000000..77a4e97835cf --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Eof.java @@ -0,0 +1,75 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Eof.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF Record used to mark the end of a section of file + */ +public class Eof implements BIFFRecord { + + /** + * Constructor + */ + public Eof() { + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>BeginningOfFile</code> + */ + public short getBiffType() { + return PocketExcelConstants.EOF_MARKER; + } + + public int read(InputStream input) throws IOException { + return 0; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + + Debug.log(Debug.TRACE,"Writing Eof record"); + + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/ExtendedFormat.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/ExtendedFormat.java new file mode 100644 index 000000000000..254c2f2bddf4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/ExtendedFormat.java @@ -0,0 +1,388 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ExtendedFormat.java,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.awt.Color; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.util.ColourConverter; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF Record descibing extended formatting information + * + */ +public class ExtendedFormat implements BIFFRecord, +org.openoffice.xmerge.converter.xml.OfficeConstants { + + private byte[] ixfnt = new byte[2]; // Index to Font Record + private byte[] ixnf = new byte[2]; + private byte[] fattributes = new byte[4]; + private byte[] fBaseAttr = new byte[2]; // base attribute flags + private byte[] fTextAttr = new byte[2]; // text attribute flags + private byte[] icvFore = new byte[2]; // Background colour of the cell + private byte[] icvFill = new byte[2]; + private byte bRight; // Right border Style + private byte bTop; // Top border style + private byte bLeft; // Left border style + private byte bBottom; // Bottom border style + private byte backstyle; + private byte borderstyle; + + public static final int TOP_BORDER = 0x01; + public static final int LEFT_BORDER = 0x02; + public static final int BOTTOM_BORDER = 0x04; + public static final int RIGHT_BORDER = 0x08; + + // Horizontal Alignment Styles + public static final int NORMAL_ALIGN = 0x00; + public static final int LEFT_ALIGN = 0x01; + public static final int CENTER_ALIGN = 0x02; + public static final int RIGHT_ALIGN = 0x03; + + // Vertical Alignment Styles + public static final int TOP_ALIGN = 0x10; + public static final int MIDDLE_ALIGN = 0x20; + public static final int BOTTOM_ALIGN = 0x30; + + public static final int WORD_WRAP = 0x08; + + /** + * Constructs an <code>ExtendedFormat</code> from the + * <code>InputStream</code> + * + * @param is <code>InputStream</code> to read from + */ + public ExtendedFormat(InputStream is) throws IOException { + read(is); + } + + /** + * Constructs a pocket Excel Document using defualt values and sets the + * font index using the specified attribute + * + * @param ixfnt index of the font this format should use + */ + public ExtendedFormat(int ixfnt, Format fmt) { + + this.ixfnt = EndianConverter.writeShort((short)ixfnt); + String category = fmt.getCategory(); + if(category.equalsIgnoreCase(CELLTYPE_CURRENCY)) { + this.ixnf = EndianConverter.writeShort((short) 0); + } else if(category.equalsIgnoreCase(CELLTYPE_DATE)) { + this.ixnf = EndianConverter.writeShort((short) 0x12); + } else if(category.equalsIgnoreCase(CELLTYPE_TIME)) { + this.ixnf = EndianConverter.writeShort((short) 0x1E); + } else { + this.ixnf = EndianConverter.writeShort((short) 0); + } + this.fattributes = new byte[] {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}; + this.fBaseAttr = new byte[] {(byte)0x02,(byte)0x00}; + + this.fTextAttr = new byte[] {(byte)0x00, (byte)0x00}; + + int align = fmt.getAlign(); + + // Horizontal alignment + if(align==Format.CENTER_ALIGN) { + fTextAttr[0] |= CENTER_ALIGN; + } else if(align==Format.LEFT_ALIGN) { + fTextAttr[0] |= LEFT_ALIGN; + } else if(align==Format.RIGHT_ALIGN) { + fTextAttr[0] |= RIGHT_ALIGN; + } else { + fTextAttr[0] |= NORMAL_ALIGN; + } + + int vertAlign = fmt.getVertAlign(); + + // Vertical alignment + if(vertAlign==Format.TOP_ALIGN) { + fTextAttr[0] |= TOP_ALIGN; + } else if(vertAlign==Format.BOTTOM_ALIGN) { + fTextAttr[0] |= BOTTOM_ALIGN; + } else if(vertAlign==Format.MIDDLE_ALIGN) { + fTextAttr[0] |= MIDDLE_ALIGN; + } else { + fTextAttr[0] |= BOTTOM_ALIGN; + } + + if(fmt.getAttribute(Format.WORD_WRAP)) { + fTextAttr[0] |= WORD_WRAP; + } + + if(fmt.getAttribute(Format.LEFT_BORDER)) { + fTextAttr[1] |= LEFT_BORDER; + } + if(fmt.getAttribute(Format.RIGHT_BORDER)) { + fTextAttr[1] |= RIGHT_BORDER; + } + if(fmt.getAttribute(Format.TOP_BORDER)) { + fTextAttr[1] |= TOP_BORDER; + } + if(fmt.getAttribute(Format.BOTTOM_BORDER)) { + fTextAttr[1] |= BOTTOM_BORDER; + } + + Color background = fmt.getBackground(); + if( background != null ) { + ColourConverter cc = new ColourConverter(PocketExcelConstants.cLookup); + icvFill = EndianConverter.writeShort(cc.convertFromRGB(background)); + } else { + icvFill = new byte[] {(byte)0xFF,(byte)0x00}; + } + + icvFore = new byte[] {(byte)0xFF,(byte)0x00}; + + bRight = (byte) 0xFF; + bTop = (byte) 0xFF; + bLeft = (byte) 0xFF; + bBottom = (byte) 0xFF; + backstyle = (byte) 0x00; + borderstyle = (byte) 0x00; + + } + + /** + * Get the font index this format uses + * + * @return the font index + */ + public int getFontIndex() { + return EndianConverter.readShort(ixfnt); + } + + /** + * Get the font index this format uses + * + * @return the font index + */ + public int getFormatIndex() { + return EndianConverter.readShort(ixnf); + } + + /** + * Get the font index this format uses + * + * @return the font index + */ + public int getTextAttr() { + return EndianConverter.readShort(fTextAttr); + } + + /** + * Get the background color this format uses + * + * @return the background color + */ + public Color getBackground() { + short rgb = EndianConverter.readShort(icvFill); + Color c = null; + if(rgb!=0xFF) { + ColourConverter cc = new ColourConverter(PocketExcelConstants.cLookup); + c = cc.convertToRGB(rgb); + } + return c; + } + + /** + * Get the Vertical alignment for this Format + * + * @return the alignment + */ + public int getVertAlign() { + + int mask = MIDDLE_ALIGN | BOTTOM_ALIGN | TOP_ALIGN; + int masked = fTextAttr[0] & mask; + + if(masked == MIDDLE_ALIGN) + return Format.MIDDLE_ALIGN; + + if(masked == BOTTOM_ALIGN) + return Format.BOTTOM_ALIGN; + + if(masked == TOP_ALIGN) + return Format.TOP_ALIGN; + + return Format.BOTTOM_ALIGN; + } + + /** + * Get the alignment for this Format + * + * @return the alignment + */ + public int getAlign() { + + int mask = LEFT_ALIGN | CENTER_ALIGN | RIGHT_ALIGN; + int masked = fTextAttr[0] & mask; + + if(masked == MIDDLE_ALIGN) + return Format.LEFT_ALIGN; + + if(masked == CENTER_ALIGN) + return Format.CENTER_ALIGN; + + if(masked == RIGHT_ALIGN) + return Format.RIGHT_ALIGN; + + return Format.LEFT_ALIGN; + } + + /** + * Is the word wrap set + * + * @return true if it is selected + */ + public boolean isWordWrap() { + return (!((fTextAttr[0] & WORD_WRAP) == 0)); + } + /** + * Get the border style + * + * @param side the side to test + * @return true if it is selected + */ + public boolean isBorder(int side) { + return (!((fTextAttr[1] & side) == 0)); + } + + /** + * Compare two ExtendedFormat to see if the font index is the same + * + * @param the ExtendedFormat to be used in the comaprison + * @return boolean if the two are the same otherwise false + */ + public boolean compareTo(ExtendedFormat rhs) { + + if(EndianConverter.readShort(icvFill) != + EndianConverter.readShort(rhs.icvFill)) + return false; + + if(this.getTextAttr() != rhs.getTextAttr()) + return false; + + if(this.getVertAlign() != rhs.getVertAlign()) + return false; + + if(this.getAlign() != rhs.getAlign()) + return false; + + if (this.getFontIndex() != rhs.getFontIndex()) + return false; + + if (this.getFormatIndex() != rhs.getFormatIndex()) + return false; + + return true; + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>ExtendedFormat</code> + */ + public short getBiffType() { + return PocketExcelConstants.EXTENDED_FORMAT; + } + + /** + * Reads the extended format from the <code>Inputstream</code> + * + * @param input the <code>Inputstream</code>to read + * @return toal number of bytes read + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(ixfnt); + numOfBytesRead += input.read(ixnf); + numOfBytesRead += input.read(fattributes); + numOfBytesRead += input.read(fBaseAttr); + numOfBytesRead += input.read(fTextAttr); + numOfBytesRead += input.read(icvFore); + numOfBytesRead += input.read(icvFill); + bRight = (byte) input.read(); + bTop = (byte) input.read(); + bLeft = (byte) input.read(); + bBottom = (byte) input.read(); + backstyle = (byte) input.read(); + borderstyle = (byte) input.read(); + numOfBytesRead += 6; + + Debug.log(Debug.TRACE,"\tixfnt : "+ EndianConverter.readShort(ixfnt) + + " ixnf : " + EndianConverter.readShort(ixnf) + + " fattributes : " + EndianConverter.readInt(fattributes) + + " fBaseAttr : " + EndianConverter.readShort(fBaseAttr) + + "\n\tfTextAttr : " + EndianConverter.readShort(fTextAttr) + + " icvFore : " + EndianConverter.readShort(icvFore) + + " icvFill : " + EndianConverter.readShort(icvFill) + + " bRight : " + bRight + + "\n\tbTop : " + bTop + + " bLeft : " + bLeft + + " bBottom : " + bBottom + + " backstyle : " + backstyle + + " borderstyle : " + borderstyle); + return numOfBytesRead; + } + + /** + * Writes the ExtendedFormat to the <code>Outputstream<code> + * + * @param output the <code>Outputstream</code>to write to + */ + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(ixfnt); + output.write(ixnf); + output.write(fattributes); + output.write(fBaseAttr); + output.write(fTextAttr); + output.write(icvFore); + output.write(icvFill); + output.write(bRight); + output.write(bTop); + output.write(bLeft); + output.write(bBottom); + output.write(backstyle); + output.write(borderstyle); + + Debug.log(Debug.TRACE,"Writing ExtendedFormat record"); + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/FloatNumber.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/FloatNumber.java new file mode 100644 index 000000000000..db80eccb9cb8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/FloatNumber.java @@ -0,0 +1,124 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FloatNumber.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + +/** + * Represents a BIFF Record describing a floating point + */ +public class FloatNumber extends CellValue { + + protected byte[] num = new byte[8]; + + /** + * Constructs a pocket Excel Document from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public FloatNumber(InputStream is) throws IOException { + read(is); + } + + /** + * Constructs a <code>FloatNumber</code> using specified attributes + * + * @param row row number + * @param col column number + * @param cellContents contents of the cell + * @param ixfe font index + */ + public FloatNumber(int row, int column, String cellContents, int ixfe) throws IOException { + + setIxfe(ixfe); + setRow(row); + setCol(column); + double cellLong = (double) Double.parseDouble(cellContents); + num = EndianConverter.writeDouble(cellLong); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>FloatNumber</code> + */ + public short getBiffType() { + return PocketExcelConstants.NUMBER_CELL; + } + + /** + * Reads a<code>FloatNumber</code> from the specified <code>InputStream</code> + * + * @param input the <code>InputStram</code> to read from + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = super.read(input); + + numOfBytesRead += input.read(num); + + Debug.log(Debug.TRACE," num : " + getString()); + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + + super.write(output); + + output.write(num); + + Debug.log(Debug.TRACE,"Writing FloatNumber record"); + } + + + /** + * Gets the numerical value the cell represents + * + * @return the <code>String</code> representing a double value + */ + public String getString() throws IOException { + + double value = EndianConverter.readDouble(num); + Double myDo = new Double(value); + return myDo.toString(); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/FontDescription.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/FontDescription.java new file mode 100644 index 000000000000..50ff9e5e64d7 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/FontDescription.java @@ -0,0 +1,290 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FontDescription.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.awt.Color; + +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.util.ColourConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents a BIFF Record descibing a font used + */ +public class FontDescription implements BIFFRecord { + + private byte[] dwHeight = new byte[2]; + private byte[] grbit = new byte[2]; + private byte[] icvFore = new byte[2]; + private byte[] bls = new byte[2]; + private byte[] Reserved2 = new byte[2]; + private byte uls; + private byte bFamily; + private byte bCharSet; + private byte Reserved3; + private byte cch; + private byte[] rgch; + + public static final int UNDERLINE = 0x01; + public static final int ITALIC = 0x02; + + /** + * Constructs a FontDescription from the bold italic and undelrine attributes + * + * @param italic Italic attribute + * @param bold Bold attribute + * @param underline Underline attribute + */ + public FontDescription(Format fmt) throws IOException { + + Debug.log(Debug.TRACE,"Building FontDescriptor based on Format : " + fmt); + + this.dwHeight = EndianConverter.writeShort((short) (fmt.getFontSize()*20)); + + grbit = new byte[] {(byte)0x00, (byte)0x00}; + bls = EndianConverter.writeShort((short) 400); + uls = 0; + + if (fmt.getAttribute(Format.ITALIC)) + grbit[0] |= ITALIC; + + if (fmt.getAttribute(Format.BOLD)) + bls = EndianConverter.writeShort((short) 700); + + if (fmt.getAttribute(Format.UNDERLINE)) + uls |= UNDERLINE; + + + bFamily = 0; + bCharSet = 0; + + String fontName = fmt.getFontName(); + if( !fontName.equals("Tahoma") && + !fontName.equals("Courier New")) { + // We will set our default font to be Tahoma + fontName = new String("Tahoma"); + } + + cch = (byte) fontName.length(); + rgch = fontName.getBytes("UTF-16LE"); + + Color foreground = fmt.getForeground(); + if( foreground != null ) { + ColourConverter cc = new ColourConverter(PocketExcelConstants.cLookup); + icvFore = EndianConverter.writeShort(cc.convertFromRGB(foreground)); + } else { + icvFore = new byte[] {(byte)0xFF,(byte)0x00}; + } + + Reserved2 = EndianConverter.writeShort((short) 0); + Reserved3 = 0; + + } + + /** + * Tests if this font descriptor defines italic + * + * @return true if italic otherwise false + */ + public boolean isItalic() { + + return (EndianConverter.readShort(grbit) == 2); + } + + /** + * Tests if this font descriptor defines underline + * + * @return true if underline otherwise false + */ + public boolean isUnderline() { + + return (uls == 1); + } + + /** + * Tests if this font descriptor defines bold + * + * @return true if bold otherwise false + */ + public boolean isBold() { + + return (EndianConverter.readShort(bls) == 700); + } + + /** + * Get the background color this format uses + * + * @return the background color + */ + public Color getForeground() { + short rgb = EndianConverter.readShort(icvFore); + Color c = null; + if(rgb!=0xFF) { + ColourConverter cc = new ColourConverter(PocketExcelConstants.cLookup); + c = cc.convertToRGB(rgb); + } + return c; + } + + /** + * Compares current font descriptor against one passed in + * + * @return true if attrbitues are the same + */ + public boolean compareTo(FontDescription rhs) { + + if(EndianConverter.readShort(icvFore) != + EndianConverter.readShort(rhs.icvFore)) + return false; + + if (EndianConverter.readShort(dwHeight) != + EndianConverter.readShort(dwHeight)) + return false; + + if (this.getFont() != rhs.getFont()) + return false; + + if (this.isBold() != rhs.isBold()) + return false; + + if (this.isUnderline() != rhs.isUnderline()) + return false; + + if (this.isItalic() != rhs.isItalic()) + return false; + + return true; + } + + + /** + * Constructs a Font Description from the <code>InputStream</code> + * + * @param is InputStream containing a <code>FontDescription</code> + */ + public FontDescription(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>FontDescription</code> + */ + public short getBiffType() { + return PocketExcelConstants.FONT_DESCRIPTION; + } + + /** + * Get the Font size + * + */ + public int getFontSize() { + return EndianConverter.readShort(dwHeight)/20; + } + + /** + * Get the font name + * + */ + public String getFont() { + + String name; + + try { + name = new String(rgch, "UTF-16LE"); + } catch (UnsupportedEncodingException e){ + name = "Tahoma"; + } + return name; + } + + /** + * Constructs a Font Description from the <code>InputStream</code> + * + * @param is InputStream containing a <code>FontDescription</code> + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(dwHeight); + numOfBytesRead += input.read(grbit); + numOfBytesRead += input.read(icvFore); + numOfBytesRead += input.read(bls); + numOfBytesRead += input.read(Reserved2); + uls = (byte) input.read(); + bFamily = (byte) input.read(); + bCharSet = (byte) input.read(); + Reserved3 = (byte) input.read(); + cch = (byte) input.read(); + numOfBytesRead += 5; + + rgch = new byte[cch*2]; + input.read(rgch, 0, cch*2); + + Debug.log(Debug.TRACE,"\tdwHeight : "+ EndianConverter.readShort(dwHeight) + + " grbit : " + EndianConverter.readShort(grbit) + + " bls : " + EndianConverter.readShort(bls) + + " uls : " + uls + + "\n\tFamily : " + bFamily + + " bCharSet : " + bCharSet + + " cch : " + cch + + " rgch : " + new String(rgch,"UTF-16LE")); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(dwHeight); + output.write(grbit); + output.write(icvFore); + output.write(bls); + output.write(Reserved2); + output.write(uls); + output.write(bFamily); + output.write(bCharSet); + output.write(Reserved3); + output.write(cch); + output.write(rgch); + + Debug.log(Debug.TRACE,"Writing FontDescription record"); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Formula.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Formula.java new file mode 100644 index 000000000000..b2f74f1f6be9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Formula.java @@ -0,0 +1,266 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Formula.java,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.util.Vector; +import java.util.Enumeration; +import java.util.Calendar; +import java.util.Date; +import java.text.DateFormat; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula.FormulaHelper; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents a BIFF Record describing a formula + */ +public class Formula extends CellValue implements OfficeConstants { + + private byte[] num = new byte[8]; + private byte grbit; + private byte[] cce = new byte[2]; + private byte[] rgce; + private FormulaHelper fh = new FormulaHelper(); + + /** + * Constructs a <code>Formula</code> using specified attributes + * + * @param row row number + * @param col column number + * @param cellContents contents of the cell + * @param ixfe font index + * @param value the value of the cell + */ + public Formula(int row, int column, String cellContents, int ixfe, Format fmt, Workbook wb) + throws Exception { + + fh.setWorkbook(wb); + + setRow(row); + setCol(column); + setIxfe(ixfe); + setFormula(cellContents); + + String category = fmt.getCategory(); + String value = fmt.getValue(); + + if(category.equalsIgnoreCase(CELLTYPE_BOOLEAN)) { + num[0]=(byte)0x01; + num[1]=(byte)0x00; + if(value.equalsIgnoreCase("true")) { + num[2]=(byte)0x01; + } else { + num[2]=(byte)0x00; + } + num[3]=(byte)0x00;num[4]=(byte)0x00;num[5]=(byte)0x00; + num[6]=(byte)0xFF;num[7]=(byte)0xFF; + } else if(category.equalsIgnoreCase(CELLTYPE_DATE)) { + Debug.log(Debug.TRACE,"Date Formula"); + num = EndianConverter.writeDouble(toExcelSerialDate(fmt.getValue())); + } else if(category.equalsIgnoreCase(CELLTYPE_TIME)) { + Debug.log(Debug.TRACE,"Time Formula"); + num = EndianConverter.writeDouble(toExcelSerialTime(fmt.getValue())); + } else if(category.equalsIgnoreCase(CELLTYPE_PERCENT)) { + Debug.log(Debug.TRACE,"Percent Formula"); + double percent = (double) Double.parseDouble(fmt.getValue()); + num = EndianConverter.writeDouble(percent); + } else if(category.equalsIgnoreCase(CELLTYPE_CURRENCY)) { + Debug.log(Debug.TRACE,"Currency Formula"); + } else if(category.equalsIgnoreCase(CELLTYPE_STRING)) { + Debug.log(Debug.TRACE,"String Formula"); + num[0]=(byte)0x00; + num[1]=(byte)0x00; + num[2]=(byte)0x00; + num[3]=(byte)0x00; + num[4]=(byte)0x00; + num[5]=(byte)0x00; + num[6]=(byte)0xFF; + num[7]=(byte)0xFF; + } else { + Debug.log(Debug.TRACE,"Float Formula"); + double cellLong = (double) Double.parseDouble(fmt.getValue()); + num = EndianConverter.writeDouble(cellLong); + } + } + + /** + * Translates a <code>String</code> written in infix which represents a + * formula into a byte[] what can be written to pocket excel file. + * + * @param formula string + */ + public void setFormula(String inFormula) throws Exception { + + rgce = fh.convertCalcToPXL(inFormula); + cce = EndianConverter.writeShort((short) rgce.length); + } + + /** + * Constructs a pocket Excel formula from the + * <code>InputStream</code> + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public Formula(InputStream is, Workbook wb) throws IOException { + read(is); + fh.setWorkbook(wb); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Formula</code> + */ + public short getBiffType() { + return PocketExcelConstants.FORMULA_CELL; + } + + /** + * Reads the formula data members from the stream. Byte arrays for Strings + * are doubled as they are stored as unicode + * + * @return total number of bytes read + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = super.read(input); + + numOfBytesRead += input.read(num); + grbit = (byte) input.read(); + numOfBytesRead ++; + numOfBytesRead += input.read(cce); + + int strLen = EndianConverter.readShort(cce); + rgce = new byte[strLen]; + input.read(rgce, 0, strLen); + + Debug.log(Debug.TRACE, " num : " + num + + "\n\tgrbit : " + grbit + + " cce : " + EndianConverter.readShort(cce) + + " rgce : " + new String(rgce,"UTF-16LE") + + "\n" + numOfBytesRead + " Bytes Read"); + + return numOfBytesRead; + } + + /** + * Writes the Formula record to the <code>OutputStream</code> + * + * @param the <code>OutputStream</code> being written to + */ + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + + super.write(output); + + output.write(num); + output.write(grbit); + output.write(cce); + output.write(rgce); + + Debug.log(Debug.TRACE,"Writing Formula record"); + } + + /** + * Gets the <code>String</code> representing the cell value + * + * @return the <code>String</code> representing the cell value + */ + public String getValue() throws IOException { + + double value = EndianConverter.readDouble(num); + Double myDo = new Double(value); + return myDo.toString(); + } + + /** + * Gets the <code>String</code> representing the cells contents + * + * @return the <code>String</code> representing the cells contents + */ + public String getString() throws IOException { + + return fh.convertPXLToCalc(rgce); + } + + /** + * Excel dates are the number of days since 1/1/1900. This method converts + * to this date. + * + * @param s String representing a date in the form YYYY-MM-DD + * @return The excel serial date + */ + public long toExcelSerialDate(String s) throws IOException { + + int year = Integer.parseInt(s.substring(0,4)); + int month = Integer.parseInt(s.substring(5,7)); + int day = Integer.parseInt(s.substring(8,10)); + + long serialDate = (1461 * (year + 4800 + (month - 14) / 12)) / 4 + + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12 - + (3 * ((year + 4900 + (month - 14) / 12)) / 100) / 4 + + day - 2415019 - 32075; + + return serialDate; + } + + /** + * Excel times are a fraction of a 24 hour day expressed in seconds. This method converts + * to this time. + * + * @param s String representing a time in the form ??HH?MM?SS? + * @return The excel serial time + */ + public double toExcelSerialTime(String s) throws IOException { + + int hours = Integer.parseInt(s.substring(2,4)); + int mins = Integer.parseInt(s.substring(5,7)); + int secs = Integer.parseInt(s.substring(8,10)); + + int timeSecs = (hours*3600) + (mins*60) + (secs); + + double d = (double) timeSecs / (24 * 3600); + + return d; + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/LabelCell.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/LabelCell.java new file mode 100644 index 000000000000..aafe992cad47 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/LabelCell.java @@ -0,0 +1,143 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: LabelCell.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Reperesent a BIFF Record descibing a cell containing a string + */ +public class LabelCell extends CellValue { + + private byte[] cch = new byte[2]; + private byte[] rgch; + + /** + * Constructs a <code>LabelCell</code> using specified attributes + * + * @param row row number + * @param col column number + * @param cellContents contents of the cell + * @param ixfe font index + */ + public LabelCell(int row, int column, String cellContents, int ixfe) + throws IOException { + + setLabel(cellContents); + setRow(row); + setCol(column); + setIxfe(ixfe); + } + + /** + * Reads a LabelCell from the <code>InputStream</code> + * + * @param is the <code>Inputstream</code> to read from + */ + public LabelCell(InputStream is) throws IOException { + read(is); + } + + /** + * Writes a <code>LabelCell</code> to the specified <code>Outputstream</code> + * + * @param os the <code>OutputStream</code> to write to + */ + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + + super.write(output); + + output.write(cch); + output.write(rgch); + + Debug.log(Debug.TRACE,"Writing Label record"); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>LabelCell</code> + */ + public short getBiffType() { + return PocketExcelConstants.LABEL_CELL; + } + + /** + * Reads a<code>LabelCell</code> from the specified <code>InputStream</code> + * + * @param input the <code>InputStram</code> to read from + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = super.read(input); + + numOfBytesRead += input.read(cch); + + int strLen = EndianConverter.readShort(cch)*2; + rgch = new byte[strLen]; + input.read(rgch, 0, strLen); + + Debug.log(Debug.TRACE, " cch : " + EndianConverter.readShort(cch) + + " rgch : " + new String(rgch, "UTF-16LE")); + + return numOfBytesRead; + } + + + /** + * Gets the <code>String</code> representing the cells contents + * + * @return the <code>String</code> representing the cells contents + */ + public String getString() throws IOException { + return (new String(rgch,"UTF-16LE")); + } + + /** + * Sets the <code>String</code> representing the cells contents + * + * @return the <code>String</code> representing the cells contents + */ + private void setLabel(String cellContents) throws IOException { + rgch = cellContents.getBytes("UTF-16LE"); + cch = EndianConverter.writeShort((short)cellContents.length()); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/NumberFormat.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/NumberFormat.java new file mode 100644 index 000000000000..0735b401a6b8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/NumberFormat.java @@ -0,0 +1,98 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: NumberFormat.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents a BIFF Record describing a number format + */ +public class NumberFormat implements BIFFRecord { + + private byte cce; + private byte[] rgch; + + /** + * Constructs a NumberFormat Record from the <code>InputStream</code> + * + * @param is InputStream containing the record data + */ + public NumberFormat(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>NumberFormat</code> + */ + public short getBiffType() { + return PocketExcelConstants.NUMBER_FORMAT; + } + + /** + * Reads the NumberFormat from the <code>InputStream</code> Byte array + * containg strings are doubled in length becuse they use unicode + * + * @return the total number of bytes read + */ + public int read(InputStream input) throws IOException { + + cce = (byte) input.read(); + int numOfBytesRead = 1; + + rgch = new byte[cce*2]; + numOfBytesRead += input.read(rgch, 0, cce*2); + + Debug.log(Debug.TRACE, "\tcce : "+ cce + + " rgch : " + new String(rgch,"UTF-16LE")); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(cce); + output.write(rgch); + + Debug.log(Debug.TRACE,"Writing NumberFormat record"); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Pane.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Pane.java new file mode 100644 index 000000000000..4155a658ae40 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Pane.java @@ -0,0 +1,222 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Pane.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.awt.Point; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; + +/** + * Represents a BIFF Record that describes the number and position of unfrozen + * panes. + */ +public class Pane implements BIFFRecord { + + private byte[] x = new byte[2]; + private byte[] y = new byte[2]; + private byte[] rwTop = new byte[2]; + private byte[] colLeft = new byte[2]; + private byte pnnAcct; + + /** + * Default Constructor + */ + public Pane() { + pnnAcct = (byte) 0x02; // Default setting + } + + /** + * Constructs a Pane Record from the <code>InputStream</code> + * + * @param is InputStream containing a Pane record + */ + public Pane(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Pane</code> + */ + public short getBiffType() { + return PocketExcelConstants.PANE_INFO; + } + + /** + * Gets the split point for this pane, in the case of splits this will be + * in twips. + * + * @return the split point + */ + public Point getSplitPoint() { + + int xTwips = EndianConverter.readShort(x)/11; + int yTwips = EndianConverter.readShort(y)/15; + return (new Point(xTwips, yTwips)); + } + + /** + * Gets the freeze point for this pane, in the case of freezes this will + * be a zero-based index to either the column or row. + * + * @return the freeze point + */ + public Point getFreezePoint() { + + return (new Point(EndianConverter.readShort(x), + EndianConverter.readShort(y))); + } + + /** + * Sets the split point for this pane, coordinates are in column row units + * if the split type is freeze or twips if split type is split. + * + * @param splitType contains the X and Y split types (freeze or split) + * @param p the split point + */ + public void setSplitPoint(Point splitType, Point p) { + + if(splitType.getX()==SheetSettings.SPLIT + || splitType.getY()==SheetSettings.SPLIT) { + int yTwips = (int) p.getY(); + short yPxl = (short) (yTwips * 15); + y = EndianConverter.writeShort(yPxl); + int xTwips = (int) p.getX(); + short xPxl = (short) (xTwips * 11); + x = EndianConverter.writeShort(xPxl); + } else { + y = EndianConverter.writeShort((short) p.getY()); + x = EndianConverter.writeShort((short) p.getX()); + } + + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Pane</code> + */ + public void setPaneNumber(int paneNumber) { + pnnAcct = (byte) paneNumber; + } + + /** + * Get the pane number of the active pane + * 0 - bottom right, 1 - top right + * 2 - bottom left, 3 - top left + * + * @return the hex code for <code>Pane</code> + */ + public int getPaneNumber() { + return pnnAcct; + } + + /** + * Set the top row visible in the lower pane + * + * @param top 0-based inex of the top row + */ + public void setTop(int top) { + rwTop = EndianConverter.writeShort((short)top); + } + + /** + * Set leftmost column visible in the right pane + * + * @param left 0-based index of the leftmost column + */ + public void setLeft(int left) { + colLeft = EndianConverter.writeShort((short)left); + } + + /** + * Get the top row visible in the lower pane + * + * @return the hex code for <code>Pane</code> + */ + public int getTop() { + return EndianConverter.readShort(rwTop); + } + + /** + * Get leftmost column visible in the right pane + * + * @return 0-based index of the column + */ + public int getLeft() { + return EndianConverter.readShort(colLeft); + } + + + /** + * Reads a <code>Pane</code> record from the <code>InputStream</code> + * + * @param input <code>InputStream</code> to read from + * @return the total number of bytes read + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(x); + numOfBytesRead += input.read(y); + numOfBytesRead += input.read(rwTop); + numOfBytesRead += input.read(colLeft); + pnnAcct = (byte) input.read(); + numOfBytesRead++; + + Debug.log(Debug.TRACE, "\tx : "+ EndianConverter.readShort(x) + + " y : " + EndianConverter.readShort(y) + + " rwTop : " + EndianConverter.readShort(rwTop) + + " colLeft : " + EndianConverter.readShort(colLeft) + + " pnnAcct : " + pnnAcct); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(x); + output.write(y); + output.write(rwTop); + output.write(colLeft); + output.write(pnnAcct); + + Debug.log(Debug.TRACE,"Writing Pane record"); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Row.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Row.java new file mode 100644 index 000000000000..5ffb49da45d5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Row.java @@ -0,0 +1,142 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Row.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents s BIFF Record that describes the format of a column + */ +public class Row implements BIFFRecord { + + private byte[] rw = new byte[2]; + private byte[] miyRw = new byte[2]; + private byte[] grbit = new byte[2]; + private byte[] ixfe = new byte[2]; + private float scale = (float) 1; + + /** + * Constructs a pocket Excel Document from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param rw Zero based row number + * @param miyRw row height + */ + public Row(int rw, int miyRw, boolean userDefined) { + this.rw = EndianConverter.writeShort((short) rw); + miyRw *= scale; + this.miyRw = EndianConverter.writeShort((short) miyRw); + if(userDefined) { + grbit = EndianConverter.writeShort((short) 2); + } else { + grbit = EndianConverter.writeShort((short) 0); + } + ixfe = EndianConverter.writeShort((short) 0); + } + + /** + * Constructs a Row fro man <code>InputStream</code> + * + * @param is InputStream containing a Pane Record + */ + public Row(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Row</code> + */ + public short getBiffType() { + return PocketExcelConstants.ROW_DESCRIPTION; + } + + /** + * Get the height of this row + * + * @return the height of this row + */ + public short getRowHeight() { + return EndianConverter.readShort(miyRw); + } + + /** + * Get the rown number for this style + * + * @return the row this style applies to + */ + public short getRowNumber() { + return EndianConverter.readShort(rw); + } + + /** + * Reads a Row from an <code>InputStream</code> + * + * @param is InputStream containing a Pane Record + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(rw); + numOfBytesRead += input.read(miyRw); + short scaledHeight = (short) (EndianConverter.readShort(miyRw) / scale); + miyRw = EndianConverter.writeShort(scaledHeight); + numOfBytesRead += input.read(grbit); + numOfBytesRead += input.read(ixfe); + + Debug.log(Debug.TRACE,"\trw : "+ EndianConverter.readShort(rw) + + " miyRw : " + EndianConverter.readShort(miyRw) + + " grbit : " + EndianConverter.readShort(grbit) + + " ixfe : " + EndianConverter.readShort(ixfe)); + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(rw); + output.write(miyRw); + output.write(grbit); + output.write(ixfe); + + Debug.log(Debug.TRACE,"Writing Row record"); + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Selection.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Selection.java new file mode 100644 index 000000000000..bafafc9c371f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Selection.java @@ -0,0 +1,146 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Selection.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.awt.Point; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents a BIFF Record that describes the selected area of a worksheet + */ +public class Selection implements BIFFRecord { + + private byte[] rwTop = new byte[2]; + private byte colLeft; + private byte[] rwBottom = new byte[2]; + private byte colRight; + private byte[] rwActive = new byte[2]; + private byte colActive; + + /** + * Default Constructor + */ + public Selection() { + this.rwTop = EndianConverter.writeShort((short) 0); + this.colLeft = 0; + this.rwBottom = EndianConverter.writeShort((short) 0); + this.colRight = 0; + this.rwActive = EndianConverter.writeShort((short) 0); + this.colActive = 0; + + } + + /** + * Constructs a Selection Record from the <code>InputStream</code> + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public Selection(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Selection</code> + */ + public short getBiffType() { + return PocketExcelConstants.CURRENT_SELECTION; + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Selection</code> + */ + public Point getActiveCell() { + Point p = new Point(colActive, EndianConverter.readShort(rwActive)); + return p; + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Selection</code> + */ + public void setActiveCell(Point p) { + + colActive = (byte) p.getX(); + rwActive = EndianConverter.writeShort((short) p.getY()); + } + + /** + * Reads a Selection Record from the <code>InputStream</code> + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(rwTop); + colLeft += (byte) input.read(); + numOfBytesRead += input.read(rwBottom); + colRight += (byte) input.read(); + numOfBytesRead += input.read(rwActive); + colActive += (byte) input.read(); + numOfBytesRead += 3; + + Debug.log(Debug.TRACE,"\trwTop : "+ EndianConverter.readShort(rwTop) + + " colLeft : " + colLeft + + " rwBottom : " + EndianConverter.readShort(rwBottom) + + " colRight : "+ colRight + + " rwActive : " + EndianConverter.readShort(rwActive) + + " colActive : " + colActive); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(rwTop); + output.write(colLeft); + output.write(rwBottom); + output.write(colRight); + output.write(rwActive); + output.write(colActive); + + Debug.log(Debug.TRACE,"Writing Selection record"); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/StringValue.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/StringValue.java new file mode 100644 index 000000000000..772affb2e817 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/StringValue.java @@ -0,0 +1,128 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: StringValue.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents a BIFF Record that describes the value of a formula that + * evaluates to a string + */ +public class StringValue implements BIFFRecord { + + private byte[] cch = new byte[2]; + private byte[] rgch; + + /** + * Constructs a StringValue Record from an <code>InputStream</code> + * + * @param is InputStream containing a StringValue Record + */ + public StringValue(String str) throws IOException { + cch = EndianConverter.writeShort((short) str.length()); + rgch = new byte[str.length()]; + rgch = str.getBytes("UTF-16LE"); + } + + /** + * Constructs a StringValue Record from an <code>InputStream</code> + * + * @param is InputStream containing a StringValue Record + */ + public StringValue(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>StringValue</code> + */ + public short getBiffType() { + return PocketExcelConstants.FORMULA_STRING; + } + + /** + * Reads a StringVlaue Record from an <code>InputStream</code> + * + * @param is InputStream containing a StringValue Record + */ + public int read(InputStream input) throws IOException { + + cch[0] = (byte) input.read(); + cch[1] = (byte) input.read(); + int numOfBytesRead = 1; + + int strlen = EndianConverter.readShort(cch)*2; + rgch = new byte[strlen]; + numOfBytesRead += input.read(rgch, 0, strlen); + + Debug.log(Debug.TRACE,"\tcch : "+ cch + + " rgch : " + rgch); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(cch); + output.write(rgch); + + Debug.log(Debug.TRACE,"Writing StringValue record"); + } + + /** + * Gets the <code>String</code> representing the cells contents + * + * @return the <code>String</code> representing the cells contents + */ + public String getString() throws IOException { + String name; + + try { + name = new String(rgch, "UTF-16LE"); + } catch (UnsupportedEncodingException e){ + name = "unknown"; + } + return name; + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/UnsupportedFormulaException.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/UnsupportedFormulaException.java new file mode 100644 index 000000000000..2446e86089ed --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/UnsupportedFormulaException.java @@ -0,0 +1,46 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: UnsupportedFormulaException.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.lang.Exception; + +import org.openoffice.xmerge.util.Debug; + +/** + * At the moment any functions within a formula will result in this exception + * being thrown. + */ +public class UnsupportedFormulaException extends Exception { + + public UnsupportedFormulaException(String message){ + super(message); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Window1.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Window1.java new file mode 100644 index 000000000000..24b8aa92f580 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Window1.java @@ -0,0 +1,119 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Window1.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * Represents a BIFF REcord that describes workbook window attributes + */ +public class Window1 implements BIFFRecord { + + private byte[] grbit = new byte[2]; + private byte[] itabCur = new byte[2]; // index of selected worksheet + + /** + * Constructor + */ + public Window1() { + grbit = EndianConverter.writeShort((short) 0); + itabCur = EndianConverter.writeShort((short) 0); + } + + /** + * Constructs a Window1 Record from an <code>InputStream</code> + * + * @param is InputStream containing a Window1 Record + */ + public Window1(InputStream is) throws IOException{ + read(is); + } + + /** + * Set the number of the active sheet + * + * @param activeSheet number of the active sheet + */ + public void setActiveSheet(int activeSheet) { + itabCur = EndianConverter.writeShort((short) activeSheet); + } + + /** + * Get the number of the active sheet + * + * @return number of the active sheet + */ + public int getActiveSheet() { + return EndianConverter.readShort(itabCur); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Window1</code> + */ + public short getBiffType() { + return PocketExcelConstants.WINDOW_INFO; + } + + /** + * Reads a Window1 Record from an <code>InputStream</code> + * + * @param is InputStream containing a Window1 Record + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(grbit); + numOfBytesRead += input.read(itabCur); + + Debug.log(Debug.TRACE,"\tgrbit : "+ EndianConverter.readShort(grbit) + + " itabCur : " + EndianConverter.readShort(itabCur)); + + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(grbit); + output.write(itabCur); + + Debug.log(Debug.TRACE,"Writing Window1 record"); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Window2.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Window2.java new file mode 100644 index 000000000000..e587de7ea3b4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Window2.java @@ -0,0 +1,158 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Window2.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.awt.Point; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; + + +/** + * Represents a BIFF Record that describes worksheet window attributes + */ +public class Window2 implements BIFFRecord { + + private final static int FROZEN = 0x08; + private final static int NOSPLIT = 0x01; + + private byte[] rwTop = new byte[2]; + private byte colLeft; + private byte[] grbit = new byte[2]; + + /** + * Constructor + */ + public Window2() { + this.rwTop = EndianConverter.writeShort((short) 0); + this.colLeft = 0; + this.grbit = EndianConverter.writeShort((short) 0); + } + + /** + * Constructs a Window2 Record from an <code>InputStream</code> + * + * @param is InputStream containing a Window2 Record + */ + public Window2(InputStream is) throws IOException { + read(is); + } + + /** + * Get the hex code for this particular <code>BIFFRecord</code> + * + * @return the hex code for <code>Window2</code> + */ + public short getBiffType() { + return PocketExcelConstants.SHEET_WINDOW_INFO; + } + + /** + * Sets the split type for this pane, the split type is the same for both + * x and y so we only test against one. + * + * @param splitType the split type based on types defined in + * <code>sheetSettings</code> + */ + public void setSplitType(Point splitType) { + if(splitType.getX()==SheetSettings.SPLIT) { + grbit[0] &= ~FROZEN; + grbit[1] &= ~NOSPLIT; + } else { + grbit[0] |= FROZEN; + grbit[1] |= NOSPLIT; + } + } + + /** + * This method tests if this object describes a freeze + * + * @return true if freeze otherwise false + */ + public boolean isFrozen() { + if((grbit[0] & FROZEN) != FROZEN) + return false; + + if((grbit[1] & NOSPLIT) != NOSPLIT) + return false; + + return true; + } + + /** + * This method tests if this object describes a split + * + * @return true if split otherwise false + */ + public boolean isSplit() { + if((grbit[0] & FROZEN) == FROZEN) + return false; + + if((grbit[1] & NOSPLIT) == NOSPLIT) + return false; + + return true; + } + + /** + * Reads a Window2 Record from an <code>InputStream</code> + * + * @param is InputStream containing a Window2 Record + */ + public int read(InputStream input) throws IOException { + + int numOfBytesRead = input.read(rwTop); + colLeft = (byte) input.read(); + numOfBytesRead++; + numOfBytesRead += input.read(grbit); + + Debug.log(Debug.TRACE,"\trwTop : "+ EndianConverter.readShort(rwTop) + + " colLeft : " + colLeft + + " grbit : " + EndianConverter.readShort(grbit)); + return numOfBytesRead; + } + + public void write(OutputStream output) throws IOException { + + output.write(getBiffType()); + output.write(rwTop); + output.write(colLeft); + output.write(grbit); + + Debug.log(Debug.TRACE,"Writing Window2 record"); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Workbook.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Workbook.java new file mode 100644 index 000000000000..d29efd8d9938 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Workbook.java @@ -0,0 +1,543 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Workbook.java,v $ + * $Revision: 1.17 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.NameDefinition; +import org.openoffice.xmerge.converter.xml.sxc.BookSettings; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.IntArrayList; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; +import org.openoffice.xmerge.converter.xml.sxc.ColumnRowInfo; + +/** + * This class is used by <code> PxlDocument</code> to maintain pexcel + * workbooks. + * + * @author Martin Maher + */ +public class Workbook implements org.openoffice.xmerge.Document, +OfficeConstants { + + private Vector fonts = new Vector(); + private Vector extendedFormats = new Vector(); + private Vector worksheets = new Vector(); + private Vector boundsheets = new Vector(); + private Vector definedNames = new Vector(); + private static final CodePage cp; + private static final Window1 win1; + private static final BeginningOfFile bof;; + private static final Eof eof; + private String fileName; + + static { + cp = new CodePage(); + win1 = new Window1(); + bof = new BeginningOfFile(true); + eof = new Eof(); + } + + + /** + * Constructs a pocket Excel Workbook with the name of the file passed in + * as an argument. Also fills out a basic header block containing the + * minimum number of objects that can be created at this time. + * + * @param name Name of the Pocket Excel Data file. (excluding the file + * extension) + */ + public Workbook(String name) throws IOException { + fileName = name + PocketExcelConstants.FILE_EXTENSION; + Format defaultFormat = new Format(); + FontDescription fd = new FontDescription(defaultFormat); + fonts.add(fd); + ExtendedFormat xf = new ExtendedFormat(0, defaultFormat); + extendedFormats.add(xf); + } + + /** + * Constructs a pocket Excel Workbook from the + * <code>InputStream</code> and assigns it the document name passed in + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public Workbook(String name, InputStream is) throws IOException { + read(is); + fileName = name; + } + + /** + * Writes the current workbook to the <code>Outputstream</code> + * + * @param os The destination outputstream + */ + public void write(OutputStream os) throws IOException { + bof.write(os); + cp.write(os); + for(Enumeration e = definedNames.elements();e.hasMoreElements();) { + DefinedName dn = (DefinedName) e.nextElement(); + dn.write(os); + } + win1.write(os); + for(Enumeration e = fonts.elements();e.hasMoreElements();) { + FontDescription fd = (FontDescription) e.nextElement(); + fd.write(os); + } + for(Enumeration e = extendedFormats.elements();e.hasMoreElements();) { + ExtendedFormat xf = (ExtendedFormat) e.nextElement(); + xf.write(os); + } + for(Enumeration e = boundsheets.elements();e.hasMoreElements();) { + BoundSheet bs = (BoundSheet) e.nextElement(); + bs.write(os); + } + eof.write(os); + + for(Enumeration e = worksheets.elements();e.hasMoreElements();) { + Worksheet ws = (Worksheet) e.nextElement(); + ws.write(os); + } + } + + /** + * Reads a workbook from the <code>InputStream</code> and contructs a + * workbook object from it + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public void read(InputStream is) throws IOException { + + boolean done = false; + + int b = 0; + while (!done) + { + b = is.read(); + if (b == -1) + { + Debug.log(Debug.TRACE,"End of file reached"); + break; + } + + switch (b) + { + case PocketExcelConstants.DEFINED_NAME: + Debug.log(Debug.TRACE,"NAME: Defined Name (18h)"); + DefinedName dn = new DefinedName(is, this); + definedNames.add(dn); + break; + + case PocketExcelConstants.BOF_RECORD: + Debug.log(Debug.TRACE,"BOF Record"); + bof.read(is); + break; + + case PocketExcelConstants.EOF_MARKER: + Debug.log(Debug.TRACE,"EOF Marker"); + eof.read(is); + Worksheet ws = new Worksheet(this); + while(ws.read(is)) { + worksheets.add(ws); + ws = new Worksheet(this); + } + break; + + case PocketExcelConstants.FONT_DESCRIPTION: + Debug.log(Debug.TRACE,"FONT: Font Description (31h)"); + FontDescription fd = new FontDescription(is); + fonts.add(fd); + break; + + case PocketExcelConstants.WINDOW_INFO: + Debug.log(Debug.TRACE,"WINDOW1: Window Information (3Dh) [PXL 2.0]"); + win1.read(is); + break; + + case PocketExcelConstants.CODEPAGE: + Debug.log(Debug.TRACE,"CODEPAGE : Codepage and unknown fields (42h)"); + cp.read(is); + break; + + case PocketExcelConstants.BOUND_SHEET: + Debug.log(Debug.TRACE,"BOUNDSHEET: Sheet Information (85h)"); + BoundSheet bs = new BoundSheet(is); + boundsheets.add(bs); + break; + + case PocketExcelConstants.EXTENDED_FORMAT: + Debug.log(Debug.TRACE,"XF: Extended Format (E0h) [PXL 2.0]"); + ExtendedFormat xf = new ExtendedFormat(is); + extendedFormats.add(xf); + break; + + default: + b = is.read(); + break; + } + + } + is.close(); + } + + /** + * Adds a font recrod to the workbook + * + * @param f the font record to add + */ + public int addFont(FontDescription f) { + + boolean alreadyExists = false; + int i = 0; + + for(Enumeration e = fonts.elements();e.hasMoreElements();) { + FontDescription fd = (FontDescription) e.nextElement(); + if(fd.compareTo(f)) { + alreadyExists = true; + break; + } else { + i++; + } + } + + if(!alreadyExists) + fonts.add(f); + + return i; + } + + /** + * Adds a ExtendedFormat record to the workbook + * + * @param f the font recrod to add + */ + public int addExtendedFormat(Format fmt) throws IOException { + + FontDescription fd = new FontDescription(fmt); + int ixfnt = addFont(fd); + ExtendedFormat xf = new ExtendedFormat(ixfnt, fmt); + + boolean alreadyExists = false; + int i = 0; + + for(Enumeration e = extendedFormats.elements();e.hasMoreElements();) { + ExtendedFormat currentXF = (ExtendedFormat) e.nextElement(); + if(xf.compareTo(currentXF)) { + alreadyExists = true; + break; + } else if(!alreadyExists) { + i++; + } + } + + if(!alreadyExists) + extendedFormats.add(xf); + + return i; + } + + /** + * Gets a worksheet at a particular index from mthe current workbook. + * + * @param index the index of the worksheet to retrieve + */ + public Worksheet getWorksheet(int index) { + + return ((Worksheet) worksheets.elementAt(index)); + } + + /** + * Returns a FontDescription indictated by the + * index parameter passed in to the method + * + * @param ixfnt index to the FontDescriptions, this is a 0 based index + * @return FontDescription indexed by ixfe + */ + public FontDescription getFontDescription(int ixfnt) { + + return (FontDescription) fonts.elementAt(ixfnt); + } + + /** + * Returns a ExtendedFormat indictated by the + * index parameter passed in to the method + * + * @param ixfe index to the FontDescriptions, this is a 0 based index + * @return FontDescription indexed by ixfe + */ + public ExtendedFormat getExtendedFormat(int ixfe) { + + return (ExtendedFormat) extendedFormats.elementAt(ixfe); + } + + /** + * Returns an enumeration of DefinedNames for this workbook + * + * @return Enumeration for the DefinedNames + */ + public Enumeration getDefinedNames() { + + return definedNames.elements(); + } + + /** + * Returns an enumeration of <code>Settings</code> for this workbook + * + * @return Enumeration of <code>Settings</code> + */ + public BookSettings getSettings() { + + Vector settingsVector = new Vector(); + int index = 0; + for(Enumeration e = worksheets.elements();e.hasMoreElements();) { + Worksheet ws = (Worksheet) e.nextElement(); + SheetSettings s = ws.getSettings(); + s.setSheetName(getSheetName(index++)); + settingsVector.add(s); + } + BookSettings bs = new BookSettings(settingsVector); + String activeSheetName = getSheetName(win1.getActiveSheet()); + bs.setActiveSheet(activeSheetName); + return bs; + } + + /** + * Returns a <code>Vector</code> containing all the worksheet Names + * + * @return a <code>Vector</code> containing all the worksheet Names + */ + public Vector getWorksheetNames() { + + Vector wsNames = new Vector(); + + for(int i = 0;i < boundsheets.size();i++) { + wsNames.add(getSheetName(i)); + } + + return wsNames; + } + + /** + * Returns the name of the worksheet at the specified index + * + * @return a <code>String</code> containing the name of the worksheet + */ + public String getSheetName(int index) { + BoundSheet bs = (BoundSheet) boundsheets.elementAt(index); + + return bs.getSheetName(); + } + + /** + * Adds a <code>Worksheet</code> to the workbook. + * + * @return name the name of the <code>Worksheet</code> to be added + */ + public void addWorksheet(String name) throws IOException { + + BoundSheet bs = new BoundSheet(name); + boundsheets.add(bs); + + Worksheet ws = new Worksheet(); + worksheets.add(ws); + } + + /** + * Adds a cell to the current worksheet. + * + * @return the name of the <code>Worksheet</code> to be added + */ + public void addCell(int row,int col, Format fmt, String cellContents) + throws IOException { + + Worksheet currentWS = (Worksheet) worksheets.elementAt(worksheets.size()-1); + int ixfe = addExtendedFormat(fmt); + + String category = fmt.getCategory(); + + // Now the formatting is out of the way add the cell + Debug.log(Debug.TRACE,"Cell Format: " + fmt); + Debug.log(Debug.TRACE,"Row : " + row); + Debug.log(Debug.TRACE,"Col : " + col); + if(cellContents.startsWith("=")) { + try { + Formula f = new Formula(row, col, cellContents, ixfe, fmt, this); + currentWS.addCell(f); + if(category.equalsIgnoreCase(CELLTYPE_STRING)) { + StringValue sv = new StringValue(fmt.getValue()); + currentWS.addCell(sv); + } + } catch(Exception e) { + Debug.log(Debug.TRACE, "Parsing Exception thrown : " + e.getMessage()); + BoolErrCell errorCell = new BoolErrCell(row, col, ixfe, 0x2A, 1); + currentWS.addCell(errorCell); + } + } else if(category.equalsIgnoreCase(OfficeConstants.CELLTYPE_FLOAT)) { + try { + FloatNumber num = new FloatNumber(row, col, cellContents, ixfe); + currentWS.addCell(num); + } catch(Exception e) { + Debug.log(Debug.TRACE,"Error could not parse Float " + cellContents); + LabelCell lc = new LabelCell(row, col, cellContents, ixfe); + currentWS.addCell(lc); + } + } else { + if(cellContents.length()==0) { + Debug.log(Debug.TRACE, "Blank Cell"); + BlankCell b = new BlankCell(row, col, ixfe); + currentWS.addCell(b); + } else { + Debug.log(Debug.TRACE, "Label Cell : " + cellContents); + LabelCell lc = new LabelCell(row, col, cellContents, ixfe); + currentWS.addCell(lc); // three because we assume the last three + // Records in any worksheet is the selection, + // window2 and eof Records + } + } + } + + /** + * Will create a number of ColInfo records based on the column widths + * based in. + * + * @param columnRows <code>Vector</code> of <code>ColumnRowInfo</code> + */ + public void addColInfo(Vector columnRows) throws IOException { + + Worksheet currentWS = (Worksheet) worksheets.elementAt(worksheets.size()-1); + + int nCols = 0; + int nRows = 0; + + Debug.log(Debug.TRACE,"Workbook: addColInfo()"); + for(Enumeration e = columnRows.elements();e.hasMoreElements();) { + ColumnRowInfo cri =(ColumnRowInfo) e.nextElement(); + int ixfe = 0; + int size = cri.getSize(); + int repeated = cri.getRepeated(); + if(cri.isColumn()) { + Debug.log(Debug.TRACE,"Workbook: adding ColInfo width = " + size); + ColInfo newColInfo = new ColInfo( nCols, + nCols+repeated-1, + size, ixfe); + currentWS.addCol(newColInfo); + nCols += repeated; + } else if(cri.isRow()) { + + Debug.log(Debug.TRACE,"Workbook: adding Row Height = " + size); + if(!cri.isDefaultSize()) { + for(int i=0;i<repeated;i++) { + Row newRow = new Row(nRows++, size, cri.isUserDefined()); + currentWS.addRow(newRow); + } + } else { + // If it is the Default Row we don't need to add it + nRows += repeated; + } + + } + } + } + + /** + * Will create a number of ColInfo recrods based on the column widths + * based in. + * + * @param an integer list representing the column widths + */ + public void addNameDefinition(NameDefinition nameDefinition) throws IOException { + + DefinedName dn = new DefinedName(nameDefinition, this); + definedNames.add(dn); + } + + /** + * Adds the <code>BookSettings</code> for this workbook. + * + * @param book the <code>BookSettings</code> to add + */ + public void addSettings(BookSettings book) throws IOException { + + int index = 0; + Vector sheetSettings = book.getSheetSettings(); + String activeSheetName = book.getActiveSheet(); + + for(Enumeration e = worksheets.elements();e.hasMoreElements();) { + Worksheet ws = (Worksheet) e.nextElement(); + String name = getSheetName(index++); + if(activeSheetName.equals(name)) { + win1.setActiveSheet(index-1); + } + for(Enumeration eSettings = sheetSettings.elements();eSettings.hasMoreElements();) { + SheetSettings s = (SheetSettings) eSettings.nextElement(); + if(name.equals(s.getSheetName())) { + ws.addSettings(s); + } + } + } + } + + /** + * Return the filename of the pxl document without the file extension + * + * @return filename without the file extension + */ + public String getName() { + + // We have to strip off the file extension + int end = fileName.lastIndexOf("."); + String name; + if( end >= 0) // check in case the filename is already stripped + name = fileName.substring(0, end); + else + name = fileName; + + return name; + } + + /** + * Returns the filename of the pxl document with the file extension + * + * @return filename with the file extension + */ + public String getFileName() { + + return fileName; + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Worksheet.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Worksheet.java new file mode 100644 index 000000000000..d0e4f829722a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/Worksheet.java @@ -0,0 +1,323 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Worksheet.java,v $ + * $Revision: 1.10 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.util.Vector; +import java.util.Enumeration; +import java.awt.Point; + +import org.openoffice.xmerge.util.IntArrayList; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.converter.xml.sxc.SheetSettings; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; + + +/** + * This class is used by <code>PxlDocument</code> to maintain pexcel + * worksheets. + * + * @author Martin Maher + */ +public class Worksheet { + + private String name; + private Workbook wb; + private Vector rows = new Vector(); + private Vector colInfo = new Vector(); + private Vector cells = new Vector(); + private DefColWidth dcw = new DefColWidth(); + private DefRowHeight drh = new DefRowHeight(); + private Window2 win2 = new Window2(); + private Selection sel = new Selection(); + private Pane p = new Pane(); + private BeginningOfFile bof; + private Eof eof; + + /** + * Writes the current workbook to the <code>Outputstream</code> + * + * @param os The destination outputstream + */ + public Worksheet(Workbook wb) { + this.wb = wb; + } + + /** + * Default Contructor + * + * @param os The destination outputstream + */ + public Worksheet() { + } + + /** + * Writes the current workbook to the <code>Outputstream</code> + * + * @param os The destination outputstream + */ + public void write(OutputStream os) throws IOException { + + bof = new BeginningOfFile(false); + bof.write(os); + dcw.write(os); + for(Enumeration e = colInfo.elements();e.hasMoreElements();) { + ColInfo ci = (ColInfo) e.nextElement(); + ci.write(os); + } + drh.write(os); + for(Enumeration e = rows.elements();e.hasMoreElements();) { + Row rw = (Row) e.nextElement(); + rw.write(os); + } + for(Enumeration e = cells.elements();e.hasMoreElements();) { + BIFFRecord cv = (BIFFRecord) e.nextElement(); + cv.write(os); + } + win2.write(os); + p.write(os); + sel.write(os); + eof = new Eof(); + eof.write(os); + } + + /** + * Reads a worksheet from the <code>InputStream</code> and contructs a + * workbook object from it + * + * @param is InputStream containing a Pocket Excel Data file. + */ + public boolean read(InputStream is) throws IOException { + + int b = is.read(); + + if (b==-1) + return false; + + while(b!=-1) { + switch (b) + { + case PocketExcelConstants.BLANK_CELL: + Debug.log(Debug.TRACE,"Blank Cell (01h)"); + BlankCell bc = new BlankCell(is); + cells.add(bc); + break; + + case PocketExcelConstants.NUMBER_CELL: + Debug.log(Debug.TRACE,"NUMBER: Cell Value, Floating-Point Number (03h)"); + FloatNumber fn = new FloatNumber(is); + cells.add(fn); + break; + + case PocketExcelConstants.LABEL_CELL: + Debug.log(Debug.TRACE,"LABEL: Cell Value, String Constant (04h)"); + LabelCell lc = new LabelCell(is); + cells.add(lc); + break; + + case PocketExcelConstants.BOOLERR_CELL: + Debug.log(Debug.TRACE,"BOOLERR: Cell Value, Boolean or Error (05h)"); + BoolErrCell bec = new BoolErrCell(is); + break; + + case PocketExcelConstants.FORMULA_CELL: + Debug.log(Debug.TRACE,"FORMULA: Cell Formula (06h)"); + Formula f = new Formula(is, wb); + cells.add(f); + break; + + case PocketExcelConstants.FORMULA_STRING: + Debug.log(Debug.TRACE,"String Value of a Formula (07h)"); + StringValue sv = new StringValue(is); + break; + + case PocketExcelConstants.ROW_DESCRIPTION: + Debug.log(Debug.TRACE,"ROW: Describes a Row (08h)"); + Row rw = new Row(is); + rows.add(rw); + break; + + case PocketExcelConstants.BOF_RECORD: + Debug.log(Debug.TRACE,"BOF Record"); + bof = new BeginningOfFile(is); + break; + + case PocketExcelConstants.EOF_MARKER: + Debug.log(Debug.TRACE,"EOF Marker"); + eof = new Eof(); + return true; + + case PocketExcelConstants.CURRENT_SELECTION: + Debug.log(Debug.TRACE,"SELECTION: Current Selection (1Dh)"); + sel = new Selection(is); + break; + + case PocketExcelConstants.NUMBER_FORMAT: + Debug.log(Debug.TRACE,"FORMAT: Number Format (1Eh)"); + NumberFormat nf = new NumberFormat(is); + break; + + case PocketExcelConstants.DEFAULT_ROW_HEIGHT: + Debug.log(Debug.TRACE,"DEFAULTROWHEIGHT: Default Row Height (25h)"); + drh = new DefRowHeight(is); + break; + + case PocketExcelConstants.SHEET_WINDOW_INFO: + Debug.log(Debug.TRACE,"WINDOW2: Sheet Window Information (3Eh) [PXL 2.0]"); + win2 = new Window2(is); + break; + + case PocketExcelConstants.PANE_INFO: + Debug.log(Debug.TRACE,"PANE: Number of Panes and their Position (41h) [PXL 2.0]"); + p = new Pane(is); + break; + + case PocketExcelConstants.DEF_COL_WIDTH: + Debug.log(Debug.TRACE,"DEFCOLWIDTH: Default Column Width (55h) [PXL 2.0]"); + dcw = new DefColWidth(is); + break; + + case PocketExcelConstants.COLINFO: + Debug.log(Debug.TRACE,"COLINFO: Column Formatting Information (7Dh) [PXL 2.0]"); + ColInfo ci = new ColInfo(is); + colInfo.add(ci); + break; + + default: + break; + } + b = is.read(); + + } + Debug.log(Debug.TRACE,"Leaving Worksheet:"); + + return true; + } + + /** + * Returns an enumerator which will be used to access individual cells + * + * @return an enumerator to the worksheet cells + */ + public Enumeration getCellEnumerator() throws IOException { + return (cells.elements()); + } + + /** + * Adds a cell to this worksheet. Current valdid celltypes are + * <code>FloatNumber</code>, <code>LabelCell</code> or <code>Formula</code> + * + * @param f the font recrod to add + */ + public void addCell(BIFFRecord br) { + cells.add(br); + } + + /** + * Adds a number of ColInfo Records to the worksheet base on a list of + * clumnwidths passed in + * + * @param list of column widths + */ + public void addRow(Row r) { + rows.add(r); + } + + /** + * Adds a number of ColInfo Records to the worksheet base on a list of + * clumnwidths passed in + * + * @param list of column widths + */ + public void addCol(ColInfo c) { + colInfo.add(c); + } + /** + * Returns an <code>Enumeration</code> to the ColInfo's for this worksheet + * + * @return an <code>Enumeration</code> to the ColInfo's + */ + public void addSettings(SheetSettings s) { + + sel.setActiveCell(s.getCursor()); + p.setLeft(s.getLeft()); + p.setTop(s.getTop()); + p.setPaneNumber(s.getPaneNumber()); + Point split = s.getSplit(); + if(split.getX()!=0 || split.getY()!=0) { + p.setSplitPoint(s.getSplitType(), split); + win2.setSplitType(s.getSplitType()); + } + } + + /** + * Returns an <code>Enumeration</code> to the ColInfo's for this worksheet + * + * @return an <code>Enumeration</code> to the ColInfo's + */ + public Enumeration getColInfos() { + + return (colInfo.elements()); + } + + /** + * Returns a <code>SheetSettings</code> object containing a collection of data + * contained in <code>Pane</code>, <code>Window2</code> and + * <code>Selection</code> + * + * @return an <code>SheetSettings</code> + */ + public SheetSettings getSettings() { + + SheetSettings s = new SheetSettings(); + s.setCursor(sel.getActiveCell()); + if(win2.isFrozen()) { + s.setFreeze(p.getFreezePoint()); + } else if(win2.isSplit()) { + s.setSplit(p.getSplitPoint()); + } + s.setPaneNumber(p.getPaneNumber()); + s.setTopLeft(p.getTop(), p.getLeft()); + return s; + } + /** + * Returns an <code>Enumeration</code> to the Rows for this worksheet + * + * @return an <code>Enumeration</code> to the Rows + */ + public Enumeration getRows() { + + return (rows.elements()); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/build.xml new file mode 100644 index 000000000000..a30c348c84f3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/build.xml @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.6 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxsp_records" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxsp_records"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxc/pexcel/records"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/BIFFRecord.java"/> + <include name="${package}/CellValue.java"/> + <include name="${package}/Workbook.java"/> + <include name="${package}/Worksheet.java"/> + <include name="${package}/BeginningOfFile.java"/> + <include name="${package}/BlankCell.java"/> + <include name="${package}/BoolErrCell.java"/> + <include name="${package}/BoundSheet.java"/> + <include name="${package}/CodePage.java"/> + <include name="${package}/ColInfo.java"/> + <include name="${package}/DefColWidth.java"/> + <include name="${package}/DefRowHeight.java"/> + <include name="${package}/DefinedName.java"/> + <include name="${package}/Eof.java"/> + <include name="${package}/ExtendedFormat.java"/> + <include name="${package}/FloatNumber.java"/> + <include name="${package}/FontDescription.java"/> + <include name="${package}/UnsupportedFormulaException.java"/> + <include name="${package}/Formula.java"/> + <include name="${package}/LabelCell.java"/> + <include name="${package}/NumberFormat.java"/> + <include name="${package}/Pane.java"/> + <include name="${package}/Row.java"/> + <include name="${package}/Selection.java"/> + <include name="${package}/StringValue.java"/> + <include name="${package}/Window1.java"/> + <include name="${package}/Window2.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaCompiler.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaCompiler.java new file mode 100644 index 000000000000..49474e5de25f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaCompiler.java @@ -0,0 +1,275 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FormulaCompiler.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.util.*; +import org.openoffice.xmerge.util.Debug; + +/** + * FormulaCompiler converts Calc formula string into PocketXL bytes + * and PocketXL formula bytes into Calc Formula strings + * + * For converting from infix to Reverse Polish (or Postfix) notation the string is + * converted into a vector of Tokens and then re-ordered based on a modified version + * of the standard Infix to RPN conversion algorithms. + * <pre> + * Infix2Rpn(tokens) + * while have more tokens + * if token is operand + * push to stack + * else if token is function, argument separater, or open bracket + * push token + * extract tokens to matching close bracket into param + * Infix2Rpn(param) + * else if token is close bracket + * pop from stack into result until close bracket or function + * else + * while stack.top.priority >= token.priority + * add stack.pop to result + * push token onto stack + * </pre> + * For converting from RPN to Infix the following algorithm is applied: + * <pre> + * while have more tokens + * if token is operand + * push token to stack + * else if token is function or operator + * pop from stack number of args required by token + * apply token to params to make expr + * push expr to stack + * return stack.pop + * </pre> + */ +public class FormulaCompiler { + /** + * Constructs a FormulaCompiler object + */ + public FormulaCompiler() { + } + + private boolean isPercent(Token pt) { + return pt.getTokenID() == TokenConstants.TPERCENT; + } + + private boolean isOpenBrace(Token pt) { + return pt.getTokenID() == TokenConstants.TPAREN; + } + + private boolean isCloseBrace(Token pt) { + return pt.getValue().compareTo(")") == 0; + } + + private boolean isParamDelimiter(Token pt) { + return pt.getTokenID() == TokenConstants.TARGSEP; + } + + private boolean isBinaryOperator(Token pt) { + return false; + } + + /** + * Re-order into Infix format + * @param tokens The tokens in RPN form + * @return The vector of tokens re-ordered in Infix notation + */ + public Vector RPN2Infix(Vector tokens) { + Vector infixExpr = new Vector(15); + ListIterator iter = tokens.listIterator(); + Stack evalStack = new Stack(); + Stack args = new Stack(); + + while (iter.hasNext()) { + Token pt = (Token)iter.next(); + if (pt.isOperand()) { + Vector expr = new Vector(5); + expr.add(pt); + evalStack.push(expr); + } else if (pt.isOperator() || pt.isFunction()) { + args.clear(); + for (int i=0; i< pt.getNumArgs(); i++) { + args.push(evalStack.pop()); + } + evalStack.push(makeExpression(pt, args)); + } + } + return (Vector)evalStack.elementAt(0); + } + + /** + * Convert the infix expression to RPN. Note that open brackets are saved onto the stack to preserve the users bracketing. + * <p>Also note that the open bracket following functions is not pushed onto the stack - it is always implied when + * writing out results + * + * @param tokens The vector of tokens in Infix form + * + * @return A vector of tokens for the expression in Reverse Polish Notation order + */ + public Vector infix2RPN(Vector tokens) { + Vector rpnExpr = new Vector(15); + Stack evalStack = new Stack(); + ListIterator iter = tokens.listIterator(); + while (iter.hasNext()) { + Token pt = (Token)iter.next(); + + if (pt.isOperand()) { //Operands are output immediately + rpnExpr.add(pt); + } else if (pt.isFunction() || isParamDelimiter(pt) || isOpenBrace(pt)) { //Extract parameters after afunction or comma + evalStack.push(pt); + if (pt.isFunction()) { + iter.next(); + } + Vector param = extractParameter(iter); + Debug.log(Debug.TRACE, "Extracted parameter " + param); + rpnExpr.addAll(infix2RPN(param)); + } else if (isCloseBrace(pt)) { //Pop off stack till you meet a function or an open bracket + Token tmpTok = null; + boolean bPop = true; + while (bPop) { + if (evalStack.isEmpty()) { + bPop = false; + } else { + tmpTok = (Token)evalStack.pop(); + //if (!(isOpenBrace(tmpTok) || isParamDelimiter(tmpTok))) { //Don't output brackets and commas + if (!isParamDelimiter(tmpTok)) { //Don't output commas + rpnExpr.add(tmpTok); + } + if (tmpTok.isFunction() || isOpenBrace(tmpTok)) { + bPop = false; + } + } + } + } else { + if (!evalStack.isEmpty()) { + while (!evalStack.isEmpty() && + (((Token)evalStack.peek()).getTokenPriority() >=pt.getTokenPriority())) { + Token topTok = (Token)evalStack.peek(); + if (topTok.isFunction() || isOpenBrace(topTok)) { + break; + } + rpnExpr.add(evalStack.pop()); + } + } + evalStack.push(pt); + } + } + + while (!evalStack.isEmpty()) { + Token topTok = (Token)evalStack.peek(); + if (!(isOpenBrace(topTok) || isParamDelimiter(topTok))) { //Don't output brackets and commas + rpnExpr.add(evalStack.pop()); + } + else + { + evalStack.pop(); + } + } + return rpnExpr; + } + + /** + * Extract a parameter or bracketed sub-expression + * @param iter an iterator into the list + * @return A complete sub-expression + */ + protected Vector extractParameter(ListIterator iter) { + Vector param = new Vector(5); + int subExprCount = 0; + + while (iter.hasNext()) { + Token pt = (Token)iter.next(); + Debug.log(Debug.TRACE, "Token is " + pt + " and subExprCount is " + subExprCount); + if (isOpenBrace(pt)) { + subExprCount++; + param.add(pt); + } else if (isCloseBrace(pt)) { + if (subExprCount == 0) { + iter.previous(); + return param; + } else { + subExprCount--; + param.add(pt); + } + } else if (isParamDelimiter(pt) && (subExprCount == 0)) { + iter.previous(); + return param; + } else { + param.add(pt); + } + } + return param; + } + + /** + * Given the operator and it's operators + * @param pt The operator token + * @param args The arguments for this operator + * @return A correctly ordered expression + */ + protected Vector makeExpression(Token pt, Stack args) { + Vector tmp = new Vector(5); + TokenFactory tf = new TokenFactory(); + if (pt.isOperator()) { + if (pt.getNumArgs()==2) { //Binary operator + tmp.addAll((Vector)args.pop()); + tmp.add(pt); + tmp.addAll((Vector)args.pop()); + } else if (pt.getNumArgs() == 1) { + if(isPercent(pt)) { + tmp.addAll((Vector)args.elementAt(0)); + tmp.add(pt); + } else { + tmp.add(pt); + tmp.addAll((Vector)args.elementAt(0)); + } + if (isOpenBrace(pt)) { + tmp.add(tf.getOperatorToken(")",1)); + } + } + } else if (pt.isFunction()) { + tmp.add(pt); + tmp.add(tf.getOperatorToken("(",1)); + if (!args.isEmpty()) { + Vector v = (Vector)args.pop(); + tmp.addAll(v); + } + while (!args.isEmpty()) { + tmp.add(tf.getOperatorToken(",",1)); + Vector v = (Vector)args.pop(); + tmp.addAll(v); + + } + tmp.add(tf.getOperatorToken(")",1)); + } + + return tmp; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaHelper.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaHelper.java new file mode 100644 index 000000000000..2e4e773a5f27 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaHelper.java @@ -0,0 +1,156 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FormulaHelper.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; + +/** + * This Helper class provides a simplified interface to conversion between PocketXL formula representation + * and Calc formula representation.<p> + * The class is used by {@link org.openoffice.xmerge.converter.xml.sxc.pexcel.Records.Formula} + */ +public class FormulaHelper { + + private static FormulaParser parser; + private static FormulaCompiler compiler; + private static TokenEncoder encoder; + private static TokenDecoder decoder; + private boolean rangeType = false; + private boolean expressionType = false; + + static { + parser = new FormulaParser(); + compiler = new FormulaCompiler(); + encoder = new TokenEncoder(); + decoder = new TokenDecoder(); + } + + /** + * Sets the workbook cache so that global data such as + * <code>DefinedNames</code>, <code>Boundsheets</code> can be read + * + * @param wb Wrokbook object containing all the global data + */ + public void setWorkbook(Workbook wb) { + + encoder.setWorkbook(wb); + decoder.setWorkbook(wb); + parser.setWorkbook(wb); + } + + /** + * Convertes a string representation of a calc formula into an array of PocketXL bytes + * @param formula The Formula String (e.g. 1+SUM(A1,B1)) + * + * @throws UnsupportedFunctionException Thrown if a function in the formula is nto supported by Pocket Excel + * @throws FormulaParsingException Thrown when the formula is not well formed + * + */ + public byte[] convertCalcToPXL(String formula) throws UnsupportedFunctionException, FormulaParsingException { + + Vector parseTokens = parser.parse(formula); + Vector rpnTokens = compiler.infix2RPN(parseTokens); + + ByteArrayOutputStream bytes = null; + try { + bytes = new ByteArrayOutputStream(); + for (Enumeration e = rpnTokens.elements(); e.hasMoreElements();) { + Token t = (Token)e.nextElement(); + bytes.write(encoder.getByte(t)); + } + } catch (IOException e) { + } + + return bytes.toByteArray(); + } + + /** + * Converts a PocketXL byte array into a Calc function string + * @param formula A byte array that contains the PocketXL bytes for a formula + * + */ + public String convertPXLToCalc(byte[] formula) { + + Vector parseTokens = decoder.getTokenVector(formula); + Vector infixTokens = compiler.RPN2Infix(parseTokens); + + StringBuffer buff = new StringBuffer(); + for (Enumeration e = infixTokens.elements();e.hasMoreElements();) { + Token t = (Token)e.nextElement(); + buff.append(t.toString()); + // If we are parsing a Name definition we need to know if it is of + // type range or expression + if(!t.isOperand()) { + expressionType = true; + } + } + if(!expressionType) { + rangeType = true; + } + return "=" + buff.toString(); + } + + /** + * Returns a boolean indicating whether or not the byte[] parsed is of + * type range. This means it contains only a cell reference and no + * operators. This is necessry because the syntax for range and expression + * types differs. This is only of interest when dealing with + * <code>DefinedNames</code> and not <code>Formula</code> + * + * @return a boolean true if of type range otherwise false + * + */ + public boolean isRangeType() { + + return rangeType; + } + + /** + * Returns a boolean indicating whether or not the byte[] parsed is of + * type expression. This means it contains operators. This is necessry + * because the syntax for range and expression types differs. This is + * only of interest when dealing with <code>DefinedNames</code> and not + * <code>Formula</code> + * + * @return a boolean true if of type expression otherwise false + * + */ + public boolean isExpressionType() { + + return expressionType; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaParser.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaParser.java new file mode 100644 index 000000000000..2422a5297b96 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaParser.java @@ -0,0 +1,567 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FormulaParser.java,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + + +import java.io.*; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; +import org.openoffice.xmerge.util.Debug; + +/** + * This is the Formula Parser based on an article written by Jack Crenshaw. It is a + * top down parser with some basic error handling. It handles + * +,-,*,/,>,<,>=,<=,=,<>, unary + and - as well as functions. + * The BNF notation for this parser is + * <pre> + * <expression> ::= <unary op> <term> [<addop>|<logop> <term>] + * <term> ::= <factor> [<mulop> <factor>] + * <factor> ::= <number>[%] | <CellRef> | <QuoteString> | <expression> + * </pre> + */ +public class FormulaParser { + + private char look; + private String formulaStr; + private int index = 1; + private TokenFactory tokenFactory; + private Vector tokenVector; + private Workbook wb; + + /** + * Default constructor + */ + public FormulaParser() { + + Debug.log(Debug.TRACE,"Creating a Formula Parser"); + tokenFactory = new TokenFactory(); + tokenVector = new Vector(); + } + + /** + * + */ + public void setWorkbook(Workbook wb) { + + this.wb = wb; + } + + /** + * Parse method for parsing from a String to a byte[] + * + * @param formula A <code>String</code> representation of a formula + * starting with the '=' character + * @return A <code>Vector</code> containing the parsed <code>Token</code>s + */ + public Vector parse(String formula) throws FormulaParsingException { + + index = 1; + look = ' '; + tokenVector.clear(); + if(formula.startsWith("=")) { + formulaStr = formula; + Debug.log(Debug.TRACE,"Creating a Formula Parser for " + formulaStr); + getChar(); + expression(); + } else { + throw new FormulaParsingException("No equals found!" + makeErrorString()); + } + return tokenVector; + } + + /** + * Identify + and - operators + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isAddOp(char c) { + return (c == '-') || (c == '+'); + } + + /** + * Determine if the current character is a multiop + * + * @return A boolean returning the result of the comparison + */ + private boolean isMultiOp() { + return look=='*' || look =='/' || look == '^' || look == '&'; + } + + /** + * Identify <, >, <=, >=, =, <> using the index to find the current character(s) + * + * @return A boolean returning the result of the comparison + */ + private boolean isLogicalOp() { + if (!isLogicalOpChar(look)) { + return false; + } else if ((index+1) >= formulaStr.length()) {//logical operators in their own right : if at end then return true + return true; + } else if (!isLogicalOpChar(formulaStr.charAt(index))) { // we have >, < or = on their own + return true; + } else if ((look == '<') && ((formulaStr.charAt(index) == '>') || formulaStr.charAt(index) == '=')) { // <>, or <= + return true; + } else if ((look == '>') && (formulaStr.charAt(index) == '=')) { // >= + return true; + } + + return false; + } + + /** + * Identify <, >, <=, >=, =, <> + * + * @param The <code>String</code> which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isLogicalOp(String op) { + return ((op.compareTo(">") == 0) || + (op.compareTo("<") == 0) || + (op.compareTo(">=") == 0) || + (op.compareTo("<=") == 0) || + (op.compareTo("=") == 0) || + (op.compareTo("<>") == 0)); + } + + + /** + * Identify characters that MAY be logical operator characters + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isLogicalOpChar(char c) { + return (c == '>') || (c == '<') || (c == '='); + } + + /** + * Identify special Cell Reference charaters + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isCellRefSpecialChar(char c) { + return (c == ':') || (c == '$') || (c == '.'); + } + + /** + * Identify letters + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isAlpha(char c) { + return(Character.isLetter(c)); + } + + /** + * Identify numbers + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isDigit(char c) { + return(Character.isDigit(c)); + } + + /** + * Identify numbers + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isPercent(char c) { + return (c == '%'); + } + + /** + * Identify letters or numbers + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isAlphaNum(char c) { + return(isAlpha(c) || isDigit(c)); + } + + /** + * Identify valid Characters for cell references + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isCellRefChar(char c) { + return(isAlpha(c) || isDigit(c) || isCellRefSpecialChar(c)); + } + + /** + * Test if current character is a match and move to next character + * + * @param c The character which is to be matched + */ + private void match(char c) throws FormulaParsingException { + + if(look==c) { + Debug.log(Debug.TRACE,"Operator Found : " + look); + getChar(); + skipWhite(); + } + else + throw new FormulaParsingException("Unexpected character '" + c + "'" + makeErrorString()); + } + + /** + * Test if current character is a match and move to next character + * + * @param symbol The <code>String</code> to be matched. + */ + private void match(String symbol) throws FormulaParsingException { + + int numChars = symbol.length(); + boolean bContinue = true; + for (int i=0;i<numChars && bContinue; i++) { + if (look == symbol.charAt(i)) { + bContinue = getChar(); + skipWhite(); + } else { + throw new FormulaParsingException("Unexpected character '" + symbol + "'" + makeErrorString()); + } + } + } + + /** + * Skip over whitespaces (ie. spaces and tabs) + */ + private void skipWhite() throws FormulaParsingException { + + boolean success = true; + + while(Character.isWhitespace(look) && success) { + success = getChar(); + } + } + + /** + * This is a factor for multiplication and division operators + */ + private void factor() throws FormulaParsingException { + if(isAddOp(look)) { // handle unary addop + Character ch = new Character(look); + match(look); + tokenVector.add(tokenFactory.getOperatorToken(ch.toString(), 1)); + } + if(look=='(') { + match('('); + tokenVector.add(tokenFactory.getOperatorToken("(", 1)); + expression(); + match(')'); + tokenVector.add(tokenFactory.getOperatorToken(")", 1)); + } else if(isDigit(look)){ + getNum(); + } else { + ident(); + } + } + + /** + * Pulls the next character from the <code>String</code> + * + * @return boolean false if the end if the statement + * is reached otherwise true + */ + private boolean getChar() throws FormulaParsingException { + + boolean success = true; + + if(index<formulaStr.length()) { + look = formulaStr.charAt(index); + index++; + if(look==',') + success = false; + } else { + success = false; + } + return success; + } + + /** + * Parses the number of arguments in a function + * + * @return The number of arguments + */ + private int arguments() throws FormulaParsingException { + int numArgs; + + skipWhite(); + if(look==')') + numArgs = 0; + else + numArgs = 1; + + while(look!=')') { + expression(); + if(look==',') { + numArgs++; + match(','); + tokenVector.add(tokenFactory.getOperatorToken(",", 1)); + } + } + return numArgs; + } + + /** + * Test to see if we have come across a cell reference or a Name + * Definition. + */ + private boolean isCellRef(String s) { + char c; + boolean result = false; + + for(int i = 0;i<s.length();i++) { + c = s.charAt(i); + if(isCellRefSpecialChar(c)) { + result = true; + break; + } + } + + // if it is a simple cell reference then there will not be a cell + // reference 'special char' so we should also look for a digit + if(!result) { + if(isDigit(s.charAt(1)) || isDigit(s.charAt(2))) { + result = true; + } + } + return result; + } + + /** + * Test to see if we have come across a cell reference or a function and + * add the resulting toek nto the tokenVector. + */ + private void ident() throws FormulaParsingException { + + String cell = getTokenString(); + if(look=='(') { + Debug.log(Debug.TRACE,"Found Function : " + cell); + + int index = tokenVector.size(); + match('('); + tokenVector.add(tokenFactory.getOperatorToken("(", 1)); + int numArgs = arguments(); + match(')'); + tokenVector.add(tokenFactory.getOperatorToken(")", 1)); + tokenVector.insertElementAt(tokenFactory.getFunctionToken(cell, numArgs), index); + } else { + + if(cell.indexOf('.')!=-1) { + String cellRef = cell.substring(cell.indexOf('.') + 1, cell.length()); + if(cellRef.indexOf(':')!=-1) { + tokenVector.add(tokenFactory.getOperandToken(cell, "3D_CELL_AREA_REFERENCE")); + } else { + tokenVector.add(tokenFactory.getOperandToken(cell, "3D_CELL_REFERENCE")); + } + } else if(cell.indexOf(':')!=-1) { + tokenVector.add(tokenFactory.getOperandToken(cell, "CELL_AREA_REFERENCE")); + } else if(isCellRef(cell)) { + tokenVector.add(tokenFactory.getOperandToken(cell, "CELL_REFERENCE")); + } else { + tokenVector.add(tokenFactory.getOperandToken(cell, "NAME")); + } + } + } + + /** + * Will keep pulling valid logical operators from the formula and return + * the resultant <code>String</code>. + * + * @return a <code>String<code> representing a logical operator + */ + private String getLogicalOperator() throws FormulaParsingException { + String op = new String(); + boolean status; + + do { + op += look; + status = getChar(); + } while(isLogicalOpChar(look) && status); + skipWhite(); + return op; + } + + /** + * Keeps pulling characters from the statement until we get an + * operator and returns the resulting string. + * + * @return A <code>String</code>representing the next token + */ + private String getTokenString() throws FormulaParsingException { + + if(!isAlpha(look) && look!='$') + throw new FormulaParsingException("Expected Cell Reference" + makeErrorString()); + else { + String cell = new String(); + boolean status; + do { + cell += look; + status = getChar(); + } while(isCellRefChar(look) && status); + skipWhite(); + return cell; + } + } + + /** + * Keeps pulling numbers from the statement and add the resulting integer + * token to the tokenVector. + */ + private void getNum() throws FormulaParsingException { + + Debug.log(Debug.TRACE,"getNum : "); + if(!isDigit(look)) + throw new FormulaParsingException("Expected Integer" + makeErrorString()); + else { + String num = new String(); + boolean status; + + do { + num += look; + status = getChar(); + } while((isDigit(look) || ((look == '.') && isDigit(formulaStr.charAt(index)))) && status); + skipWhite(); + tokenVector.add(tokenFactory.getOperandToken(num, "INTEGER")); + if(isPercent(look)) { + match(look); + tokenVector.add(tokenFactory.getOperatorToken("%", 1)); + Debug.log(Debug.TRACE,"Added Percent token to Vector: "); + } + Debug.log(Debug.TRACE,"Number parsed : " + num); + } + } + + + /** + * Term will parse multiplication/division expressions + */ + private void term() throws FormulaParsingException { + factor(); + while(isMultiOp()) { + multiOp(Character.toString(look)); + } + } + + /** + * Expression is the entry point for the parser. It is the code + * that parses addition/subtraction expressions. + */ + private void expression() throws FormulaParsingException { + + if (look == '"') { //Extract a quoted string... + StringBuffer buff = new StringBuffer(); + boolean success = true; + success = getChar(); + while (look != '"' && success) { + buff.append(look); + success = getChar(); + } + + if (look != '"') { //We've reached the end of the string without getting a closing quote + throw new FormulaParsingException("Expected closing quote." + makeErrorString()); + } else { + tokenVector.add(tokenFactory.getOperandToken(buff.toString(), "STRING")); + getChar(); //Move on to the next character + } + } else { + term(); + } + while(isAddOp(look) || isLogicalOp()) { + if (isAddOp(look)) { + addOp(Character.toString(look)); + } else if (isLogicalOp()) { + logicalOp(); + } + } + } + + /** + * Test to see if the next token (represented as a <code>String</code>) is + * the same as the String passed in. Move the index along to the end of + * that String and add that <code>Token</code> to the tokenVector. Then + * call <code>term</code> to parse the right hand side of the operator. + * + * @param op A <code>String</code> representing the operator + */ + private void addOp(String op) throws FormulaParsingException { + match(op); + tokenVector.add(tokenFactory.getOperatorToken(op, 2)); + term(); + } + + /** + * Test to see if the next token (represented as a <code>String</code>) is + * the same as the String passed in. Move the index along to the end of + * that String and add that <code>Token</code> to the tokenVector. Then + * call <code>factor</code> to parse the right hand side of the operator. + * + * @param op A <code>String</code> representing the operator + */ + private void multiOp(String op) throws FormulaParsingException { + match(op); + tokenVector.add(tokenFactory.getOperatorToken(op, 2)); + factor(); + } + + /** + * Pull a logical operator starting at the current index, add a token for + * that operator to the tokenVector and call <code>term<code> to parse the + * right hand side of the operator + */ + private void logicalOp() throws FormulaParsingException { + String op = getLogicalOperator(); + tokenVector.add(tokenFactory.getOperatorToken(op, 2)); + term(); + } + + private String makeErrorString() { + StringBuffer buff = new StringBuffer(); + for (int i=0; i<index-1; i++) { + buff.append(' '); + } + + buff.append('^'); + return "\n\t" + formulaStr + "\n\t" + buff.toString(); + } + } + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaParsingException.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaParsingException.java new file mode 100644 index 000000000000..f961bcbf49a0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FormulaParsingException.java @@ -0,0 +1,49 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FormulaParsingException.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +/* + * If the formula failed to be parsed properly this exception will be thrown + * + * Martin Maher + */ + +import java.io.*; + +import org.openoffice.xmerge.util.Debug; + +public class FormulaParsingException extends Exception { + + public FormulaParsingException(String message) { + super(message); + } + } diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FunctionLookup.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FunctionLookup.java new file mode 100644 index 000000000000..c8205b6d4754 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/FunctionLookup.java @@ -0,0 +1,210 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FunctionLookup.java,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import org.openoffice.xmerge.util.Debug; + +import java.util.HashMap; + +public class FunctionLookup extends SymbolLookup { + + private HashMap stringToArgs = null; + + /** + * The default constructor - invokes {@link #initialize() initialize()} + */ + public FunctionLookup() { + initialize(); + } + + /** + * Initialize the lookup table for functions + */ + public void initialize() { + if ((stringToID != null) || (idToString != null) || (stringToArgs !=null)) { + return; + } + stringToID = new HashMap(); + idToString = new HashMap(); + stringToArgs = new HashMap(); + + // Functions with Variable number of Arguments + // Math and Trig + addEntry("SUM", TokenConstants.TSUM, -1); + addEntry("MIN", TokenConstants.TMIN, -1); + addEntry("PRODUCT", TokenConstants.TPRODUCT, -1); + addEntry("LOG", TokenConstants.TLOG, -1); + addEntry("SUMIF", TokenConstants.TSUMIF, -1); + addEntry("TRUNC", TokenConstants.TRUNC, -1); + // Financial + addEntry("DDB", TokenConstants.TDDB, -1); + addEntry("FV", TokenConstants.TFV, -1); + addEntry("IRR", TokenConstants.TIRR, -1); + addEntry("NPER", TokenConstants.TNPER, -1); + addEntry("NPV", TokenConstants.TNPV, -1); + addEntry("PMT", TokenConstants.TPMT, -1); + addEntry("PV", TokenConstants.TPV, -1); + addEntry("RATE", TokenConstants.TRATE, -1); + // Statistical + addEntry("AVERAGE", TokenConstants.TAVERAGE, -1); + addEntry("COUNT", TokenConstants.TCOUNT, -1); + addEntry("COUNTA", TokenConstants.TCOUNTA, -1); + addEntry("MAX", TokenConstants.TMAX, -1 ); + addEntry("MIN", TokenConstants.TMIN, -1); + addEntry("STDEV", TokenConstants.TSTDEV, -1 ); + addEntry("STDEVP", TokenConstants.TSTDEVP, -1 ); + addEntry("VAR", TokenConstants.TVAR, -1); + addEntry("VARP", TokenConstants.TVARP, -1); + // Lookup + addEntry("CHOOSE", TokenConstants.TCHOOSE, -1); + addEntry("HLOOKUP", TokenConstants.THLOOKUP, -1); + addEntry("INDEX", TokenConstants.TINDEX, -1); + addEntry("MATCH", TokenConstants.TMATCH, -1) ; + addEntry("VLOOKUP", TokenConstants.TVLOOKUP, -1); + // Text + addEntry("RIGHT", TokenConstants.TRIGHT, -1); + addEntry("SUBSTITUTE", TokenConstants.TSUBSTITUTE, -1); + addEntry("FIND", TokenConstants.TFIND, -1); + addEntry("LEFT", TokenConstants.TLEFT, -1); + // Logical + addEntry("AND", TokenConstants.TAND, -1 ); + addEntry("IF", TokenConstants.TIF, -1) ; + addEntry("OR", TokenConstants.TOR, -1); + + // Functions with Fixed number of Arguments + // Math and Trig + addEntry("ABS", TokenConstants.TABS, 1); + addEntry("ACOS", TokenConstants.TACOS, 1); + addEntry("ASIN", TokenConstants.TASIN, 1); + addEntry("ATAN", TokenConstants.TATAN, 1); + addEntry("ATAN2", TokenConstants.TATAN2, 1); + addEntry("COS", TokenConstants.TCOS, 1); + addEntry("COUNTIF", TokenConstants.TCOUNTIF, 1); + addEntry("DEGREES", TokenConstants.TDEGREES, 1); + addEntry("EXP", TokenConstants.TEXP, 1); + addEntry("FACT", TokenConstants.TFACT, 1); + addEntry("INT", TokenConstants.TINTE, 1); + addEntry("LN", TokenConstants.TLN, 1); + addEntry("LOG10", TokenConstants.TLOG10, 1); + addEntry("MOD", TokenConstants.TMOD, 1); + addEntry("PI", TokenConstants.TPI, 0); + addEntry("POWER", TokenConstants.TPOWERF, 2); + addEntry("RADIANS", TokenConstants.TRADIANS, 1); + addEntry("RAND", TokenConstants.TRAND, 1); + addEntry("ROUND", TokenConstants.TROUND, 1); + addEntry("SQRT", TokenConstants.TSQRT, 1); + addEntry("TAN", TokenConstants.TTAN, 1); + addEntry("SIN", TokenConstants.TSIN, 1); + // Financial + addEntry("SLN", TokenConstants.TSLN, 3); + addEntry("SYD", TokenConstants.TSYD, 4); + // Date and Time + addEntry("DATE", TokenConstants.TDATE, 3); + addEntry("DATEVALUE", TokenConstants.TDATEVALUE, 1); + addEntry("DAY", TokenConstants.TDAY, 1); + addEntry("HOUR", TokenConstants.THOUR, 1); + addEntry("MINUTE", TokenConstants.TMINUTE, 1 ); + addEntry("MONTH", TokenConstants.TMONTH, 1); + addEntry("NOW", TokenConstants.TNOW, 0); + addEntry("SECOND", TokenConstants.TSECOND, 1); + addEntry("TIME", TokenConstants.TTIME, 3); + addEntry("TIMEVALUE", TokenConstants.TTIMEVALUE, 1); + addEntry("YEAR", TokenConstants.TYEAR, 1); + // Statistical + addEntry("COUNTBLANK", TokenConstants.TCOUNTBLANK, 1); + // lookup + addEntry("COLUMNS", TokenConstants.TCOLUMNS, 1); + addEntry("ROWS", TokenConstants.TROWS, 1); + // Database + addEntry("DAVERAGE", TokenConstants.TDAVAERAGE, 3); + addEntry("DCOUNT", TokenConstants.TDCOUNT, 3); + addEntry("DCOUNTA", TokenConstants.TDCOUNTA, 2); + addEntry("DGET", TokenConstants.TDGET, 3); + addEntry("DMAX", TokenConstants.TDMAX, 3); + addEntry("DMIN", TokenConstants.TDMIN, 3); + addEntry("DPRODUCT", TokenConstants.TDPRODUCT, 3); + addEntry("DSTDEV", TokenConstants.TDSTDEV, 3); + addEntry("DSTDEVP", TokenConstants.TDSTDEVP, 3) ; + addEntry("DSUM", TokenConstants.TDSUM, 3); + addEntry("DVAR", TokenConstants.TDVAR, 3); + addEntry("DVARP", TokenConstants.TDVARP, 3); + // Text + addEntry("EXACT", TokenConstants.TEXACT, 2); + addEntry("LEN", TokenConstants.TLEN, 1); + addEntry("LOWER", TokenConstants.TLOWER, 1); + addEntry("MID", TokenConstants.TMID, 3); // ?????? + addEntry("PROPER", TokenConstants.TPROPER, 1); + addEntry("REPLACE", TokenConstants.TREPLACE, 4); + addEntry("REPT", TokenConstants.TREPT, 2); + addEntry("T", TokenConstants.TT, 1); + addEntry("TRIM", TokenConstants.TRIM, 1); + addEntry("UPPER", TokenConstants.TUPPER, 1); + addEntry("VALUE", TokenConstants.TVALUE, 1); + // Logical + addEntry("FALSE", TokenConstants.TFALSE, 0); + addEntry("NOT", TokenConstants.TNOT, 1); + addEntry("TRUE", TokenConstants.TTRUE, 0); + // Informational + addEntry("ERRORTYPE", TokenConstants.TERRORTYPE, 1); + addEntry("ISBLANK", TokenConstants.TISBLANK, 1); + addEntry("ISERR", TokenConstants.TISERR, 1); + addEntry("ISERROR", TokenConstants.TISERROR, 1); + addEntry("ISLOGICAL", TokenConstants.TISLOGICAL, 1); + addEntry("ISNA", TokenConstants.TISNA, 1); + addEntry("ISNONTEXT", TokenConstants.TISNONTEXT, 1); + addEntry("ISNUMBER", TokenConstants.TISNUMBER, 1); + addEntry("ISTEXT", TokenConstants.TISTEXT, 1); + addEntry("N", TokenConstants.TN, 1); + addEntry("NA", TokenConstants.TNA, 0); + + } + + /** + * Associate a function with an identifier and specifiy the number of arguments for that function + * @param symbol The function string that will act as the key in the lookup table + * @param id The identifier for the function + * @param args The number of arguments this function requires + */ + public void addEntry(String symbol, int id, int args) { + addEntry(symbol, id); + stringToArgs.put(symbol, new Integer(args)); + } + + /** + * Retrieve the number of arguments for this function + * @param symbol The function name + * @return The number of arguments required by this function + */ + public int getArgCountFromString(String symbol) { + return ((Integer)stringToArgs.get(symbol)).intValue(); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/OperandLookup.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/OperandLookup.java new file mode 100644 index 000000000000..e8a547d1b9d6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/OperandLookup.java @@ -0,0 +1,68 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OperandLookup.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; +import java.util.HashMap; + +import org.openoffice.xmerge.util.Debug; + +/** + * A lookup table containing information about operands + */ +public class OperandLookup extends SymbolLookup { + + /** + * The default constructor - invokes {@link #initialize() initialize()} + */ + public OperandLookup() { + initialize(); + } + + /** + * Initialize the lookup table for operands + */ + public void initialize() { + if ((stringToID != null) || (idToString != null)) { + return; + } + stringToID = new HashMap(); + idToString = new HashMap(); + addEntry("CELL_REFERENCE", TokenConstants.TREF); + addEntry("CELL_AREA_REFERENCE", TokenConstants.TAREA); + addEntry("INTEGER", TokenConstants.TNUM); + addEntry("NUMBER", TokenConstants.TNUM); + addEntry("STRING", TokenConstants.TSTRING); + addEntry("NAME", TokenConstants.TNAME); + addEntry("3D_CELL_REFERENCE", TokenConstants.TREF3D); + addEntry("3D_CELL_AREA_REFERENCE", TokenConstants.TAREA3D); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/OperatorLookup.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/OperatorLookup.java new file mode 100644 index 000000000000..0e376a6d0152 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/OperatorLookup.java @@ -0,0 +1,79 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OperatorLookup.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.util.HashMap; + +import org.openoffice.xmerge.util.Debug; + +/** + * A lookup table containing information about operators + */ +public class OperatorLookup extends SymbolLookup { + + /** + * The default constructor - invokes {@link #initialize() initialize()} + */ + public OperatorLookup() { + initialize(); + } + + /** + * Initialize the lookup table for operators + */ + public void initialize() { + if ((stringToID != null) || (idToString != null)) { + return; + } + stringToID = new HashMap(); + idToString = new HashMap(); + addEntry("UNARY_PLUS", TokenConstants.TUPLUS); + addEntry("UNARY_MINUS", TokenConstants.TUMINUS); + addEntry("%", TokenConstants.TPERCENT); + addEntry("+", TokenConstants.TADD); + addEntry("-", TokenConstants.TSUB); + addEntry("*", TokenConstants.TMUL); + addEntry("/", TokenConstants.TDIV); + addEntry(",", TokenConstants.TARGSEP); + addEntry("^", TokenConstants.TPOWER); + addEntry("&", TokenConstants.TCONCAT); + addEntry("(", TokenConstants.TPAREN); + addEntry(")", TokenConstants.TCLOSEPAREN); + addEntry("<", TokenConstants.TLESS); + addEntry(">", TokenConstants.TGREATER); + addEntry(">=", TokenConstants.TGTEQUALS); + addEntry("<=", TokenConstants.TLESSEQUALS); + addEntry("=", TokenConstants.TEQUALS); + addEntry("<>", TokenConstants.TNEQUALS); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/ParseToken.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/ParseToken.java new file mode 100644 index 000000000000..41912b046e7c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/ParseToken.java @@ -0,0 +1,46 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ParseToken.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +public interface ParseToken +{ + public boolean isOperand(); + public boolean isOperator(); + public int getTokenType(); + + //GENERIC TOKENS (MOSTLY UNUSED + public static final int TOKEN_OPERATOR = 1; + public static final int TOKEN_OPERAND = 2; + public static final int TOKEN_FUNCTION_FIXED = 3; + public static final int TOKEN_FUNCTION_VARIABLE = 4; + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/PrecedenceTable.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/PrecedenceTable.java new file mode 100644 index 000000000000..265334f553f1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/PrecedenceTable.java @@ -0,0 +1,89 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PrecedenceTable.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.util.HashMap; + +/** + * This class defines the precedence applied to each operator when performing a conversion + * {@link org.openoffice.xmerge.converter.xml.sxc.pexcel.Records.formula.FormulaCompiler.infix2 from infix to RPN.}. + */ +public class PrecedenceTable { + public static final int DEFAULT_PRECEDENCE = 0; + public static final int EQNEQ_PRECEDENCE = 1; // =, <> + public static final int GTLTEQ_PRECEDENCE = 1; // >=, <= + public static final int GTLT_PRECEDENCE = 2; // >, < + public static final int ADDOP_PRECEDENCE = 4; // +, - + public static final int MULTOP_PRECEDENCE = 5; // *, / + public static final int FACTOR_PRECEDENCE = 6; // ^ + public static final int CONCAT_PRECEDENCE = 6; // & + public static final int UNARY_PRECEDENCE = 7; // !, Unary +, Unary - + public static final int PAREN_PRECEDENCE = 8; // (, ) + public static final int FUNCTION_PRECEDENCE = 8; + public static final int COMMA_PRECEDENCE = 8; + + private static HashMap map; + static { + map = new HashMap(); + + map.put("%", new Integer(UNARY_PRECEDENCE)); + map.put("+", new Integer(ADDOP_PRECEDENCE)); + map.put("-", new Integer(ADDOP_PRECEDENCE)); + map.put("*", new Integer(MULTOP_PRECEDENCE)); + map.put("/", new Integer(MULTOP_PRECEDENCE)); + map.put("(", new Integer(PAREN_PRECEDENCE)); + map.put(")", new Integer(PAREN_PRECEDENCE)); + map.put(",", new Integer(COMMA_PRECEDENCE)); + map.put(">", new Integer(GTLT_PRECEDENCE)); + map.put("<", new Integer(GTLT_PRECEDENCE)); + map.put("=", new Integer(EQNEQ_PRECEDENCE)); + map.put("&", new Integer(CONCAT_PRECEDENCE)); + map.put("^", new Integer(FACTOR_PRECEDENCE)); + map.put(">=", new Integer(GTLTEQ_PRECEDENCE)); + map.put("<=", new Integer(GTLTEQ_PRECEDENCE)); + map.put("<>", new Integer(EQNEQ_PRECEDENCE)); + map.put("FUNCTION", new Integer(FUNCTION_PRECEDENCE)); + } + + /** + * Retrieve the precedence value for a given operator. + * @param op Look up the precedence for this operator + * @return an integer representing the integer value of the operator + */ + public static int getPrecedence(String op) { + Object obj = map.get(op); + if (obj == null) { + return DEFAULT_PRECEDENCE; + } + return ((Integer)obj).intValue(); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/SymbolLookup.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/SymbolLookup.java new file mode 100644 index 000000000000..9c9ba638b448 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/SymbolLookup.java @@ -0,0 +1,85 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SymbolLookup.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.util.HashMap; + +/** + * This interface defines the attributes of a lookup table for this plugin. + * Symbols will generally be either operators (_, -, *, etc) or funtion names. + */ +public abstract class SymbolLookup { + + protected HashMap stringToID = null; + protected HashMap idToString = null; + + /** + * Perform lookup table specific initialization. This would typically entail loading values into + * the lookup table. It is best to optimize this process so that data is loaded statically and shared + * across all instances of the lookup table. + */ + abstract public void initialize(); + + /** + * Associate a symbol with a numeric value in the lookup table + * @param symbol The symbol that will act as the key in the lookup table + * @param value The value to be associated with a given symbol + */ + public void addEntry(String symbol, int id) { + Integer iObj = new Integer(id); + stringToID.put(symbol, iObj); + idToString.put(iObj, symbol); + } + + /** + * Retrieve the symbol associated with a given identifier + * @param id The identfier for which we need to retieve the symbol string + * @return The string associated with this identifier in the lookup table. + */ + public String getStringFromID(int id) { + return (String)idToString.get(new Integer(id)); + } + + /** + * Retrieve the identifier associated with a given symbol + * @param symbol The symbol for which we need to retieve the identifier + * @throws UnsupportedFunctionException Thown when the symbol is not found in the lookup table + * @return The identifier associated with this string in the lookup table. + */ + public int getIDFromString(String symbol) throws UnsupportedFunctionException { + Integer i = (Integer)stringToID.get(symbol); + if (i == null) + throw new UnsupportedFunctionException("Token '" + symbol + "' not supported by Pocket Excel"); + + return ((Integer)stringToID.get(symbol)).intValue(); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/Token.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/Token.java new file mode 100644 index 000000000000..4ec1884dae8b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/Token.java @@ -0,0 +1,157 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Token.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + + +import java.io.*; + +/** + * A Token is the basic building block of any formula. + * A Token can be of four types (Operator, Operand, Function with fixed + * arguments and function with a variable number of arguments. Each type can + * have numerous id's. Thetypes are define in <code>ParseToken</code> and the + * id's are defined in <code>TokenConstants</code>. The other member variables + * are priority which is returned from the <code>PrecedenceTable</code>, the + * value which is the String equivalent of the token (eg. "+", "$A$12", "SUM") + * and the number of arguments which is only valid for operators and functions. + * Tokens should never be created directly and instead are created by the + * <code>TokenFactory</code> + */ +public class Token implements ParseToken { + + private String value; + private int type; // operator, operand, function fixed, function variable + private int id; // cell reference, SUM, integer + private int priority; + private int numArgs=-1; + + public Token(String op, int type, int id, int args) { + this.value = op; + this.type = type; + this.id = id; + this.numArgs = args; + if(type==ParseToken.TOKEN_FUNCTION_VARIABLE) { + priority = PrecedenceTable.getPrecedence("FUNCTION"); + } else if(type==ParseToken.TOKEN_OPERATOR) { + priority = PrecedenceTable.getPrecedence(op); + } else { + priority = PrecedenceTable.getPrecedence("DEFAULT"); + } + } + + /** + * Checks if the current token is an operator + * + * @return A <code>boolean</code> result of the comaparison + */ + public boolean isOperator() { + return type == ParseToken.TOKEN_OPERATOR; + } + + /** + * Checks if the current token is an operand + * + * @return A <code>boolean</code> result of the comaparison + */ + public boolean isOperand() { + return type == ParseToken.TOKEN_OPERAND; + } + + /** + * Checks if the current token is a function + * + * @return A <code>boolean</code> result of the comaparison + */ + public boolean isFunction() { + return (type==ParseToken.TOKEN_FUNCTION_FIXED) || (type==ParseToken.TOKEN_FUNCTION_VARIABLE); + } + + /** + * Returns the token type. This can be one of four values (TOKEN_OPERATOR, + * TOKEN_OPERAND, TOKEN_FUNCTION_FIXED, TOKEN_FUNCTION_VARIABLE) defined in + * <code>ParseToken</code> + * + * @return A <code>boolean</code> result of the comparison + */ + public int getTokenType() { + + return type; + } + + /** + * Returns the ID of this token. This ID is equivalent to the pexcel hex + * value and is defined in <code>ParseToken</code> + * + * @return Returns the id of this token + */ + public int getTokenID() { + + return id; + } + + /** + * Returns the <code>String</code> equivalent of this token + * + * @return The <code>String</code> representing this Token + */ + public String getValue() { + return value; + } + + /** + * Returns the number of arguments if this token represents an operator or + * function. Otherwise returns -1. + * + * @return The number of arguments + */ + public int getNumArgs() { + return numArgs; + } + + /** + * Checks if the current token is an operator + * + * @return A <code>boolean</code> result of the comparison + */ + public int getTokenPriority() { + return priority; + } + + /** + * Returns the <code>String</code> equivalent of this token + * + * @return The <code>String</code> representing this Token + */ + public String toString() { + return getValue(); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenConstants.java new file mode 100644 index 000000000000..b8b37be7772e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenConstants.java @@ -0,0 +1,209 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TokenConstants.java,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.io.*; + +public interface TokenConstants { + + // Unary Operator Tokens + public static final int TUPLUS = 0x12; + public static final int TUMINUS = 0x13; + public static final int TPERCENT = 0x14; + public static final int TPAREN = 0x15; + // Binary Operator Tokens + public static final int TADD = 0x03; + public static final int TSUB = 0x04; + public static final int TMUL = 0x05; + public static final int TDIV = 0x06; + public static final int TPOWER = 0x07; + public static final int TCONCAT = 0x08; + + //Logical operators + public static final int TLESS = 0x09; + public static final int TLESSEQUALS = 0x0A; + public static final int TEQUALS = 0x0B; + public static final int TGTEQUALS = 0x0C; + public static final int TGREATER = 0x0D; + public static final int TNEQUALS = 0x0E; + + // Function Operator Tokens + public static final int TFUNC = 0x41; + public static final int TFUNCVAR = 0x42; + + // Constant Operand Tokens + public static final int TSTRING = 0x17; + public static final int TINT = 0x1E; + public static final int TNUM = 0x1F; + // Operand Tokens + public static final int TREF = 0x44; + public static final int TAREA = 0x25; + public static final int TNAME = 0x23; + public static final int TREF3D = 0x3A; + public static final int TAREA3D = 0x3B; + + // + public static final int TARGSEP = 0x1001; + public static final int TCLOSEPAREN = 0x1002; + + // Variable argument Functions + // Math and Trig + public static final int TSUM = 0x04; + public static final int TPRODUCT = 0xB7; + public static final int TSUMIF = 0x0159; + public static final int TLOG = 0x6D; + public static final int TRUNC = 0xC5; + // Financial + public static final int TDDB = 0x90; + public static final int TFV = 0x39; + public static final int TIRR = 0x3E; + public static final int TNPER = 0x3A; + public static final int TNPV = 0x0B; + public static final int TPMT = 0x3B; + public static final int TPV = 0x38; + public static final int TRATE = 0x3C; + // Statistical + public static final int TAVERAGE = 0x05; + public static final int TCOUNT = 0x00; + public static final int TCOUNTA = 0xA9; + public static final int TMAX = 0x07; + public static final int TMIN = 0x06; + public static final int TSTDEV = 0x0C; + public static final int TSTDEVP = 0xC1; + public static final int TVAR = 0x2E; + public static final int TVARP = 0xC2; + // Lookup + public static final int TCHOOSE = 0x64; + public static final int THLOOKUP = 0x65; + public static final int TINDEX = 0x1D; + public static final int TMATCH = 0x40; + public static final int TVLOOKUP = 0x66; + // Text + public static final int TRIGHT = 0x74; + public static final int TSUBSTITUTE = 0x78; + public static final int TFIND = 0x7c; + public static final int TLEFT = 0x73; + // Logical + public static final int TAND = 0x24; // 42 + public static final int TIF = 0x01; // 42 + public static final int TOR = 0x25; // 42 + + // Fixed argument Functions + // Math and Trig + public static final int TABS = 0x18; + public static final int TACOS = 0x63; + public static final int TASIN = 0x62; + public static final int TATAN = 0x12; + public static final int TATAN2 = 0x61; + public static final int TCOS = 0x10; + public static final int TSIN = 0x0F; + + public static final int TCOUNTIF = 0x015A; + public static final int TDEGREES = 0x0157; + public static final int TEXP = 0x15; + public static final int TFACT = 0xB8; + public static final int TINTE = 0x19; + public static final int TLN = 0x16; + + public static final int TLOG10 = 0x17; + public static final int TMOD = 0x27; + public static final int TPI = 0x13; + + public static final int TPOWERF = 0x0151; + public static final int TRADIANS = 0x0156; + public static final int TRAND = 0x3F; + public static final int TROUND = 0x1B; + public static final int TSQRT = 0x14; + public static final int TTAN = 0x11; + + public static final int TSLN = 0x8E; + public static final int TSYD = 0x8F; + + // Date and Time + public static final int TDATE = 0x41; + public static final int TDATEVALUE = 0x8C; + public static final int TDAY = 0x43; + public static final int THOUR = 0x47; + public static final int TMINUTE = 0x48; + public static final int TMONTH = 0x44; + public static final int TNOW = 0x4A; + public static final int TSECOND = 0x49; + public static final int TTIME = 0x42; + public static final int TTIMEVALUE = 0x8D; + public static final int TYEAR = 0x45; + // Statistical + public static final int TCOUNTBLANK = 0x015B ; + // lookup + public static final int TCOLUMNS = 0x4D; + public static final int TROWS = 0x4C; + // Database + public static final int TDAVAERAGE = 0x2A; + public static final int TDCOUNT = 0x28; + public static final int TDCOUNTA = 0xC7; + public static final int TDGET = 0xEB; + public static final int TDMAX = 0x2C; + public static final int TDMIN = 0x2B; + public static final int TDPRODUCT = 0xBD; + public static final int TDSTDEV = 0x2D; + public static final int TDSTDEVP = 0xC3; + public static final int TDSUM = 0x29; + public static final int TDVAR = 0x2F; + public static final int TDVARP = 0xC4; + // Text + public static final int TEXACT = 0x75; + public static final int TLEN = 0x20; + public static final int TLOWER = 0x70; + public static final int TMID = 0x1F; // ?????? + public static final int TPROPER = 0x72; + public static final int TREPLACE = 0x77; + public static final int TREPT = 0x1E; + public static final int TT = 0x82; + public static final int TRIM = 0x76; + public static final int TUPPER = 0x71; + public static final int TVALUE = 0x21; + // Logical + public static final int TFALSE = 0x23; + public static final int TNOT = 0x26; + public static final int TTRUE = 0x22; + // Informational + public static final int TERRORTYPE = 0x05; + public static final int TISBLANK = 0x81; + public static final int TISERR = 0x7E; + public static final int TISERROR = 0x03; + public static final int TISLOGICAL = 0xC6; + public static final int TISNA = 0x02; + public static final int TISNONTEXT = 0xBE; + public static final int TISNUMBER = 0x80; + public static final int TISTEXT = 0x7F; + public static final int TN = 0x83; + public static final int TNA = 0x0A; +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenDecoder.java new file mode 100644 index 000000000000..3390463e3756 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenDecoder.java @@ -0,0 +1,501 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TokenDecoder.java,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.io.*; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.DefinedName; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; + +/** + * The TokenDecoder decodes a byte[] to an equivalent <code>String</code>. The only + * public method apart from the default constructor is the getTokenVector method. + * This method takes an entire formula as a pexcel byte[] and decodes it into + * a series of <code>Token</code>s. It adds these to a <code>Vector</code> which + * is returned once all the tokens have been decoded. The Decoder supports + * the following tokens.<br><br> + * + * Operands Floating point's, Cell references (absolute and relative), + * cell ranges<br> + * Operators +,-,*,/,<,>.<=,>=,<><br> + * Functions All pexcel fixed and varaible argument functions + * + */ +public class TokenDecoder { + + private TokenFactory tf; + private FunctionLookup fl; + private OperatorLookup operatorLookup; + private OperandLookup operandLookup; + private Workbook wb; + + /** + * Default Constructor initializes the <code>TokenFactory</code> for generating + * <code>Token</code> and the <code>SymbolLookup</code> for generating + * Strings from hex values. + */ + public TokenDecoder() { + tf = new TokenFactory(); + fl = new FunctionLookup(); + operatorLookup = new OperatorLookup(); + operandLookup = new OperandLookup(); + } + + /** + * Sets global workbook data needed for defined names + */ + public void setWorkbook(Workbook wb) { + + Debug.log(Debug.TRACE, "TokenDecoder : setWorkbook"); + this.wb = wb; + } + + /** + * Returns a <code>Vector</code> of <code>Token</code> decoded from a + * byte[]. The byte[] is first converted to a + * <code>ByteArrayInputStream</code> as this is the easiest way of reading + * bytes. + * + * @param formula A Pocket Excel Formula byte[] + * @return A <code>Vector</code> of deoded <code>Token</code> + */ + public Vector getTokenVector(byte[] formula) { + + Vector v = new Vector(); + + ByteArrayInputStream bis = new ByteArrayInputStream(formula); + int b = 0 ; + Token t; + + while (bis.available()!=0) + { + b = bis.read(); + + switch (b) { + + case TokenConstants.TAREA3D: + Debug.log(Debug.TRACE, "Decoded 3D Area Cell Reference: "); + v.add(read3DCellAreaRefToken(bis)); + Debug.log(Debug.TRACE, "Decoded 3D Area Cell Reference: " + v.lastElement()); + break; + case TokenConstants.TREF3D: + Debug.log(Debug.TRACE, "Decoded 3D Cell Reference: "); + v.add(read3DCellRefToken(bis)); + Debug.log(Debug.TRACE, "Decoded 3D Cell Reference: " + v.lastElement()); + break; + case TokenConstants.TREF : + v.add(readCellRefToken(bis)); + Debug.log(Debug.TRACE, "Decoded Cell Reference: " + v.lastElement()); + break; + case TokenConstants.TAREA : + v.add(readCellAreaRefToken(bis)); + Debug.log(Debug.TRACE, "Decoded Cell Area Reference: " + v.lastElement()); + break; + case TokenConstants.TNUM : + v.add(readNumToken(bis)); + Debug.log(Debug.TRACE, "Decoded number : " + v.lastElement()); + break; + case TokenConstants.TFUNCVAR : + v.add(readFunctionVarToken(bis)); + Debug.log(Debug.TRACE, "Decoded variable argument function: " + v.lastElement()); + break; + case TokenConstants.TFUNC : + v.add(readFunctionToken(bis)); + Debug.log(Debug.TRACE, "Decoded function: " + v.lastElement()); + break; + case TokenConstants.TSTRING : + v.add(readStringToken(bis)); + Debug.log(Debug.TRACE, "Decoded string: " + v.lastElement()); + break; + case TokenConstants.TNAME : + v.add(readNameToken(bis)); + Debug.log(Debug.TRACE, "Decoded defined name: " + v.lastElement()); + break; + case TokenConstants.TUPLUS: + case TokenConstants.TUMINUS: + case TokenConstants.TPERCENT: + v.add(readOperatorToken(b, 1)); + Debug.log(Debug.TRACE, "Decoded Unary operator : " + v.lastElement()); + break; + case TokenConstants.TADD : + case TokenConstants.TSUB : + case TokenConstants.TMUL : + case TokenConstants.TDIV : + case TokenConstants.TLESS : + case TokenConstants.TLESSEQUALS : + case TokenConstants.TEQUALS : + case TokenConstants.TGTEQUALS : + case TokenConstants.TGREATER : + case TokenConstants.TNEQUALS : + v.add(readOperatorToken(b, 2)); + Debug.log(Debug.TRACE, "Decoded Binary operator : " + v.lastElement()); + break; + + default : + Debug.log(Debug.TRACE, "Unrecognized byte : " + b); + } + } + return v; + } + + /** + * Converts a zero based integer to a char (eg. a=0, b=1). + * It assumes the integer is less than 26. + * + * @param i A 0 based index + * @return The equivalent character + */ + private char int2Char(int i) { + return (char) ('A' + i); + } + + /** + * Reads a Cell Reference token from the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded String <code>Token</code> + */ + private Token readStringToken(ByteArrayInputStream bis) { + + int len = ((int)bis.read())*2; + int options = (int)bis.read(); + Debug.log(Debug.TRACE,"String length is " + len + " and Options Flag is " + options); + byte [] stringBytes = new byte[len]; + int numRead =0; + if ((numRead = bis.read(stringBytes, 0, len)) != len) { + Debug.log(Debug.TRACE,"Expected " + len + " bytes. Could only read " + numRead + " bytes."); + //throw new IOException("Expected " + len + " bytes. Could only read " + numRead + " bytes."); + } + StringBuffer outputString = new StringBuffer(); + outputString.append('"'); + try { + Debug.log(Debug.TRACE,"Using LE encoding"); + outputString.append(new String(stringBytes, "UTF-16LE")); + } catch (IOException eIO) { + outputString.append(new String(stringBytes)); //fall back to default encoding + } + outputString.append('"'); + + return (tf.getOperandToken(outputString.toString(), "STRING")); + } + + /** + * Reads a Defined Name token from the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded Name <code>Token</code> + */ + private Token readNameToken(ByteArrayInputStream bis) { + byte buffer[] = new byte[2]; + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int nameIndex = EndianConverter.readShort(buffer); + bis.skip(12); // the next 12 bytes are unused + Enumeration e = wb.getDefinedNames(); + int i = 1; + while(i<nameIndex) { + e.nextElement(); + i++; + } + Debug.log(Debug.TRACE,"Name index is " + nameIndex); + DefinedName dn = (DefinedName)e.nextElement(); + Debug.log(Debug.TRACE,"DefinedName is " + dn.getName()); + return (tf.getOperandToken(dn.getName(), "NAME")); + } + + /** + * Reads a Cell Reference token from the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded Cell Reference <code>Token</code> + */ + private Token readCellRefToken(ByteArrayInputStream bis) { + + byte buffer[] = new byte[2]; + String outputString = new String(); + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int formulaRow = EndianConverter.readShort(buffer); + int relativeFlags = (formulaRow & 0xC000)>>14; + formulaRow &= 0x3FFF; + int formulaCol = (byte) bis.read(); + + outputString = int2CellStr(formulaRow, formulaCol, relativeFlags); + + return (tf.getOperandToken(outputString,"CELL_REFERENCE")); + } + + /** + * Reads a Cell Reference token from the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded Cell Reference <code>Token</code> + */ + private Token read3DCellRefToken(ByteArrayInputStream bis) { + + byte buffer[] = new byte[2]; + String outputString = new String(); + + bis.skip(10); + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int Sheet1 = EndianConverter.readShort(buffer); + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int Sheet2 = EndianConverter.readShort(buffer); + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int formulaRow = EndianConverter.readShort(buffer); + int relativeFlags = (formulaRow & 0xC000)>>14; + formulaRow &= 0x3FFF; + int formulaCol = (byte) bis.read(); + String cellRef = "." + int2CellStr(formulaRow, formulaCol, relativeFlags); + if(Sheet1 == Sheet2) { + outputString = "$" + wb.getSheetName(Sheet1) + cellRef; + } else { + outputString = "$" + wb.getSheetName(Sheet1) + cellRef + ":$" + wb.getSheetName(Sheet2) + cellRef; + } + + return (tf.getOperandToken(outputString,"3D_CELL_REFERENCE")); + } + + /** + * Reads a Cell Reference token from the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded Cell Reference <code>Token</code> + */ + private Token read3DCellAreaRefToken(ByteArrayInputStream bis) { + + byte buffer[] = new byte[2]; + String outputString = new String(); + + bis.skip(10); + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int Sheet1 = EndianConverter.readShort(buffer); + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int Sheet2 = EndianConverter.readShort(buffer); + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int formulaRow1 = EndianConverter.readShort(buffer); + int relativeFlags1 = (formulaRow1 & 0xC000)>>14; + formulaRow1 &= 0x3FFF; + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int formulaRow2 = EndianConverter.readShort(buffer); + int relativeFlags2 = (formulaRow2 & 0xC000)>>14; + formulaRow2 &= 0x3FFF; + + int formulaCol1 = (byte) bis.read(); + int formulaCol2 = (byte) bis.read(); + + String cellRef1 = "." + int2CellStr(formulaRow1, formulaCol1, relativeFlags1); + String cellRef2 = int2CellStr(formulaRow2, formulaCol2, relativeFlags2); + + if(Sheet1 == Sheet2) { + outputString = "$" + wb.getSheetName(Sheet1) + cellRef1 + ":" + cellRef2; + } else { + outputString = "$" + wb.getSheetName(Sheet1) + cellRef1 + ":$" + wb.getSheetName(Sheet2) + "." + cellRef2; + } + + return (tf.getOperandToken(outputString,"3D_CELL_AREA_REFERENCE")); + } + + /** + * Converts a row and col 0 based index to a spreadsheet cell reference. + * It also has a relativeFlags which indicates whether or not the + * Cell Reference is relative or absolute (Absolute is denoted with '$') + * + * 00 = absolute row, absolute col + * 01 = absolute row, relative col + * 10 = relative row, absolute col + * 11 = relative row, relative col + * + * @param row The cell reference 0 based index to the row + * @param col The cell reference 0 based index to the row + * @param relativeFlags Flags indicating addressing of row and column + * @return A <code>String</code> representing a cell reference + */ + private String int2CellStr(int row, int col, int relativeFlags) { + String outputString = ""; + int firstChar = (col + 1) / 26; + + if((relativeFlags & 1) == 0) { + outputString += "$"; + } + + if(firstChar>0) { + int secondChar = (col + 1) % 26; + outputString += Character.toString(int2Char(firstChar - 1)) + Character.toString(int2Char(secondChar - 1)); + } else { + outputString += Character.toString(int2Char(col)); + } + if((relativeFlags & 2) == 0) { + outputString += "$"; + } + outputString += Integer.toString(row+1); + return outputString; + } + + /** + * Reads a Cell Area Reference (cell range) <code>Token</code> from + * the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The equivalent Cell Area Reference (cell range) + * <code>Token</code> + */ + private Token readCellAreaRefToken(ByteArrayInputStream bis) { + byte buffer[] = new byte[2]; + int formulaRow1, formulaRow2; + int formulaCol1, formulaCol2; + + String outputString = new String(); + + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + formulaRow1 = EndianConverter.readShort(buffer); + int relativeFlags1 = (formulaRow1 & 0xC000)>>14; + formulaRow1 &= 0x3FFF; + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + formulaRow2 = EndianConverter.readShort(buffer); + int relativeFlags2 = (formulaRow2 & 0xC000)>>14; + formulaRow2 &= 0x3FFF; + + formulaCol1 = (byte) bis.read(); + formulaCol2 = (byte) bis.read(); + + outputString = int2CellStr(formulaRow1, formulaCol1, relativeFlags1); + outputString += (":" + int2CellStr(formulaRow2, formulaCol2, relativeFlags2)); + + return (tf.getOperandToken(outputString,"CELL_AREA_REFERENCE")); + } + + + /** + * Reads a Number (floating point) token from the <code>ByteArrayInputStream</code> + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded Integer <code>Token</code> + */ + private Token readNumToken(ByteArrayInputStream bis) { + + byte numBuffer[] = new byte[8]; + + for(int j=0;j<8;j++) { + numBuffer[j]=(byte) bis.read(); + } + + return (tf.getOperandToken(Double.toString(EndianConverter.readDouble(numBuffer)),"NUMBER")); + } + + /** + * Read an Operator token from the <code>ByteArrayInputStream</code> + * + * @param b A Pocket Excel number representing an operator. + * @param args The number of arguments this operator takes. + * @return The decoded Operator <code>Token</code> + */ + private Token readOperatorToken(int b, int args) { + + Token t; + + if(b==TokenConstants.TUPLUS) { + t = tf.getOperatorToken("+", args); + } else if(b==TokenConstants.TUMINUS) { + t = tf.getOperatorToken("-", args); + } else { + t = tf.getOperatorToken(operatorLookup.getStringFromID(b), args); + } + return t; + } + + /** + * Read a Function token from the <code>ByteArrayInputStream</code> + * This function can have any number of arguments and this number is read + * in with the record + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded variable argument Function <code>Token</code> + */ + private Token readFunctionVarToken(ByteArrayInputStream bis) { + + int numArgs = 0; + numArgs = bis.read(); + byte buffer[] = new byte[2]; + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int functionID = EndianConverter.readShort(buffer); + return (tf.getFunctionToken(fl.getStringFromID(functionID),numArgs)); + } + + /** + * Read a Function token from the <code>ByteArrayInputStream</code> + * This function has a fixed number of arguments which it will get + * from <code>FunctionLookup</code>. + * + * @param bis The <code>ByteArrayInputStream</code> from which we read the + * bytes. + * @return The decoded fixed argument Function <code>Token</code> + */ + private Token readFunctionToken(ByteArrayInputStream bis) { + + byte buffer[] = new byte[2]; + buffer[0] = (byte) bis.read(); + buffer[1] = (byte) bis.read(); + int functionID = EndianConverter.readShort(buffer); + String functionName = fl.getStringFromID(functionID); + return (tf.getFunctionToken(functionName,fl.getArgCountFromString(functionName))); + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenEncoder.java new file mode 100644 index 000000000000..d2002df2819a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenEncoder.java @@ -0,0 +1,564 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TokenEncoder.java,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.io.*; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.Workbook; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.BoundSheet; +import org.openoffice.xmerge.converter.xml.sxc.pexcel.records.DefinedName; + +/** + * The TokenEncoder encodes a Token to an equivalent pexcel byte[]. The only + * public method apart from the default constructor is the getByte method. + * This method picks an encoder based onthe Token's type or id field and uses + * that encoder to return a byte[] which it returns. This Encoder supports + * Operands Floating point's, Cell references (absolute and relative), + * cell ranges + * Operators +,-,*,/,<,>.<=,>=,<> + * Functions All pexcel fixed and varaible argument functions + * + */ +public class TokenEncoder { + + private FunctionLookup fl; + private String parseString; + private int index; + private Workbook wb; + + /** + * Default Constructor + */ + public TokenEncoder() { + + parseString = new String(); + fl = new FunctionLookup(); + } + + /** + * Sets global workbook data needed for defined names + */ + public void setWorkbook(Workbook wb) { + + this.wb = wb; + } + + + /** + * Return the byte[] equivalent of a <code>Token</code>. The various + * encoders return <code>Vector</code> of <code>Byte</code> instead + * of byte[] because the number of bytes returned varies with each + * <code>Token</code> encoded. After the encoding is finished the Vector + * in converted to a byte[]. + * + * @param t The <code>Token</code> to be encoded + * @return An equivalent Pocket Excel byte[] + */ + public byte[] getByte(Token t) throws IOException { + + Vector tmpByteArray = null; // we use this cause we don't know till after + // the encoding takes place how big the byte [] will be + //index=0; // This class is declared static in + // FormulaHelper so better make sure our index is 0 + if(t.getTokenType()==ParseToken.TOKEN_OPERATOR) { + tmpByteArray = operatorEncoder(t); + } else if (t.getTokenType()==ParseToken.TOKEN_FUNCTION_VARIABLE || t.getTokenType()==ParseToken.TOKEN_FUNCTION_FIXED){ + tmpByteArray = functionEncoder(t); + } else { // Operands and functions + switch(t.getTokenID()) { + case TokenConstants.TNAME : + tmpByteArray = nameDefinitionEncoder(t); + break; + case TokenConstants.TREF3D : + tmpByteArray = threeDCellRefEncoder(t); + break; + case TokenConstants.TAREA3D: + tmpByteArray = threeDAreaRefEncoder(t); + break; + case TokenConstants.TREF : + tmpByteArray = cellRefEncoder(t); + break; + case TokenConstants.TAREA : + tmpByteArray = areaRefEncoder(t); + break; + case TokenConstants.TNUM : + tmpByteArray = numEncoder(t); + break; + case TokenConstants.TSTRING : + tmpByteArray = stringEncoder(t); + break; + default : + Debug.log(Debug.ERROR, "Encoder found unrecognized Token"); + } + } + + byte cellRefArray[] = new byte[tmpByteArray.size()]; + int i = 0; + String s = new String(); + for(Enumeration e = tmpByteArray.elements();e.hasMoreElements();) { + Byte tmpByte = (Byte) e.nextElement(); + s = s + tmpByte + " "; + cellRefArray[i] = tmpByte.byteValue(); + i++; + } + Debug.log(Debug.TRACE, "Encoding Token " + t.getValue() + " as [" + s + "]"); + return cellRefArray; + } + + /** + * An Operator Encoder. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector operatorEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + tmpByteArray.add(new Byte((byte)t.getTokenID())); + return tmpByteArray; + } + + + /** + * A String Encoder. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector stringEncoder(Token t) throws IOException{ + + Vector tmpByteArray = new Vector(); + tmpByteArray.add(new Byte((byte)t.getTokenID())); + tmpByteArray.add(new Byte((byte)(t.getValue().length()))); + tmpByteArray.add(new Byte((byte)0x01)); + byte [] stringBytes = t.getValue().getBytes("UTF-16LE"); + for (int i=0; i<stringBytes.length; i++) { + tmpByteArray.add(new Byte(stringBytes[i])); + } + return tmpByteArray; + } + + + /** + * An Integer Encoder. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector numEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + + double cellLong = (double) Double.parseDouble(t.getValue()); + tmpByteArray.add(new Byte((byte)t.getTokenID())); + byte[] tempByte = EndianConverter.writeDouble(cellLong); + for(int byteIter=0;byteIter<tempByte.length;byteIter++) { + tmpByteArray.add(new Byte(tempByte[byteIter])); + } + return tmpByteArray; + } + + /** + * Converts a char to an int. It is zero based + * so a=0, b=1 etc. + * + * @param ch the character to be converted + * @return -1 if not a character otherwise a 0 based index + */ + private int char2int(char ch) { + if(!Character.isLetter(ch)) + return -1; + + ch = Character.toUpperCase(ch); + return ch-'A'; + } + + /** + * Identify letters + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isAlpha(char c) { + return(Character.isLetter(c)); + } + + /** + * Identify numbers + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isDigit(char c) { + return(Character.isDigit(c)); + } + + /** + * Identify letters or numbers + * + * @param c The character which is to be identified + * @return A boolean returning the result of the comparison + */ + private boolean isAlphaNum(char c) { + return(isAlpha(c) || isDigit(c)); + } + + /** + * Parses a column reference and returns it's integer equivalent. (eg. + * A=0, D=3, BA=27) + * + * @return an 0 based index to a column + */ + private int column() { + char ch = parseString.charAt(index); + String columnStr = new String(); + int col = 0; + + while(isAlpha(ch)) { + columnStr += ch; + index++; + ch = parseString.charAt(index); + } + + if(columnStr.length()==1) { + col = char2int(columnStr.charAt(0)); + } else if (columnStr.length()==2) { + col = char2int(columnStr.charAt(0)) + 1; + col = (col*26) + char2int(columnStr.charAt(1)); + } else { + Debug.log(Debug.ERROR, "Invalid Column Reference " + columnStr ); + } + + + return col; + } + + /** + * Parses a column reference and returns it's integer equivalent. (eg. + * A=0, D=3, BA=27) + * + * @return an 0 based index to a column + */ + private int row() { + char ch = parseString.charAt(index); + String rowStr = new String(); + int row = 0; + boolean status = true; + + do { + rowStr += ch; + index++; + if(index>=parseString.length()) { + status = false; + } else { + ch = parseString.charAt(index); + } + } while(isDigit(ch) && status); + return Integer.parseInt(rowStr)-1; // Pexcel uses a 0 based index + } + + /** + * A Cell Reference Encoder (It supports absolute and relative addressing) + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private byte[] encodeCellCoordinates(String cellCoordinates) { + int col = 0, row = 0; + int addressing = 0xC000; + + index = 0; + parseString = cellCoordinates; + Debug.log(Debug.TRACE,"Encoding cell coordinates " + cellCoordinates); + if(cellCoordinates.charAt(index)=='$') { + addressing &= 0x8000; + index++; + } + col = column(); + if(cellCoordinates.charAt(index)=='$') { + addressing &= 0x4000; + index++; + } + row = row(); // Pexcel uses a 0 based index + row |= addressing; + byte tokenBytes[] = new byte[3]; + tokenBytes[0] = (byte)row; + tokenBytes[1] = (byte)(row>>8); + tokenBytes[2] = (byte)col; + return tokenBytes; + } + + /** + * A name definition Encoder + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector nameDefinitionEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + + String nameString = t.getValue(); + Debug.log(Debug.TRACE,"NameDefinitionEncoder : " + nameString); + tmpByteArray.add(new Byte((byte)t.getTokenID())); + Enumeration e = wb.getDefinedNames(); + DefinedName dn; + String name; + int definedNameIndex = 0; + do { + dn = (DefinedName)e.nextElement(); + name = dn.getName(); + Debug.log(Debug.TRACE,"Name pulled from DefinedName : " + name); + definedNameIndex++; + } while(!nameString.equalsIgnoreCase(name) && e.hasMoreElements()); + + tmpByteArray.add(new Byte((byte)definedNameIndex)); + tmpByteArray.add(new Byte((byte)0x00)); + + for(int i = 0;i < 12;i++) { + tmpByteArray.add(new Byte((byte)0x00)); + } + + return tmpByteArray; + } + /** + * A Cell Reference Encoder. It supports absolute and relative addressing + * but not sheetnames. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector cellRefEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + + tmpByteArray.add(new Byte((byte)t.getTokenID())); + byte cellRefBytes[] = encodeCellCoordinates(t.getValue()); + for(int i = 0;i < cellRefBytes.length;i++) { + tmpByteArray.add(new Byte(cellRefBytes[i])); + } + return tmpByteArray; + } + + /** + * This function will find the sheetname index for a given String + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private short findSheetIndex(String s) { + + short sheetIndex = 0; + String savedName; + String sheetName; + if (s.startsWith("$")) { + sheetName = s.substring(1,s.length()); // Remove $ + } else { + sheetName = s.substring(0,s.length()); + } + Debug.log(Debug.TRACE,"Searching for Worksheet : " + sheetName); + Vector names = wb.getWorksheetNames(); + Enumeration e = names.elements(); + do { + savedName = (String) e.nextElement(); + sheetIndex++; + } while(!savedName.equalsIgnoreCase(sheetName) && e.hasMoreElements()); + + Debug.log(Debug.TRACE,"Setting sheetindex to " + sheetIndex); + return (short)(sheetIndex-1); + } + + /** + * A 3D Cell reference encoder + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector threeDCellRefEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + parseString = t.getValue(); + Debug.log(Debug.TRACE,"Encoding 3D Cell reference " + t); + tmpByteArray.add(new Byte((byte)t.getTokenID())); + tmpByteArray.add(new Byte((byte)0xFF)); + tmpByteArray.add(new Byte((byte)0xFF)); + for(int i = 0;i < 8;i++) { + tmpByteArray.add(new Byte((byte)0x00)); + } + + String sheetRef = parseString.substring(0, parseString.indexOf('.') + 1); + if (sheetRef.indexOf(':')!=-1) { + sheetRef = parseString.substring(0, parseString.indexOf(':')); + short sheetNum1 = findSheetIndex(sheetRef); + sheetRef = parseString.substring(parseString.indexOf(':') + 1, parseString.length()); + short sheetNum2 = findSheetIndex(sheetRef); + tmpByteArray.add(new Byte((byte)sheetNum1)); + tmpByteArray.add(new Byte((byte)0x00)); + tmpByteArray.add(new Byte((byte)sheetNum2)); + tmpByteArray.add(new Byte((byte)0x00)); + } else { + sheetRef = parseString.substring(0, parseString.indexOf('.')); + short sheetNum = findSheetIndex(sheetRef); + tmpByteArray.add(new Byte((byte)sheetNum)); + tmpByteArray.add(new Byte((byte)0x00)); + tmpByteArray.add(new Byte((byte)sheetNum)); + tmpByteArray.add(new Byte((byte)0x00)); + } + String s = parseString.substring(parseString.indexOf('.') + 1, parseString.length()); + Debug.log(Debug.TRACE,"Parsing : " + s); + byte cellRefBytes[] = encodeCellCoordinates(s); + for(int i = 0;i < cellRefBytes.length;i++) { + tmpByteArray.add(new Byte(cellRefBytes[i])); + } + return tmpByteArray; + } + /** + * A 3D Area Reference Encoder. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector threeDAreaRefEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + parseString = t.getValue(); + Debug.log(Debug.TRACE,"Encoding 3D Area reference " + t); + tmpByteArray.add(new Byte((byte)t.getTokenID())); + tmpByteArray.add(new Byte((byte)0xFF)); + tmpByteArray.add(new Byte((byte)0xFF)); + for(int i = 0;i < 8;i++) { + tmpByteArray.add(new Byte((byte)0x00)); + } + + String param1= parseString.substring(0, parseString.indexOf(':')); + String cellRef1 = param1.substring(parseString.indexOf('.') + 1, param1.length()); + String sheetRef1 = param1.substring(0, param1.indexOf('.')); + short sheetNum1 = findSheetIndex(sheetRef1); + + String param2 = parseString.substring(parseString.indexOf(':') + 1, parseString.length()); + Debug.log(Debug.TRACE,"param2: " + param2); + String cellRef2 = param2.substring(param2.indexOf('.') + 1, param2.length()); + Debug.log(Debug.TRACE,"cellRef2: " + cellRef2); + + if(param2.indexOf('.')==-1) { + tmpByteArray.add(new Byte((byte)sheetNum1)); + tmpByteArray.add(new Byte((byte)0x00)); + tmpByteArray.add(new Byte((byte)sheetNum1)); + tmpByteArray.add(new Byte((byte)0x00)); + } else { + String sheetRef2 = param2.substring(0, param2.indexOf('.')); + short sheetNum2 = findSheetIndex(sheetRef2); + tmpByteArray.add(new Byte((byte)sheetNum1)); + tmpByteArray.add(new Byte((byte)0x00)); + tmpByteArray.add(new Byte((byte)sheetNum2)); + tmpByteArray.add(new Byte((byte)0x00)); + } + + byte cellRefBytes1[] = encodeCellCoordinates(cellRef1); + byte cellRefBytes2[] = encodeCellCoordinates(cellRef2); + + tmpByteArray.add(new Byte(cellRefBytes1[0])); + tmpByteArray.add(new Byte(cellRefBytes1[1])); + + tmpByteArray.add(new Byte(cellRefBytes2[0])); + tmpByteArray.add(new Byte(cellRefBytes2[1])); + + tmpByteArray.add(new Byte(cellRefBytes1[2])); + tmpByteArray.add(new Byte(cellRefBytes2[2])); + + return tmpByteArray; + } + + /** + * A Cell Range Encoder. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector areaRefEncoder(Token t) { + + Vector tmpByteArray = new Vector(); + + tmpByteArray.add(new Byte((byte)t.getTokenID())); + String param = t.getValue(); + String cellRef1 = new String(); + String cellRef2 = new String(); + + if(param.indexOf(':')==-1) { + Debug.log(Debug.ERROR, "Invalid Cell Range, could not find :"); + } else { + cellRef1 = param.substring(0, param.indexOf(':')); + cellRef2 = param.substring(param.indexOf(':') + 1, param.length()); + } + byte cellRefBytes1[] = encodeCellCoordinates(cellRef1); + byte cellRefBytes2[] = encodeCellCoordinates(cellRef2); + + tmpByteArray.add(new Byte(cellRefBytes1[0])); + tmpByteArray.add(new Byte(cellRefBytes1[1])); + + tmpByteArray.add(new Byte(cellRefBytes2[0])); + tmpByteArray.add(new Byte(cellRefBytes2[1])); + + tmpByteArray.add(new Byte(cellRefBytes1[2])); + tmpByteArray.add(new Byte(cellRefBytes2[2])); + + return tmpByteArray; + } + + /** + * A Function Encoder. + * + * @param t <code>Token</code> to be encoded + * @return A <code>Vector</code> of pexcel <code>Byte</code> + */ + private Vector functionEncoder(Token t) { + Vector tmpByteArray = new Vector(); + + int id = t.getTokenID(); + if(t.getTokenType()==ParseToken.TOKEN_FUNCTION_VARIABLE) { + tmpByteArray.add(new Byte((byte)TokenConstants.TFUNCVAR)); + tmpByteArray.add(new Byte((byte)t.getNumArgs())); + } else { + tmpByteArray.add(new Byte((byte)TokenConstants.TFUNC)); + } + + tmpByteArray.add(new Byte((byte)id)); + tmpByteArray.add(new Byte((byte)(id>>8))); + return tmpByteArray; + } + + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenFactory.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenFactory.java new file mode 100644 index 000000000000..427b56383dfc --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/TokenFactory.java @@ -0,0 +1,126 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TokenFactory.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +import java.io.*; +import java.util.Vector; +import java.util.Enumeration; + +import org.openoffice.xmerge.util.Debug; + +/** + * This is the Factory class responsible for creating a <code>Token</code>. + * It has three methods for returning three different types of Tokens + * (Operator, Operand and Function). + * This utility class is used by either the <code>FormulaParser</code> or the + * <code>FormulaDecoder</code>. + */ +public class TokenFactory { + + private OperatorLookup operatorLookup; + private OperandLookup operandLookup; + private FunctionLookup fl; + + /** + * Default Constructor + */ + public TokenFactory() { + operatorLookup = new OperatorLookup(); + operandLookup = new OperandLookup(); + fl = new FunctionLookup(); + } + + /** + * The Factory method for creating function Tokens + * + * @return The created <code>Token</code> + */ + public Token getFunctionToken(String s, int args) { + Token t = null; + // We will have to fix this later to include fixed function tokens + // Also will need to handle errors where functions names are incorrect??? + Debug.log(Debug.TRACE,"TokenFactory creating function Token : " + s); + try { + t = new Token(s, ParseToken.TOKEN_FUNCTION_VARIABLE, fl.getIDFromString(s), args); + } catch (UnsupportedFunctionException eFn) { + + Debug.log(Debug.ERROR, eFn.getMessage()); + } + return t; + } + + /** + * The Factory method for creating operator Tokens + * + * @return The created <code>Token</code> + */ + public Token getOperatorToken(String s, int args) { + + Token t = null; + + Debug.log(Debug.TRACE,"TokenFactory creating operator Token : " + s); + try { + if(args==1) { + if(s.equals("+")) { + t = new Token(s, ParseToken.TOKEN_OPERATOR, operatorLookup.getIDFromString("UNARY_PLUS"), args); + } else if (s.equals("-")) { + t = new Token(s, ParseToken.TOKEN_OPERATOR, operatorLookup.getIDFromString("UNARY_MINUS"), args); + } else { + t = new Token(s, ParseToken.TOKEN_OPERATOR, operatorLookup.getIDFromString(s), args); + } + } else { + t = new Token(s, ParseToken.TOKEN_OPERATOR, operatorLookup.getIDFromString(s), args); + } + } catch (UnsupportedFunctionException eFn) { + Debug.log(Debug.ERROR, eFn.getMessage()); + } + return t; + } + + /** + * The Factory method for creating Operand Tokens + * + * @return The created <code>Token</code> + */ + public Token getOperandToken(String s, String type) { + Token t = null; + + Debug.log(Debug.TRACE,"TokenFactory creating operand (" + type + ") Token : " + s); + try { + t = new Token(s, ParseToken.TOKEN_OPERAND, operandLookup.getIDFromString(type), 0); + } catch (UnsupportedFunctionException eFn) { + Debug.log(Debug.ERROR, eFn.getMessage()); + } + + return t; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/UnsupportedFunctionException.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/UnsupportedFunctionException.java new file mode 100644 index 000000000000..6eeae73cb0b8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/UnsupportedFunctionException.java @@ -0,0 +1,44 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: UnsupportedFunctionException.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula; + +/* + * Exception thrown when a function specified in a calc formula has no equivalent in Pocket Excel + * + * @author : Mike Hayes + */ + +public class UnsupportedFunctionException extends Exception { + UnsupportedFunctionException(String message) { + super(message); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/build.xml new file mode 100644 index 000000000000..05865f52c740 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/build.xml @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxspr_formula" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxspr_formula"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/FormulaCompiler.java"/> + <include name="${package}/FormulaHelper.java"/> + <include name="${package}/FormulaParser.java"/> + <include name="${package}/FormulaParsingException.java"/> + <include name="${package}/FunctionLookup.java"/> + <include name="${package}/OperandLookup.java"/> + <include name="${package}/Operatorookup.java"/> + <include name="${package}/ParseToken.java"/> + <include name="${package}/PrecedenceTable.java"/> + <include name="${package}/SymbolLookup.java"/> + <include name="${package}/Token.java"/> + <include name="${package}/TokenConstants.java"/> + <include name="${package}/TokenDecoder.java"/> + <include name="${package}/TokenEncoder.java"/> + <include name="${package}/TokenFactory.java"/> + <include name="${package}/UnsupportedFunctionException.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/makefile.mk new file mode 100644 index 000000000000..47db7a258006 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcxs_pexcel +PRJ=../../../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/package.html new file mode 100644 index 000000000000..7e719f53bebe --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/formula/package.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + <title>org.openoffice.xmerge.converter.xml.sxc.pexcel.records.formula package</title> + +</head> + <body bgcolor="white"> + +<p> This package contains the classes necessary for converting pexcel formula +to and from StarCalc Formula.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/package.html new file mode 100644 index 000000000000..79188bf45310 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxc/pexcel/records/package.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + <title>org.openoffice.xmerge.converter.xml.sxc.pexcel.records package</title> + +</head> + <body bgcolor="white"> + +<p> This package contains the objects that represent BIFF Records for the +pocket excel format. Each one implements the BIFF Record abstract class which +contains three basic functions (read, write and getBiffType). BIFF Records +which are not used do not contain setter's or getter's for their member +variables as some records have a large number of variables. It should be up +to the implementer which attributes get set and which get set to default +values.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/SxwDocument.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/SxwDocument.java new file mode 100644 index 000000000000..4888357a6de2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/SxwDocument.java @@ -0,0 +1,98 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxwDocument.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw; + +import org.w3c.dom.Document; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * This class is an implementation of <code>OfficeDocument</code> for + * the SXW format. + */ +public class SxwDocument extends OfficeDocument { + + + /** + * Constructor with arguments to set <code>name</code>. + * + * @param name The name of the <code>Document</code> + */ + public SxwDocument(String name) { + super(name); + } + + + /** + * Constructor with arguments to set <code>name</code>, the + * <code>namespaceAware</code> flag, and the <code>validating</code> + * flag. + * + * @param name The name of the <code>Document</code>. + * @param namespaceAware The value of the namespaceAware flag. + * @param validating The value of the validating flag. + */ + public SxwDocument(String name, boolean namespaceAware, boolean validating) { + + super(name, namespaceAware, validating); + } + + + /** + * Returns the Office file extension for the SXW format. + * + * @return The Office file extension for the SXW format. + */ + protected String getFileExtension() { + return OfficeConstants.SXW_FILE_EXTENSION; + } + + + /** + * Returns the Office attribute for the SXW format. + * + * @return The Office attribute for the SXW format. + */ + protected String getOfficeClassAttribute() { + return OfficeConstants.SXW_TYPE; + } + + /** + * Method to return the MIME type of the document. + * + * @return String The document's MIME type. + */ + protected final String getDocumentMimeType() { + return OfficeConstants.SXW_MIME_TYPE; + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/SxwPluginFactory.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/SxwPluginFactory.java new file mode 100644 index 000000000000..06af85d94431 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/SxwPluginFactory.java @@ -0,0 +1,81 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SxwPluginFactory.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw; + +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.PluginFactory; +import org.openoffice.xmerge.PluginFactory; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.util.registry.ConverterInfo; + +/** + * General implementation of the <code>PluginFactory</code> interface + * for SXW documents. + * + * @see org.openoffice.xmerge.DocumentDeserializer + * @see org.openoffice.xmerge.DocumentMerger + * @see org.openoffice.xmerge.DocumentSerializer + */ +public abstract class SxwPluginFactory extends PluginFactory { + + /** + * Constructor that caches the <code>ConvertInfo</code> that + * corresponds to the registry information for this plug-in. + * + * @param ci <code>ConvertInfo</code> object. + */ + public SxwPluginFactory (ConverterInfo ci) { + super(ci); + } + + + public Document createOfficeDocument(String name, InputStream is) + throws IOException { + + // read zipped XML stream + SxwDocument doc = new SxwDocument(name); + doc.read(is); + return doc; + } + + public Document createOfficeDocument(String name, InputStream is,boolean isZip) + throws IOException { + + // read XML stream + SxwDocument doc = new SxwDocument(name); + doc.read(is,isZip); + return doc; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/ConverterCapabilitiesImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..852f8f6f4b49 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/ConverterCapabilitiesImpl.java @@ -0,0 +1,96 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterCapabilitiesImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * <p>AportisDoc implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxw.aportisdoc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarWriter XML to/from AportisDoc conversions. The + * <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_DOCUMENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_DOCUMENT_CONTENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_HEADING.equals(tag)) + return true; + else if (OfficeConstants.TAG_ORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_UNORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_ITEM.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_HEADER.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPAN.equals(tag)) + return true; + else if (OfficeConstants.TAG_HYPERLINK.equals(tag)) + return true; + else if (OfficeConstants.TAG_LINE_BREAK.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPACE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TAB_STOP.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_SPACE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_SPACE_COUNT.equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocConstants.java new file mode 100644 index 000000000000..6f097636a9ba --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocConstants.java @@ -0,0 +1,72 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocConstants.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import org.openoffice.xmerge.converter.palm.PdbUtil; + +/** + * Constants used for encoding and decoding the AportisDoc format. + * + * @author Herbie Ong + */ +interface DocConstants { + + /** Creator id. */ + public static final int CREATOR_ID = PdbUtil.intID("REAd"); + + /** Type id. */ + public static final int TYPE_ID = PdbUtil.intID("TEXt"); + + /** Constant for uncompressed version. */ + public static final short UNCOMPRESSED = 1; + + /** Constant for compressed version. */ + public static final short COMPRESSED = 2; + + /** Constant used for spare fields. */ + public static final int SPARE = 0; + + /** AportisDoc record size. */ + public static final short TEXT_RECORD_SIZE = 4096; + + /** Constant for encoding scheme. */ + public static final String ENCODING = "8859_1"; + + /** Constant for TAB character. */ + public final static char TAB_CHAR = '\t'; + + /** Constant for EOL character. */ + public final static char EOL_CHAR = '\n'; + + /** Constant for SPACE character. */ + public final static char SPACE_CHAR = ' '; +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocDecoder.java new file mode 100644 index 000000000000..f8631cccc78e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocDecoder.java @@ -0,0 +1,307 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocDecoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.ArrayList; + +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.util.Resources; +import org.openoffice.xmerge.util.Debug; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxw.DocumentDeserializerImpl} + * to decode the AportisDoc format. It currently decodes + * the text content into a single <code>String</code> object. + * + * @author Herbie Ong + */ +final class DocDecoder implements DocConstants { + + /** For decoding purposes. */ + private final static int COUNT_BITS = 3; + + /** Resources object for I18N. */ + private Resources res = null; + + + /** + * Default constructor creates a header and a text buffer + * for holding all the text in the AportisDoc database. + */ + DocDecoder() { + res = Resources.getInstance(); + } + + + /** + * Decode the text records into a single <code>String</code> + * of text content. + * + * @param Record <code>Record</code> array holding AportisDoc + * contents. + * + * @throws IOException If any I/O error occurs. + */ + String parseRecords(Record[] recs) throws IOException { + + // read the header record + HeaderInfo header = readHeader(recs[0].getBytes()); + + dumpHeader(header); + + // store all the characters in textBuffer + StringBuffer textBuffer = new StringBuffer(header.textLen); + + switch (header.version) { + + case COMPRESSED: + for (int i = 1; i <= header.textRecordCount; i++) { + + byte[] bytes = decompress(recs[i].getBytes(), + header.textRecordSize); + log("processing " + bytes.length + " bytes"); + String str = new String(bytes, ENCODING); + textBuffer.append(str); + } + + break; + + case UNCOMPRESSED: + for (int i = 1; i <= header.textRecordCount; i++) { + + byte[] bytes = recs[i].getBytes(); + log("processing " + bytes.length + " bytes"); + String str = new String(bytes, ENCODING); + textBuffer.append(str); + } + + break; + + default: + throw new IOException(res.getString("UNKNOWN_DOC_VERSION")); + + } + + return textBuffer.toString(); + } + + + /** + * <p>Decompress the <code>byte</code> array.</p> + * + * <p>The resulting uncompressed <code>byte</code> array should + * be within <code>textRecordSize</code> length, definitely + * within twice the size it claims, else treat it as a problem + * with the encoding of that PDB and throw + * <code>IOException</code>.</p> + * + * @param bytes Compressed <code>byte</code> array. + * @param textRecordSize Size of uncompressed + * <code>byte</code> array. + * + * @throws IOException If <code>textRecordSize</code> < + * <code>cBytes.length</code>. + */ + private byte[] decompress(byte[] cBytes, int textRecordSize) + throws IOException { + + // create byte array for storing uncompressed bytes + // it should be within textRecordSize range, definitely + // within twice of textRecordSize! if not, then + // an ArrayIndexOutOfBoundsException will get thrown, + // and it should be converted into an IOException, and + // treat it as a conversion error. + byte[] uBytes = new byte[textRecordSize*2]; + + int up = 0; + int cp = 0; + + try { + + while (cp < cBytes.length) { + + int c = cBytes[cp++] & 0xff; + + // codes 1...8 mean copy that many bytes + if (c > 0 && c < 9) { + + while (c-- > 0) + uBytes[up++] = cBytes[cp++]; + } + + // codes 0, 9...0x7F represent themselves + else if (c < 0x80) { + uBytes[up++] = (byte) c; + } + + // codes 0xC0...0xFF represent "space + ascii char" + else if (c >= 0xC0) { + uBytes[up++] = (byte) ' '; + uBytes[up++] = (byte) (c ^ 0x80); + } + + // codes 0x80...0xBf represent sequences + else { + c <<= 8; + c += cBytes[cp++] & 0xff; + int m = (c & 0x3fff) >> COUNT_BITS; + int n = c & ((1 << COUNT_BITS) - 1); + n += COUNT_BITS; + while (n-- > 0) { + uBytes[up] = uBytes[up - m]; + up++; + } + } + } + + } catch (ArrayIndexOutOfBoundsException e) { + + throw new IOException( + res.getString("DOC_TEXT_RECORD_SIZE_EXCEEDED")); + } + + // note that ubytes may be larger that the amount of + // uncompressed bytes, so trim it to another byte array + // with the exact size. + byte[] textBytes = new byte[up]; + System.arraycopy(uBytes, 0, textBytes, 0, up); + + return textBytes; + } + + + /** + * Read the header <code>byte</code> array. + * + * @param bytes <code>byte</code> array containing header + * record data. + * + * @return <code>HeaderInfo</code> object. + * + * @throws IOException If any I/O error occurs. + */ + private HeaderInfo readHeader(byte[] bytes) throws IOException { + + HeaderInfo header = new HeaderInfo(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + DataInputStream dis = new DataInputStream(bis); + + // Normally the first 2 bytes comprised of the version + // which should either be COMPRESSED or UNCOMPRESSED + // SmartDoc/Quickword would add a 0x01 to the first + // byte, thus their version would be 0x0101 for UNCOMPRESSED + // instead of 0x0001 and 0x0102 for UNCOMPRESSED instead of + // 0x0002. + + dis.readByte(); + header.version = dis.readByte(); + + // read extra 2 unused bytes + dis.readShort(); + + // Read the text length, this should be unsigned 4 bytes. + // We could store the read value into a long, but then + // our current buffer limit is the max positive of an int. + // That is a large enough limit, thus we shall stay with + // storing the value in an int. If it exceeds, then + // an IOException should be thrown. + header.textLen = dis.readInt(); + if (header.textLen < 0) { + throw new IOException(res.getString("DOC_TEXT_LENGTH_EXCEEDED")); + } + + // read the number of records - unsigned 2 bytes + header.textRecordCount = ((int) dis.readShort()) & 0x0000ffff; + + // read the record size - unsigned 2 bytes + header.textRecordSize = ((int) dis.readShort()) & 0x0000ffff; + + // read extra 4 unused bytes + dis.readInt(); + + return header; + } + + + /** + * Prints out header info into log. Used for debugging purposes only. + * + * @param header <code>HeaderInfo</code> structure. + */ + private void dumpHeader(HeaderInfo header) { + + log("<DOC_INFO "); + log("version=\"" + header.version + "\" "); + log("text-length=\"" + header.textLen + "\" "); + log("number-of-records=\"" + header.textRecordCount + "\" "); + log("record-size=\"" + header.textRecordSize + "\" />"); + } + + + /** + * Sends message to the log object. + * + * @param str Debug string message. + */ + private void log(String str) { + Debug.log(Debug.TRACE, str); + } + + + /** + * Inner class to store AportisDoc header information. + */ + private class HeaderInfo { + + /** length of text section */ + int textLen = 0; + + /** number of text records */ + int textRecordCount = 0; + + /** + * size of a text record. This is normally the same as + * TEXT_RECORD_SIZE, but some applications may modify this. + */ + int textRecordSize = 0; + + /** compression type */ + int version = 0; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocEncoder.java new file mode 100644 index 000000000000..cd08b9921a17 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocEncoder.java @@ -0,0 +1,217 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocEncoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.ArrayList; + +import org.openoffice.xmerge.converter.palm.Record; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxw.DocumentSerializerImpl + * DocumentSerializerImpl} to encode the AportisDoc format. + * It does not deal with any XML tags. It only knows how to encode + * from <code>String</code>. + * + * @author Herbie Ong + */ +final class DocEncoder implements DocConstants { + + /** Text buffer to contain text section. */ + private StringBuffer textBuffer = null; + + /** Length of text section. */ + private int textLen = 0; + + /** Number of text records. */ + private int textRecCount = 0; + + + /** + * Default constructor creates a header and + * a text buffer for holding all the text in + * the AportisDoc database. + */ + DocEncoder() { + + textBuffer = new StringBuffer(TEXT_RECORD_SIZE); + } + + + /** + * This method appends text into the text section of + * the AportisDoc database. + * + * @param text <code>String</code> to append. + */ + void addText(String text) { + + textBuffer.append(text); + } + + + /** + * This method appends text into the text section of + * the AportisDoc database. + * + * @param text <code>char</code> array to append. + */ + void addText(char[] text) { + + textBuffer.append(text); + } + + + /** + * This method appends text character into the text + * section of the AportisDoc database. + * + * @param text <code>char</code> to append. + */ + void addText(char text) { + + textBuffer.append(text); + } + + + /** + * This method encodes the information given to a + * palm <code>Record</code> array in the AportisDoc + * database format. + * + * @return <code>Record</code> array holding AportisDoc + * contents. + * + * @throws IOException If any I/O error occurs. + */ + Record[] getRecords() throws IOException { + + byte textBytes[] = processTextBuffer(); + textLen = textBytes.length; + textRecCount = (short) (textBytes.length / TEXT_RECORD_SIZE); + + // recBytes to hold a record of bytes at a time + byte recBytes[] = new byte[TEXT_RECORD_SIZE]; + int pos = 0; + + List textRecords = new ArrayList(textRecCount + 1); + + // split textBytes into chunks of Record objects + // and store in textRecords object. + for (int i = 0; i < textRecCount; i++) { + + System.arraycopy(textBytes, pos, recBytes, 0, recBytes.length); + pos += recBytes.length; + Record zRec = new Record(recBytes); + textRecords.add(zRec); + } + + // there's more if ... + + if (pos < textLen) { + + textRecCount++; + + recBytes = new byte[textLen - pos]; + System.arraycopy(textBytes, pos, recBytes, 0, recBytes.length); + Record rec = new Record(recBytes); + textRecords.add(rec); + } + + // construct the Record array and copy + // references from textRecords. + + Record[] allRecords = new Record[textRecords.size() + 1]; + + allRecords[0] = new Record(getHeaderBytes()); + + for (int i = 1; i < allRecords.length; i++) { + + allRecords[i] = (Record) textRecords.get(i-1); + } + + return allRecords; + } + + + /** + * This method converts the text buffer into a <code>byte</code> + * array with the proper encoding of the text section of the + * AportisDoc format. + * + * TODO: do compression. + * + * @return byte[] Converted <code>byte</code> array of text + * section. + * + * @throws IOException If any I/O error occurs. + */ + private byte[] processTextBuffer() throws IOException + { + String str = textBuffer.toString(); + byte bytes[] = str.getBytes(ENCODING); + + return bytes; + } + + + /** + * This method produces the <code>byte</code> array for the header. + * + * @return <code>byte</code> array containing header record data. + * + * @throws IOException If any I/O error occurs. + */ + private byte[] getHeaderBytes() throws IOException + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + + // TODO: for now, we shall use UNCOMPRESSED. + // later, we need to use COMPRESSED or a setting. + dos.writeShort(UNCOMPRESSED); + dos.writeShort(SPARE); + dos.writeInt(textLen); + dos.writeShort(textRecCount); + dos.writeShort(TEXT_RECORD_SIZE); + dos.writeInt(SPARE); + + byte[] bytes = bos.toByteArray(); + + return bytes; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentDeserializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentDeserializerImpl.java new file mode 100644 index 000000000000..a819f82c14c3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentDeserializerImpl.java @@ -0,0 +1,316 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentDeserializerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.Text; + +import java.io.IOException; +import java.util.Enumeration; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.PdbDecoder; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.Debug; + +/** + * <p>AportisDoc implementation of <code>DocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.aportisdoc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts an file in AportisDoc PDB format to StarOffice + * XML format.</p> + * + * <p>The <code>deserialize</code> method uses a <code>DocDecoder</code> + * to read the AportisDoc format into a <code>String</code> object, then + * it calls <code>buildDocument</code> to create a <code>SxwDocument</code> + * object from it.</p> + * + * @author Herbie Ong + */ +public final class DocumentDeserializerImpl + implements OfficeConstants, DocConstants, DocumentDeserializer { + + /** A <code>ConvertData</code> object assigned to this object. */ + private ConvertData cd = null; + + + /** + * Constructor that assigns the given <code>ConvertData</code> + * to this object as input. + * + * @param cd A <code>ConvertData</code> object to read data for + * the conversion process by the <code>deserialize</code> + * method. + */ + public DocumentDeserializerImpl(ConvertData cd) { + this.cd = cd; + } + + + /** + * Convert the given <code>ConvertData</code> object + * into a <code>SxwDocument</code> object. + * + * @return Resulting <code>SxwDocument</code> object. + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public Document deserialize() throws IOException, ConvertException { + + int numberOfPDBs = cd.getNumDocuments(); + Document doc = null; + int i=0; + ConvertData cdOut; + Enumeration e = cd.getDocumentEnumeration(); + while (e.hasMoreElements()) { + PalmDocument palmDoc = (PalmDocument) e.nextElement(); + PalmDB pdb = palmDoc.getPdb(); + + log("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + log("<AportisDoc>"); + + Record[] recs = pdb.getRecords(); + String docName = palmDoc.getName(); + DocDecoder decoder = new DocDecoder(); + String text = decoder.parseRecords(recs); + doc = buildDocument(docName, text); + + log("</AportisDoc>"); + } + + return doc; + } + + + /** + * Parses the text content of an AportisDoc format and build a + * <code>SxwDocument</code>. + * + * @param docName Name of <code>Document</code>. + * @param str Text content of AportisDoc format. + * + * @return Resulting <code>SxwDocument</code> object. + * + * @throws IOException If any I/O error occurs. + */ + private SxwDocument buildDocument(String docName, String str) + throws IOException { + + // create minimum office xml document. + SxwDocument sxwDoc = new SxwDocument(docName); + sxwDoc.initContentDOM(); + + org.w3c.dom.Document doc = sxwDoc.getContentDOM(); + + // Grab hold of the office:body tag, + // Assume there should be one. + // This is where top level paragraphs will append to. + NodeList list = doc.getElementsByTagName(TAG_OFFICE_BODY); + Node bodyNode = list.item(0); + + // Store all the text in a character array. + char[] text = str.toCharArray(); + + // startIndex has 2 purposes: + // if value is -1, it means that there are no text characters + // needed to be processed for a Text node. if value >= 0, it + // is the index of the starting position of a text section + // for a Text node. + int startIndex = -1; + + // Create a paragraph node to start with. + Element paraNode = doc.createElement(TAG_PARAGRAPH); + + log("<PARA>"); + + for (int i = 0; i < text.length; i++) { + + switch (text[i]) { + + case TAB_CHAR: + + // Check if there are text to be processed first. + if (startIndex >= 0) { + addTextNode(doc, paraNode, text, startIndex, i - 1); + startIndex = -1; + } + + // Then, add tab element. + Element tabNode = doc.createElement(TAG_TAB_STOP); + paraNode.appendChild(tabNode); + + log("<TAB/>"); + break; + + case EOL_CHAR: + + // Check if there are text to be processed first. + if (startIndex >= 0) { + addTextNode(doc, paraNode, text, startIndex, i - 1); + startIndex = -1; + } + + // Then, add the current paragraph to body. + bodyNode.appendChild(paraNode); + + // Create another paragraph element. + paraNode = doc.createElement(TAG_PARAGRAPH); + + log("</PARA>"); + log("<PARA>"); + break; + + case SPACE_CHAR: + + // count is the number of space chars from i + int count = 0; + + // Do a look ahead and count the number of space chars + while (text[i + 1 + count] == SPACE_CHAR) { + count++; + } + + // Need to build a space node ONLY if count is > 1. + + if (count > 0) { + + // Check if there are text to be processed first + if (startIndex >= 0) { + addTextNode(doc, paraNode, text, + startIndex, i); + startIndex = -1; + } + + // Then, create a space element + // with the proper attribute. + Element spaceNode = doc.createElement(TAG_SPACE); + spaceNode.setAttribute(ATTRIBUTE_SPACE_COUNT, + Integer.toString(count)); + + paraNode.appendChild(spaceNode); + + // reposition i to the last space character. + i += count; + + log("<SPACE count=\"" + count + "\" />"); + + } else { + + // If there are no chars for text node yet, + // consider this one. + if (startIndex < 0) { + + startIndex = i; + log("<TEXT>"); + } + } + + break; + + default: + + // If there are no chars for text node yet, + // this should be the start. + if (startIndex < 0) { + + startIndex = i; + log("<TEXT>"); + } + + break; + } + } + + int lastIndex = text.length - 1; + + // Check if there are text to be processed first. + + if (startIndex >= 0) { + addTextNode(doc, paraNode, text, startIndex, lastIndex); + } + + // Then, add the last paragraph element if it is not added yet. + if (text[lastIndex] != EOL_CHAR) { + bodyNode.appendChild(paraNode); + } + + log("</PARA>"); + + return sxwDoc; + } + + + /** + * Add a Text <code>Node</code> to the given paragraph node with the + * text starting at the given <code>startPos</code> until + * <code>endPos</code>. + * + * @param doc <code>org.w3c.dom.Document</code> object for creating + * <code>Node</code> objects. + * @param para The current paragraph <code>Node</code> to append + * text <code>Node</code>. + * @param text Array of characters containing text. + * @param startPos Starting index position for text value. + * @param endPos End index position for text value. + */ + private void addTextNode(org.w3c.dom.Document doc, Node para, char text[], + int startPos, int endPos) { + + String str = new String(text, startPos, endPos - startPos + 1); + Text textNode = doc.createTextNode(str); + para.appendChild(textNode); + log(str); + log("</TEXT>"); + } + + /** + * Sends message to the log object. + * + * @param str Debug message. + */ + private void log(String str) { + + Debug.log(Debug.TRACE, str); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentMergerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentMergerImpl.java new file mode 100644 index 000000000000..50fcfee02178 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentMergerImpl.java @@ -0,0 +1,102 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentMergerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.MergeException; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.Difference; +import org.openoffice.xmerge.merger.NodeMergeAlgorithm; +import org.openoffice.xmerge.merger.Iterator; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.diff.ParaNodeIterator; +import org.openoffice.xmerge.merger.diff.IteratorLCSAlgorithm; +import org.openoffice.xmerge.merger.merge.DocumentMerge; +import org.openoffice.xmerge.merger.merge.CharacterBaseParagraphMerge; +import org.openoffice.xmerge.util.Debug; + + +/** + * AportisDoc implementation of <code>DocumentMerger</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.aportisdoc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + */ +public class DocumentMergerImpl implements DocumentMerger { + + private ConverterCapabilities cc_; + private org.openoffice.xmerge.Document orig = null; + + public DocumentMergerImpl(org.openoffice.xmerge.Document doc, ConverterCapabilities cc) { + cc_ = cc; + this.orig = doc; + } + + public void merge(org.openoffice.xmerge.Document modifiedDoc) throws MergeException { + + SxwDocument wdoc1 = (SxwDocument) orig; + SxwDocument wdoc2 = (SxwDocument) modifiedDoc; + + Document doc1 = wdoc1.getContentDOM(); + Document doc2 = wdoc2.getContentDOM(); + + Iterator i1 = new ParaNodeIterator(cc_, doc1.getDocumentElement()); + Iterator i2 = new ParaNodeIterator(cc_, doc2.getDocumentElement()); + + DiffAlgorithm diffAlgo = new IteratorLCSAlgorithm(); + + // find out the paragrah level diffs + Difference[] diffTable = diffAlgo.computeDiffs(i1, i2); + + if (Debug.isFlagSet(Debug.INFO)) { + Debug.log(Debug.INFO, "Diff Result: "); + + for (int i = 0; i < diffTable.length; i++) { + Debug.log(Debug.INFO, diffTable[i].debug()); + } + } + + // merge the paragraphs + NodeMergeAlgorithm charMerge = new CharacterBaseParagraphMerge(); + DocumentMerge docMerge = new DocumentMerge(cc_, charMerge); + + Iterator result = null; + + docMerge.applyDifference(i1, i2, diffTable); + } +} + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentSerializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentSerializerImpl.java new file mode 100644 index 000000000000..75edfbd78d7f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/DocumentSerializerImpl.java @@ -0,0 +1,535 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentSerializerImpl.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import java.io.IOException; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.palm.PdbEncoder; +import org.openoffice.xmerge.converter.palm.PdbDecoder; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.XmlUtil; + +/** + * <p>AportisDoc implementation of + * org.openoffice.xmerge.DocumentSerializer + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.aportisdoc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>The <code>serialize</code> method traverses the DOM + * document from the given <code>Document</code> object. It uses a + * <code>DocEncoder</code> object for the actual conversion of + * contents to the AportisDoc format.</p> + * + * @author Herbie Ong + */ + + +public final class DocumentSerializerImpl + implements OfficeConstants, DocConstants, DocumentSerializer { + + /** A <code>DocEncoder</code> object for encoding to AportisDoc. */ + private DocEncoder encoder = null; + + /** SXW <code>Document</code> object that this converter processes. */ + private SxwDocument sxwDoc = null; + + + /** + * Constructor. + * + * @param doc A SXW <code>Document</code> to be converted. + */ + public DocumentSerializerImpl(Document doc) { + sxwDoc = (SxwDocument) doc; + } + + + /** + * <p>Method to convert a <code>Document</code> into a PDB. + * It passes back the converted data as a <code>ConvertData</code> + * object.</p> + * + * <p>This method is not thread safe for performance reasons. + * This method should not be called from within two threads. + * It would be best to call this method only once per object + * instance.</p> + * + * @return The <code>ConvertData</code> object containing the output. + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public ConvertData serialize() throws ConvertException, IOException { + + + // get the server document name + + String docName = sxwDoc.getName(); + + // get DOM document + + org.w3c.dom.Document domDoc = sxwDoc.getContentDOM(); + + encoder = new DocEncoder(); + + // Traverse to the office:body element. + // There should only be one. + + NodeList list = domDoc.getElementsByTagName(TAG_OFFICE_BODY); + int len = list.getLength(); + + if (len > 0) { + Node node = list.item(0); + traverseBody(node); + } + + // create a ConvertData object. + // + Record records[] = encoder.getRecords(); + ConvertData cd = new ConvertData(); + + PalmDocument palmDoc = new PalmDocument(docName, + DocConstants.CREATOR_ID, DocConstants.TYPE_ID, + 0, PalmDB.PDB_HEADER_ATTR_BACKUP, records); + + cd.addDocument(palmDoc); + return cd; + } + + + /** + * This method traverses <i>office:body</i> element. + * + * @param node <i>office:body</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseBody(Node node) throws IOException { + + log("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + log("<AportisDOC>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH) || + nodeName.equals(TAG_HEADING)) { + + traverseParagraph(child); + + } else if (nodeName.equals(TAG_UNORDERED_LIST)) { + + traverseList(child); + + } else if (nodeName.equals(TAG_ORDERED_LIST)) { + + traverseList(child); + + } else { + + log("<OTHERS " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + log("</AportisDOC>"); + } + + + /** + * This method traverses the <i>text:p</i> and <i>text:h</i> + * element <code>Node</code> objects. + * + * @param node A <i>text:p</i> or <i>text:h</i> + * <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseParagraph(Node node) throws IOException { + + log("<PARA>"); + traverseParaContents(node); + encoder.addText(EOL_CHAR); + log("</PARA>"); + } + + + /** + * This method traverses a paragraph content. + * It uses the <code>traverseParaElem</code> method to + * traverse into Element <code>Node</code> objects. + * + * @param node A paragraph or content <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseParaContents(Node node) throws IOException { + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + short nodeType = child.getNodeType(); + + switch (nodeType) { + + case Node.TEXT_NODE: + // this is for grabbing text nodes. + String s = child.getNodeValue(); + + if (s.length() > 0) { + encoder.addText(s); + } + + log("<TEXT>"); + log(s); + log("</TEXT>"); + + break; + + case Node.ELEMENT_NODE: + + traverseParaElem(child); + break; + + case Node.ENTITY_REFERENCE_NODE: + + log("<ENTITY_REFERENCE>"); + traverseParaContents(child); + log("<ENTITY_REFERENCE/>"); + break; + + default: + log("<OTHERS " + XmlUtil.getNodeInfo(node) + " />"); + } + } + } + } + + + /** + * This method traverses an <code>Element</code> <code>Node</code> + * within a paragraph. + * + * @param node <code>Element</code> <code>Node</code> within a + * paragraph. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseParaElem(Node node) throws IOException { + + String nodeName = node.getNodeName(); + + if (nodeName.equals(TAG_SPACE)) { + + // this is for text:s tags. + NamedNodeMap map = node.getAttributes(); + Node attr = map.getNamedItem(ATTRIBUTE_SPACE_COUNT); + StringBuffer space = new StringBuffer(SPACE_CHAR); + int count = 1; + + if (attr != null) { + + try { + + String countStr = attr.getNodeValue(); + count = Integer.parseInt(countStr.trim()); + + } catch (NumberFormatException e) { + + // TODO: for now, throw IOException. + // later, perhaps will have to throw + // some other conversion exception instead. + throw new IOException(e.getMessage()); + } + } + + for (int j = 0; j < count; j++) { + + space.append(SPACE_CHAR); + } + + encoder.addText(space.toString()); + + log("<SPACE count=\"" + count + "\" />"); + + } else if (nodeName.equals(TAG_TAB_STOP)) { + + // this is for text:tab-stop + encoder.addText(TAB_CHAR); + + log("<TAB/>"); + + } else if (nodeName.equals(TAG_LINE_BREAK)) { + + // commented out by Csaba: There is no point to convert a linebreak + // into a EOL, because it messes up the number of XML nodes and the + // merge won't work properly. Other solution would be to implement such + // nodemerger, which would be able to merge embedded tags in a paragraph + + // this is for text:line-break + // encoder.addText(EOL_CHAR); + + log("skipped <LINE-BREAK/>"); + + } else if (nodeName.equals(TAG_SPAN)) { + + // this is for text:span + log("<SPAN>"); + traverseParaContents(node); + log("</SPAN>"); + + } else if (nodeName.equals(TAG_HYPERLINK)) { + + // this is for text:a + log("<HYPERLINK>"); + traverseParaContents(node); + log("<HYPERLINK/>"); + + } else if (nodeName.equals(TAG_BOOKMARK) || + nodeName.equals(TAG_BOOKMARK_START)) { + + log("<BOOKMARK/>"); + + } else if (nodeName.equals(TAG_TEXT_VARIABLE_SET) + || nodeName.equals(TAG_TEXT_VARIABLE_GET) + || nodeName.equals(TAG_TEXT_EXPRESSION) + || nodeName.equals(TAG_TEXT_USER_FIELD_GET) + || nodeName.equals(TAG_TEXT_PAGE_VARIABLE_GET) + || nodeName.equals(TAG_TEXT_SEQUENCE) + || nodeName.equals( TAG_TEXT_VARIABLE_INPUT) + || nodeName.equals(TAG_TEXT_TIME) + || nodeName.equals( TAG_TEXT_PAGE_COUNT) + || nodeName.equals(TAG_TEXT_PAGE_NUMBER ) + || nodeName.equals(TAG_TEXT_SUBJECT) + || nodeName.equals(TAG_TEXT_TITLE) + || nodeName.equals(TAG_TEXT_CREATION_TIME) + || nodeName.equals(TAG_TEXT_DATE) + || nodeName.equals(TAG_TEXT_TEXT_INPUT) + || nodeName.equals(TAG_TEXT_AUTHOR_INITIALS)) { + log("<FIELD>"); + traverseParaContents(node); + log("</FIELD>"); + + }else if (nodeName.startsWith(TAG_TEXT)) { + log("<Unknown text Field>"); + traverseParaContents(node); + log("</Unknown text Field>"); + + }else { + + log("<OTHERS " + XmlUtil.getNodeInfo(node) + " />"); + } + } + + + /** + * This method traverses list tags <i>text:unordered-list</i> and + * <i>text:ordered-list</i>. A list can only contain one optional + * <i>text:list-header</i> and one or more <i>text:list-item</i> + * elements. + * + * @param node A list <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseList(Node node) throws IOException { + + log("<LIST>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_LIST_ITEM)) { + + traverseListItem(child); + + } else if (nodeName.equals(TAG_LIST_HEADER)) { + + traverseListHeader(child); + + } else { + + log("<INVALID-XML-BUG " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + log("</LIST>"); + } + + + /** + * This method traverses a <i>text:list-header</i> element. + * It contains one or more <i>text:p</i> elements. + * + * @param node A list header <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseListHeader(Node node) throws IOException { + + log("<LIST-HEADER>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH)) { + + traverseParagraph(child); + + } else { + + log("<INVALID-XML-BUG " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + log("</LIST-HEADER>"); + } + + + /** + * <p>This method will traverse a <i>text:list-item</i>. + * A list item may contain one or more of <i>text:p</i>, + * <i>text:h</i>, <i>text:section</i>, <i>text:ordered-list</i> + * and <i>text:unordered-list</i>.</p> + * + * <p>This method currently only implements grabbing <i>text:p</i>, + * <i>text:h</i>, <i>text:unordered-list</i> and + * <i>text:ordered-list</i>.</p> + * + * @param node The <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseListItem(Node node) throws IOException { + + log("<LIST-ITEM>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH)) { + + traverseParagraph(child); + + } else if (nodeName.equals(TAG_UNORDERED_LIST)) { + + traverseList(child); + + } else if (nodeName.equals(TAG_ORDERED_LIST)) { + + traverseList(child); + + } else { + + log("<INVALID-XML-BUG " + XmlUtil.getNodeInfo(child) + " />"); + } + } + } + } + + log("</LIST-ITEM>"); + } + + + /** + * Logs debug messages. + * + * @param str The debug message. + */ + private void log(String str) { + + Debug.log(Debug.TRACE, str); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/PluginFactoryImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/PluginFactoryImpl.java new file mode 100644 index 000000000000..3f6f9e26cd50 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/PluginFactoryImpl.java @@ -0,0 +1,144 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PluginFactoryImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.aportisdoc; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.DocumentMergerFactory; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxw.SxwPluginFactory; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.registry.ConverterInfo; +import java.io.IOException; +import java.io.InputStream; + +/** + * <p>AportisDoc implementation of the <code>PluginFactory</code>. + * This encapsulates conversion of StarWriter XML format to and from + * AportisDoc format.</p> + * + * <p>The superclass produces a particular + * {@link org.openoffice.xmerge.Document Document} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxw.SxwDocument + * SxwDocument} that the converters in this class works with. Thus, + * this class only implements the methods that produces the converters, + * i.e. {@link + * org.openoffice.xmerge.DocumentSerializer + * DocumentSerializer} and {@link + * org.openoffice.xmerge.DocumentDeserializer + * DocumentDeserializer}; + * as well as the {@link + * org.openoffice.xmerge.ConverterCapabilities + * ConverterCapabilities} object that is specific to this format + * conversion. That superclass also produces a {@link + * org.openoffice.xmerge.DocumentMerger DocumentMerger} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxw.aportisdoc.DocumentMergerImpl + * DocumentMergerImpl} which this class derives the functionality.</p> + * + * @author Herbie Ong + */ +public final class PluginFactoryImpl extends SxwPluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory, + DocumentMergerFactory { + + public PluginFactoryImpl (ConverterInfo ci) { + super(ci); + } + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + /** + * Returns an instance of <code>DocumentSerializerImpl</code>, + * which is an implementation of the <code>DocumentSerializer</code> + * interface. + * + * @param doc <code>Document</code> object to be + * converted/serialized. + * + * @return A <code>DocumentSerializerImpl</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + + return new DocumentSerializerImpl(doc); + } + + + /** + * Returns an instance of <code>DocumentDeserializerImpl</code>, + * which is an implementation of the <code>DocumentDeserializer</code> + * interface. + * + * @param cd <code>ConvertData</code> object for reading data + * which will be converted back to a + * <code>Document</code> object. + * + * @return A DocumentDeserializerImpl object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + + return new DocumentDeserializerImpl(cd); + } + + + /** + * Returns an instance of <code>DocumentMergerImpl</code>, + * which is an implementation of the <code>DocumentMerger</code> + * interface. + * + * @param doc <code>Document</code> to merge. + * + * @return A DocumentMergerImpl object. + */ + public DocumentMerger createDocumentMerger(Document doc) { + + ConverterCapabilities cc = converterCap; + DocumentMergerImpl merger = new DocumentMergerImpl(doc, cc); + return merger; + } + + public Document createDeviceDocument(String name, InputStream is) + throws IOException { + + PalmDocument palmDoc = new PalmDocument(is); + return palmDoc; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/build.xml new file mode 100644 index 000000000000..5b34dc29ad9d --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/build.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxs_aportisdoc" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxs_aportisdoc"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxw/aportisdoc"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/DocConstants.java"/> + <include name="${package}/DocDecoder.java"/> + <include name="${package}/DocEncoder.java"/> + <include name="${package}/DocumentDeserializerImpl.java"/> + <include name="${package}/DocumentSerializerImpl.java"/> + <include name="${package}/DocumentMergerImpl.java"/> + <include name="${package}/ConverterCapabilitiesImpl.java"/> + <include name="${package}/PluginFactoryImpl.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/converter.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/converter.xml new file mode 100644 index 000000000000..04ab76384dd0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/converter.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: converter.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<converters> + <converter type="staroffice/sxw" version="1.0"> + <converter-display-name> + AportisDoc + </converter-display-name> + <converter-description> + StarWriter XML to/from AportisDoc conversion + </converter-description> + <converter-vendor>OpenOffice.org</converter-vendor> + <converter-class-impl> + org.openoffice.xmerge.converter.xml.sxw.aportisdoc.PluginFactoryImpl + </converter-class-impl> + <converter-target type="application/x-aportisdoc" /> + </converter> +</converters> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/makefile.mk new file mode 100644 index 000000000000..efbf2869009b --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcxs_aportisdoc +PRJ=../../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/package.html new file mode 100644 index 000000000000..9d5d1bdc00cb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/aportisdoc/package.html @@ -0,0 +1,241 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxw.aportisdoc package</title> +</head> + +<body bgcolor="white"> + +<p>Provides the tools for doing the conversion of StarWriter XML to +and from AportisDoc format.</p> + +<p>It follows the {@link org.openoffice.xmerge} framework for the conversion process.</p> + +<p>Since it converts to/from a Palm application format, these converters +follow the <a href=../../../../converter/palm/package-summary.html#streamformat> +<code>PalmDB</code> stream format</a> for writing out to the Palm sync client or +reading in from the Palm sync client.</p> + +<p>Note that <code>PluginFactoryImpl</code> also provides a +<code>DocumentMerger</code> object, i.e. {@link org.openoffice.xmerge.converter.xml.sxw.aportisdoc.DocumentMergerImpl DocumentMergerImpl}. +This functionality was derived from its superclass +{@link org.openoffice.xmerge.converter.xml.sxw.SxwPluginFactory +SxwPluginFactory}.</p> + +<h2>AportisDoc pdb format - Doc</h2> + +<p>The AportisDoc pdb format is widely used by different Palm applications, +e.g. QuickWord, AportisDoc Reader, MiniWrite, etc. Note that some +of these applications put tweaks into the format. The converters will only +support the default AportisDoc format, plus some very minor tweaks to accommodate +other applications.</p> + +<p>The text content of the format is plain text, i.e. there are no styles +or structures. There is no notion of lists, list items, paragraphs, +headings, etc. The format does have support for bookmarks.</p> + +<p>For most Doc applications, the default character encoding supported is +the extended ASCII character set, i.e. ISO-8859-1. StarWriter XML is in +UTF-8 encoding scheme. Since UTF-8 encoding scheme covers more characters, +converting UTF-8 strings into extended ASCII would mean that there can be +possible loss of character mappings.</p> + +<p>Using JAXP, XML files can be parsed and read in as Java <code>String</code>s +which is in Unicode format, there is no loss of character mapping from UTF-8 +to Java Strings. There is possible loss of character mapping in +converting Java <code>String</code>s to ASCII bytes. Java characters that +cannot be represented in extended ASCII are converted into the ASCII +character '?' or x3F in hex digit via the <code>String.getBytes(encoding)</code> +API.</p> + +<h2>SXW to DOC Conversion</h2> + +<p>The <code>DocumentSerializerImpl</code> class implements the +<code>org.openoffice.xmerge.DocumentSerializer</code>. +This class specifically provides the conversion process from a given +<code>SxwDocument</code> object to DOC formatted records, which are +then passed back to the client via the <code>ConvertData</code> object.</p> + +<p>The following XML tags are handled. [Note that some may not be implemented yet.]</p> +<ul> +<li> + <p>Paragraphs <tt><text:p></tt> and Headings <tt><text:h></tt></p> + + <p>Heading elements are classified the same as paragraph + elements since both have the same possible elements inside. + Their main difference is that they refer to different types + of style information, which is outside of their element tags. + Since there are no styles on the DOC format, headings should + be treated the same way a paragraph is converted.</p> + + <p>For paragraph elements, convert and transfer text nodes + that are essential. Text nodes directly contained within paragraph + nodes are such. There are also a number of elements that + a paragraph element may contain. These are explained in their + own context.</p> + + <p>At the end of the paragraph, an EOL character is added by + the converter to provide a separation for each paragraph, + since the Doc format does not have a notion of a paragraph.</p> +</li> +<li> + <p>White spaces <tt><text:s></tt> and Tabs <tt><text:tab-stop></tt></p> + + <p>In SXW, normally 2 or more white-space characters are collapsed into + a single space character. In order to make sure that the document + content really contains those white-space characters, there are special + elements assigned to them.</p> + + <p>The space element specifies the number of spaces are in it. + Thus, converting it just means providing the specific number of spaces + that the element requires.</p> + + <p>There is also the tab-stop element. This is a bit tricky. In a + StarWriter document, tab-stops are specified by a column position. + A tab is not an exact number of space, but rather a specific column + positioning. Say, regular tab-stops are set at every 5th column. + At column 4, if I hit a tab, it goes to column 5. At column 1, hitting + a tab would put the cursor at column 5 as well. SmartDoc and AporticDoc + applications goes by columns for the ASCII tab character. The only problem + is that in StarWriter, one could specify a different tab-stop, but not + in most of these Doc applications, at least I have not seen one. + Solution for this is just to go with the converting to the ASCII tab + character and not do anything for different tab-stop positioning.</p> +</li> +<li> + <p>Line breaks <tt><text:line-break></tt></p> + + <p>To represent line breaks, it is simpliest to just put an ASCII LF + character. Note that the side effect of this is that an end of paragraph + also contains an ASCII LF character. Thus, for the DOC to SXW conversion, + line breaks are not distinguishable from specifying the end of a + paragraph.</p> +</li> +<li> + <p>Text spans <tt><text:span></tt></p> + + <p>Text spans contain text that have different style attributes + from the paragraphs'. Text spans can be embedded within another + text span. Since it is purely for style tagging, we only needed + to convert and transfer the text elements within these.</p> +</li> +<li> + <p>Hyperlinks <tt><text:a></tt> + + <p>Convert and transfer the text portion.</p> +</li> +<li> + <p>Bookmarks <tt><text:bookmark></tt> <tt><text:bookmark-start></tt> + <tt><text:bookmark-end></tt> [Not implemented yet]</p> + + <p>In SXW, bookmark elements are embedded inside paragraph elements. + Bookmarks can either mark a text position or a text range. <tt><text:bookmark></tt> + marks a position while the pair <tt><text:bookmark-start></tt> and + <tt><text:bookmark-end></tt></p> marks a text range. The DOC format only + supports bookmarking a text position. Thus, for the conversion, + <tt><text:bookmark></tt> and <tt><text:bookmark-start></tt> will both mark + a text position.</p> +</li> +<li> + <p>Change Tracking <tt><text:tracked-changes></tt> + <tt><text:change*></tt> [Not implemented yet]</p> + + <p>Change tracking elements are not supported yet on the current + OpenOffice XML filters, will have to watch out on this. The text + within these elements have to be interpreted properly during the + conversion process.</p> +</li> +<li> + <p>Lists <tt><text:unordered-list></tt> and + <tt><text:ordered-lists></tt></p> + + <p>A list can only contain one optional <tt><text:list-header></tt> + and one or more <tt><text:list-item></tt> elements.</p> + + <p>A <tt><text:list-header></tt> contains one or more paragraph + elements. Since there are no styles, the conversion process does not + do anything special for list headers, conversion for the paragraphs + within list headers are the same as explained above.</p> + + <p>A <tt><text:list-item></tt> may contain one or more of paragraphs, + headings, list, etc. Since the Doc format does not support any list + structure, there will not be any special handling for this element. + Conversion for elements within it shall be applied according to the + element type. Thus, lists with paragraphs within it will result in just + plain paragraphs. Sublists will not be identifiable. Paragraphs in + sublists will still appear.</p> +</li> +<li> + <p><tt><text:section></tt></p> + + <p>I am not sure what this is yet, will need to investigate more on this.</p> +</li> +</ul> +<p>There may be other tags that will still need to be addressed for this conversion.</p> + +<p>Refer to {@link org.openoffice.xmerge.converter.xml.sxw.aportisdoc.DocumentSerializerImpl DocumentSerializerImpl} +for details of implementation. It uses <code>DocEncoder</code> class to do the encoding +part.</p> + +<h2>DOC to SXW Conversion</h2> + +<p>The <code>DocumentDeserializerImpl</code> class implements the +<code>org.openoffice.xmerge.DocumentDeserializer</code>. It is +passed the device document in the form of a <code>ConvertData</code> object. +It will then create a <code>SxwDocument</code> object from the conversion of +the DOC formatted records.</p> + +<p>The text content of the Doc format will be transferred as text. Paragraph +elements will be formed based on the existence of an ASCII LF character. There +will be at least one paragraph element.</p> + +<p>Bookmarks in the Doc format will be converted to the bookmark element +<tt><text:bookmark></tt> [Not implemented yet].</p> + + +<h2>Merging changes</h2> + +<p>As mentioned above, the <code>DocumentMerger</code> object produced by +<code>PluginFactoryImpl</code> is <code>DocumentMergerImpl</code>. +Refer to the javadocs for that package/class on its merging specifications. +</p> + +<h2>TODO list</h2> + +<p><ol> +<li>Investigate Palm's with different character encodings.</li> +<li>Investigate other StarWriter XML tags</li> +</ol></p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/build.xml new file mode 100644 index 000000000000..4a1c7fba5dca --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/build.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcx_sxw" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcx_sxw"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxw"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/SxwDocument.java"/> + <include name="${package}/SxwPluginFactory.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/makefile.mk new file mode 100644 index 000000000000..03db799f178c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcx_sxw +PRJ=../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/package.html new file mode 100644 index 000000000000..47a7e940fc36 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/package.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxw package</title> +</head> + +<body bgcolor="white"> +<p>Provides base implementation of StarWriter XML conversion to and from +different "Device" <code>Document</code> formats.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/ConverterCapabilitiesImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..bc57ccc776ea --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/ConverterCapabilitiesImpl.java @@ -0,0 +1,96 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterCapabilitiesImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * <p>PocketWord implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxw.pocketword.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarWriter XML to/from PocketWord conversions. The + * <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_DOCUMENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_DOCUMENT_CONTENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_HEADING.equals(tag)) + return true; + else if (OfficeConstants.TAG_ORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_UNORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_ITEM.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_HEADER.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPAN.equals(tag)) + return true; + else if (OfficeConstants.TAG_HYPERLINK.equals(tag)) + return true; + else if (OfficeConstants.TAG_LINE_BREAK.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPACE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TAB_STOP.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_SPACE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_SPACE_COUNT.equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentDescriptor.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentDescriptor.java new file mode 100644 index 000000000000..312762308df1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentDescriptor.java @@ -0,0 +1,239 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentDescriptor.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.openoffice.xmerge.util.EndianConverter; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.IOException; + +import java.util.Vector; + + +/** + * This class to represent the data structure stored by a Pocket Word file that + * describes that file. + * + * The data structure is of variable length, beginning at the end of the + * font declarations and ending 10 bytes before the first instance of 0xFF 0xFF + * marking a paragraph block. + * + * The variable length component arises from an 8 byte structure describing each + * paragraph in the document. These paragraph descriptors appear at the end + * of the Document Descriptor. + * + * @author Mark Murnane + * @version 1.1 + */ +class DocumentDescriptor { + private short numParagraphs = 0; + private short length = 0; + private short numLines = 0; + + private Vector paragraphDesc = null; + + DocumentDescriptor() { + paragraphDesc = new Vector(0, 1); + } + + + + /** + * Updates the <code>DocumentDescriptor</code> to include details of another + * paragraph in the document. + * + * @param len The number of characters in the paragraph. + * @param lines The number of lines on screen that the paragraph uses. + */ + public void addParagraph(short len, short lines) { + ParagraphDescriptor pd = new ParagraphDescriptor(len, lines); + + paragraphDesc.add(pd); + numParagraphs++; + numLines += lines; + length += pd.length; + } + + + /** + * Retrieve the <code>DocumentDescriptor's</code> data. Due to the variable + * length nature of the descriptor, certain fields can only be + * calculated/written after the addition of all paragraphs. + * + * @return Byte array containing the Pocket Word representation of this + * <code>DocumentDescriptor</code>. + */ + public byte[] getDescriptor () { + ByteArrayOutputStream descStream = new ByteArrayOutputStream(); + + writeHeader(descStream); + + /* + * This value seems to increment by 0x02 for each paragraph. + * For a single paragraph doc, the value is 0x08, 0x0A for two, + * 0x0C for three ... + */ + try { + descStream.write(EndianConverter.writeShort((short)(6 + + (numParagraphs * 2)))); + + descStream.write(EndianConverter.writeShort(numParagraphs)); + descStream.write(EndianConverter.writeShort((short)0)); + descStream.write(EndianConverter.writeShort(numParagraphs)); + + descStream.write(EndianConverter.writeShort((short)0)); + descStream.write(EndianConverter.writeShort((short)length)); + descStream.write(EndianConverter.writeShort((short)0)); + + descStream.write(EndianConverter.writeShort(numLines)); + descStream.write(new byte[] { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } ); + + for (int i = 0; i < paragraphDesc.size(); i++) { + ParagraphDescriptor pd = (ParagraphDescriptor)paragraphDesc.elementAt(i); + + descStream.write(pd.getDescriptor()); + } + + // Byte sequence marking the end of this DocumentDescriptor + descStream.write(EndianConverter.writeShort((short)0)); + descStream.write(EndianConverter.writeShort((short)0x41)); + } + catch (IOException ioe) { + // Should never happen as this is a memory based stream. + } + + return descStream.toByteArray(); + } + + + /* + * This method loads the intial fixed portion of the descriptor and the + * mid-section. The mid-section is variable but Pocket Word doesn't seem + * to mind default values. + */ + private void writeHeader(OutputStream descStream) { + + try { + descStream.write(new byte[] { 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x06, 0x00, + 0x15, 0x00, 0x10, 0x00, + 0x01, 0x00, (byte)0xD0, 0x2F, + 0x00, 0x00, (byte)0xE0, 0x3D, + 0x00, 0x00, (byte)0xF0, 0x00, + 0x00, 0x00, (byte)0xA0, 0x05, + 0x00, 0x00, (byte)0xA0, 0x05, + 0x00, 0x00, (byte)0xA0, 0x05, + 0x00, 0x00, (byte)0xA0, 0x05, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, + 0x07, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x04, 0x00, 0x00 } ); + + /* + * The next four bytes are variable, but a pattern hasn't yet been + * established. Pocket Word seems to accept this constant value. + * + * The bytes are repeated after another 12 byte sequence which does + * not seem to change from one file to the next. + */ + descStream.write(new byte[] { (byte)0xE2, 0x02, 0x00, 0x00 } ); + descStream.write(new byte[] { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x04, 0x00, 0x00 } ); + descStream.write(new byte[] { (byte)0xE2, 0x02, 0x00, 0x00 } ); + + descStream.write(new byte[] { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x08, 0x00 } ); + } + catch (IOException ioe) { + /* Shouldn't happen with a ByteArrayOutputStream */ + } + } + + + /** + * <code>ParagraphDescriptor</code> represents the data structure used to + * describe individual paragraphs within a <code>DocumentDescriptor.</code> + * + * It is used solely by the <code>DocumentDescriptor<code> class. + */ + private class ParagraphDescriptor { + private short filler = 0; + private short lines = 0; + private short length = 0; + private short unknown = 0x23; + + public ParagraphDescriptor(short len, short numLines) { + lines = numLines; + length = (short)(len + 1); + } + + public byte[] getDescriptor() { + ByteArrayOutputStream desc = new ByteArrayOutputStream(); + + try { + desc.write(EndianConverter.writeShort(filler)); + desc.write(EndianConverter.writeShort(lines)); + desc.write(EndianConverter.writeShort(length)); + desc.write(EndianConverter.writeShort(unknown)); + } + catch (IOException ioe) { + /* Should never happen */ + } + + return desc.toByteArray(); + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentDeserializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentDeserializerImpl.java new file mode 100644 index 000000000000..0378006661c1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentDeserializerImpl.java @@ -0,0 +1,301 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentDeserializerImpl.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentDeserializer; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; + +import org.openoffice.xmerge.converter.xml.ParaStyle; +import org.openoffice.xmerge.converter.xml.TextStyle; +import org.openoffice.xmerge.converter.xml.StyleCatalog; + +import org.openoffice.xmerge.util.OfficeUtil; + +import java.io.InputStream; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.FileDescriptor; + +import java.util.Enumeration; +import java.util.Vector; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; + + +/** + * <p>Pocket Word implementation of <code>DocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.pocketword.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts a Pocket Word file to an OpenOffice Writer XML DOM.</p> + * + * @author Mark Murnane + * @version 1.1 + */ +public final class DocumentDeserializerImpl + implements DocumentDeserializer, OfficeConstants { + + private PocketWordDocument pswDoc = null; + private SxwDocument sxwDoc = null; + private String docName; + + private StyleCatalog styleCat = null; + + + /** + * Initialises a new <code>DocumentDeserializerImpl</code> using the + * supplied <code>ConvertData</code>.</p> + * + * <p>The <code>Document</code> objects in the <code>ConvertData</code> + * should be {@link + * org.openoffice.xmerge.converter.xml.sxw.pocketword.PocketWordDocument + * PocketWordDocument} objects.</p> + * + * @param cd ConvertData containing a <code>PocketWordDocument</code> + * for conversion. + */ + public DocumentDeserializerImpl(ConvertData cd) { + Enumeration e = cd.getDocumentEnumeration(); + + // A Pocket Word file is composed of one binary file + while (e.hasMoreElements()) { + pswDoc = (PocketWordDocument)e.nextElement(); + } + + docName = pswDoc.getName(); + } + + + /** + * <p>Convert the data passed into the <code>DocumentDeserializer</code> + * constructor into the OpenOffice Writer <code>Document</code> + * format.</p> + * + * <p>This method may or may not be thread-safe. It is expected + * that the user code does not call this method in more than one + * thread. And for most cases, this method is only done once.</p> + * + * @return The resulting <code>Document</code> object from conversion. + * + * @throws ConvertException If any Convert error occurs. + * @throws IOException If any I/O error occurs. + */ + public Document deserialize() throws IOException, ConvertException { + Enumeration pe = pswDoc.getParagraphEnumeration(); + + sxwDoc = new SxwDocument (docName); + sxwDoc.initContentDOM(); + + // Default to an initial 5 entries in the catalog. + styleCat = new StyleCatalog(5); + + try { + buildDocument(pe); + } + catch (Exception e) { + e.printStackTrace(); + throw new ConvertException("Error building OpenOffice Writer DOM: " + + e.toString()); + + } + + return sxwDoc; + } + + + /** + * This method actually takes care of the conversion. + * + * @param data An Enumeration of all Paragraphs in the Pocket Word doc. + * + * @return The OpenOffice Writer XML representation of the data. + * + * @throws IOException If any I/O errors occur. + */ + private void buildDocument(Enumeration data) throws IOException { + + org.w3c.dom.Document doc = sxwDoc.getContentDOM(); + + /* + * There should be only one each of office:body and + * office:automatic-styles in each document. + */ + Node bodyNode = doc.getElementsByTagName(TAG_OFFICE_BODY).item(0); + + // Not every document has an automatic style tag + Node autoStylesNode = doc.getElementsByTagName( + TAG_OFFICE_AUTOMATIC_STYLES).item(0); + if (autoStylesNode == null) { + autoStylesNode = doc.createElement(TAG_OFFICE_AUTOMATIC_STYLES); + doc.insertBefore(autoStylesNode, bodyNode); + } + + + // Needed for naming new styles + int paraStyles = 1; + int textStyles = 1; + + // Pocket Word has no concept of a list. + Element listNode = null; + + + // Down to business ... + while (data.hasMoreElements()) { + Paragraph p = (Paragraph)data.nextElement(); + Element paraNode = doc.createElement(TAG_PARAGRAPH); + + // Set paragraph style information here + ParaStyle pStyle = p.makeStyle(); + if (pStyle == null) { + paraNode.setAttribute(ATTRIBUTE_TEXT_STYLE_NAME, + PocketWordConstants.DEFAULT_STYLE); + } + else { + // Create paragraph style + pStyle.setName(new String("PS" + paraStyles++)); + paraNode.setAttribute(ATTRIBUTE_TEXT_STYLE_NAME, pStyle.getName()); + styleCat.add(pStyle); + } + + + /* + * For each of the paragraphs, process each segment. + * There will always be at least one. + */ + Enumeration paraData = p.getSegmentsEnumerator(); + Vector textSpans = new Vector(0, 1); + + do { + ParagraphTextSegment pts = (ParagraphTextSegment)paraData.nextElement(); + Element span = doc.createElement(OfficeConstants.TAG_SPAN); + + TextStyle ts = pts.getStyle(); + + if (ts != null) { + ts.setName(new String("TS" + textStyles++)); + span.setAttribute(ATTRIBUTE_TEXT_STYLE_NAME, ts.getName()); + styleCat.add(ts); + } + else { + span.setAttribute(ATTRIBUTE_TEXT_STYLE_NAME, + PocketWordConstants.DEFAULT_STYLE); + } + + // If this isn't a blank paragraph + if (pts.getText() != null && !pts.getText().equals("")) { + Node[] children = OfficeUtil.parseText(pts.getText(), doc); + + for (int j = 0; j < children.length; j++) { + span.appendChild(children[j]); + } + } + + textSpans.add(span); + + } while (paraData.hasMoreElements()); + + + /* + * Special case for the first span. If it has no style, then + * it shouldn't be a span, so just add its children with style + * set as standard. + */ + Element firstSpan = (Element)textSpans.elementAt(0); + String styleName = firstSpan.getAttribute(ATTRIBUTE_TEXT_STYLE_NAME); + if (styleName.equals(PocketWordConstants.DEFAULT_STYLE)) { + NodeList nl = firstSpan.getChildNodes(); + int len = nl.getLength(); + + for (int i = 0; i < len; i++) { + /* + * Always take item 0 as the DOM tree event model will + * cause the NodeList to shrink as each Node is reparented. + * + * By taking the first item from the list, we essentially + * traverse the list in order. + */ + paraNode.appendChild(nl.item(0)); + } + } + else { + paraNode.appendChild(firstSpan); + } + + // The rest are spans, so just add them + for (int i = 1; i < textSpans.size(); i++) { + paraNode.appendChild((Node)textSpans.elementAt(i)); + } + + + /* + * Pocket Word doesn't support lists, but it does have bulleted + * paragraphs that are essentially the same thing. + * + * Unlike OpenOffice Writer, a blank paragraph can be bulleted + * as well. This will be handled by inserting a blank paragraph + * into the unordered list, but OpenOffice Writer will not display + * an item at that point in the list. + */ + if (p.isBulleted()) { + if (listNode == null) { + listNode = doc.createElement(TAG_UNORDERED_LIST); + } + Element listItem = doc.createElement(TAG_LIST_ITEM); + listItem.appendChild(paraNode); + listNode.appendChild(listItem); + } + else { + if (listNode != null) { + bodyNode.appendChild(listNode); + listNode = null; + } + bodyNode.appendChild(paraNode); + } + } // End processing paragraphs + + + // Now write the style catalog to the document + NodeList nl = styleCat.writeNode(doc, "dummy").getChildNodes(); + int nlLen = nl.getLength(); // nl.item reduces the length + for (int i = 0; i < nlLen; i++) { + autoStylesNode.appendChild(nl.item(0)); + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentMergerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentMergerImpl.java new file mode 100644 index 000000000000..ae087d65b6a2 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentMergerImpl.java @@ -0,0 +1,102 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentMergerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.MergeException; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.Difference; +import org.openoffice.xmerge.merger.NodeMergeAlgorithm; +import org.openoffice.xmerge.merger.Iterator; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.diff.ParaNodeIterator; +import org.openoffice.xmerge.merger.diff.IteratorLCSAlgorithm; +import org.openoffice.xmerge.merger.merge.DocumentMerge; +import org.openoffice.xmerge.merger.merge.CharacterBaseParagraphMerge; +import org.openoffice.xmerge.util.Debug; + + +/** + * PocketWord implementation of <code>DocumentMerger</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.pocketword.PluginFactoryImpl + * PluginFactoryImpl}.</p> + */ +public class DocumentMergerImpl implements DocumentMerger { + + private ConverterCapabilities cc_; + private org.openoffice.xmerge.Document orig = null; + + public DocumentMergerImpl(org.openoffice.xmerge.Document doc, ConverterCapabilities cc) { + cc_ = cc; + this.orig = doc; + } + + public void merge(org.openoffice.xmerge.Document modifiedDoc) throws MergeException { + + SxwDocument wdoc1 = (SxwDocument) orig; + SxwDocument wdoc2 = (SxwDocument) modifiedDoc; + + Document doc1 = wdoc1.getContentDOM(); + Document doc2 = wdoc2.getContentDOM(); + + Iterator i1 = new ParaNodeIterator(cc_, doc1.getDocumentElement()); + Iterator i2 = new ParaNodeIterator(cc_, doc2.getDocumentElement()); + + DiffAlgorithm diffAlgo = new IteratorLCSAlgorithm(); + + // find out the paragrah level diffs + Difference[] diffTable = diffAlgo.computeDiffs(i1, i2); + + if (Debug.isFlagSet(Debug.INFO)) { + Debug.log(Debug.INFO, "Diff Result: "); + + for (int i = 0; i < diffTable.length; i++) { + Debug.log(Debug.INFO, diffTable[i].debug()); + } + } + + // merge the paragraphs + NodeMergeAlgorithm charMerge = new CharacterBaseParagraphMerge(); + DocumentMerge docMerge = new DocumentMerge(cc_, charMerge); + + Iterator result = null; + + docMerge.applyDifference(i1, i2, diffTable); + } +} + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentSerializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentSerializerImpl.java new file mode 100644 index 000000000000..2a715a7871cd --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/DocumentSerializerImpl.java @@ -0,0 +1,440 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentSerializerImpl.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentSerializer; + +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; + +import org.openoffice.xmerge.converter.xml.ParaStyle; +import org.openoffice.xmerge.converter.xml.TextStyle; +import org.openoffice.xmerge.converter.xml.StyleCatalog; + +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + + +/** + * <p>Pocket Word implementation of <code>DocumentDeserializer</code> + * for use by {@link + * org.openoffice.xmerge.converter.xml.sxw.pocketword.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts an OpenOffice Writer XML files to a Pocket Word file<.</p> + * + * @author Mark Murnane + * @version 1.1 + */ +public final class DocumentSerializerImpl + implements DocumentSerializer, OfficeConstants { + + private PocketWordDocument pswDoc; + private SxwDocument sxwDoc; + + private StyleCatalog styleCat = null; + + private boolean inList = false; + + + /** + * <p>Initialises a new <code>DocumentSerializerImpl</code> using the.<br> + * supplied <code>Document</code></p> + * + * <p>The supplied document should be an {@link + * org.openoffice.xmerge.converter.xml.sxw.SxwDocument SxwDocument} + * object.</p> + * + * @param document The <code>Document</code> to convert. + */ + public DocumentSerializerImpl(Document doc) { + sxwDoc = (SxwDocument)doc; + pswDoc = new PocketWordDocument(sxwDoc.getName()); + } + + + /** + * <p>Convert the data passed into the <code>DocumentSerializerImpl</code> + * constructor into Pocket Word format.</p> + * + * <p>This method may or may not be thread-safe. It is expected + * that the user code does not call this method in more than one + * thread. And for most cases, this method is only done once.</p> + * + * @return <code>ConvertData</code> object to pass back the + * converted data. + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public ConvertData serialize() throws IOException, ConvertException { + ConvertData cd = new ConvertData(); + + org.w3c.dom.Document doc = sxwDoc.getContentDOM(); + + // Load any style info before traversing the document content tree + loadStyles(); + + NodeList list = doc.getElementsByTagName(TAG_OFFICE_BODY); + + int len = list.getLength(); + if (len > 0) { + Node node = list.item(0); + traverseBody(node); + } + + cd.addDocument(pswDoc); + + return cd; + } + + + /* + * Handles the loading of defined styles from the style.xml file as well + * as automatic styles from the content.xml file. + * + * Any change to a defined style, such as a short bold section, falls into + * the latter category. + */ + private void loadStyles() { + org.w3c.dom.Document contentDom = sxwDoc.getContentDOM(); + org.w3c.dom.Document styleDom = sxwDoc.getStyleDOM(); + + styleCat = new StyleCatalog(25); + + NodeList nl = null; + String families[] = new String[] { PocketWordConstants.TEXT_STYLE_FAMILY, + PocketWordConstants.PARAGRAPH_STYLE_FAMILY, + PocketWordConstants.PARAGRAPH_STYLE_FAMILY }; + Class classes[] = new Class[] { TextStyle.class, + ParaStyle.class, + TextStyle.class }; + + String[] styleTypes = new String[] { TAG_OFFICE_STYLES, + TAG_OFFICE_AUTOMATIC_STYLES, + TAG_OFFICE_MASTER_STYLES }; + + /* + * Documents converted from PSW -> SXW will not have a style.xml when + * being converted back to PSW. This would occur if a document was + * not modified within Writer between conversions. + * + * Any Writer modifications and saves create the style.xml and other + * portions of a complete Writer SXW file. + */ + if (styleDom != null) { + // Process the Style XML tree + for (int i = 0; i < styleTypes.length; i++ ) { + nl = styleDom.getElementsByTagName(styleTypes[i]); + if (nl.getLength() != 0) { + styleCat.add(nl.item(0), families, classes, null, false); + } + } + } + + /* + * Process the content XML for any other style info. + * Should only be automatic types here. + */ + for (int i = 0; i < styleTypes.length; i++ ) { + nl = contentDom.getElementsByTagName(styleTypes[i]); + if (nl.getLength() != 0) { + styleCat.add(nl.item(0), families, classes, null, false); + } + } + } + + + /* + * Process the office:body tag. + */ + private void traverseBody(Node node) throws IOException, ConvertException { + + if (node.hasChildNodes()) { + NodeList nList = node.getChildNodes(); + int len = nList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH) + || nodeName.equals(TAG_HEADING)) { + traverseParagraph(child); + } + + if (nodeName.equals(TAG_UNORDERED_LIST) || + nodeName.equals(TAG_ORDERED_LIST)) { + traverseList(child); + } + } + } + } + } + + + /* + * Process a text:p tag + */ + private void traverseParagraph(Node node) throws IOException, ConvertException { + String styleName = getAttribute(node, ATTRIBUTE_TEXT_STYLE_NAME); + + ParaStyle pstyle = (ParaStyle)styleCat.lookup(styleName, + PocketWordConstants.PARAGRAPH_STYLE_FAMILY, null, + ParaStyle.class); + if (pstyle != null) { + pstyle = (ParaStyle)pstyle.getResolved(); + } + + TextStyle tstyle = (TextStyle)styleCat.lookup(styleName, + PocketWordConstants.PARAGRAPH_STYLE_FAMILY, null, + TextStyle.class); + if (pstyle != null) { + tstyle = (TextStyle)tstyle.getResolved(); + } + + try { + pswDoc.addParagraph(pstyle, inList); + } + catch (Exception e) { + throw new ConvertException( + "Error adding paragraph to PocketWordDocument.\n" + + e.toString()); + } + + traverseParagraphContents(node, tstyle); + } + + + /* + * Process the contents of a paragraph. This method handles situations + * where the paragraph contains multiple children, each representing a + * differently formatted piece of text. + */ + private void traverseParagraphContents (Node node, TextStyle defTextStyle) + throws IOException, ConvertException { + // First up, get the style of this little bit + String styleName = getAttribute(node, ATTRIBUTE_TEXT_STYLE_NAME); + TextStyle tStyle = (TextStyle)styleCat.lookup(styleName, + PocketWordConstants.TEXT_STYLE_FAMILY, null, + TextStyle.class); + + if (tStyle == null) { + tStyle = defTextStyle; + } + + if (node.hasChildNodes()) { + NodeList nList = node.getChildNodes(); + int len = nList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nList.item(i); + short nodeType = child.getNodeType(); + + switch (nodeType) { + case Node.TEXT_NODE: + String s = child.getNodeValue(); + if (s.length() > 0) { + try { + pswDoc.addParagraphData(s, tStyle); + } + catch (Exception e) { + throw new ConvertException( + "Error adding data to paragraph in " + + "PocketWordDocument.\n" + e.toString()); + + } + } + break; + + case Node.ELEMENT_NODE: + if (child.getNodeName().equals(TAG_SPACE)) { + StringBuffer sb = new StringBuffer(""); + int count = 1; + + NamedNodeMap map = child.getAttributes(); + + if (map.getLength() > 0) { + Node attr = map.getNamedItem(ATTRIBUTE_SPACE_COUNT); + count = Integer.parseInt(attr.getNodeValue().trim()); + } + + for ( ; count > 0; count--) { + sb.append(" "); + } + + /* + * May want to look at style info for spaces. Could + * be important when calculating font metrics. + */ + try { + pswDoc.addParagraphData(sb.toString(), tStyle); + } + catch (Exception e) { + throw new ConvertException( + "Error adding data to paragraph in " + + "PocketWordDocument.\n" + e.toString()); + + } + } + else if (child.getNodeName().equals(TAG_TAB_STOP)) { + try { + pswDoc.addParagraphData("\t", tStyle); + } + catch (Exception e) { + throw new ConvertException( + "Error adding data to paragraph in " + + "PocketWordDocument.\n" + e.toString()); + + } + } + else if (child.getNodeName().equals(TAG_LINE_BREAK)) { + /* + * Pocket Word does not support soft line breaks. + * They are just new paragraphs. + */ + } + else if (child.getNodeName().equals(TAG_SPAN)) { + /* + * This is where the interesting ones, i.e. format + * changes occur. + */ + traverseParagraphContents (child, defTextStyle); + } + else if (child.getNodeName().equals(TAG_HYPERLINK)) { + traverseParagraphContents (child, defTextStyle); + } + else { + // Should maybe have a default in here. + } + break; + default: + // Do nothing + } + } + } + else { + /* + * If the node has no children, then it is a blank paragraph, but + * they still require an entry in the Paragraph class to make sense. + */ + pswDoc.addParagraphData("", tStyle); + } + } + + + /* + * Process a text:ordered-list or text:unordered-list tag. Pocket Word has + * no concept of a list so there is no need to differentiate between the + * two. + * + * Each item on the list contains a text:p node. + */ + private void traverseList (Node node) throws IOException, ConvertException { + inList = true; + + if (node.hasChildNodes()) { + NodeList nList = node.getChildNodes(); + int len = nList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_LIST_ITEM)) { + traverseListItem(child); + } + } + } + } + + inList = false; + } + + + /* + * Process a text:list-item node. They usually contain have a single + * text:p child but can also have sections or other lists. + * + * For this case, only paragraphs are supported. + */ + private void traverseListItem (Node node) throws IOException, ConvertException { + if (node.hasChildNodes()) { + NodeList nList = node.getChildNodes(); + int len = nList.getLength(); + + for (int i = 0; i < len; i++) { + Node child = nList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH)) { + traverseParagraph(child); + } + } + } + } + + } + + + /* + * Utility method to retrieve a Node attribute. + */ + private String getAttribute (Node node, String attribute) { + NamedNodeMap attrNodes = node.getAttributes(); + + if (attrNodes != null) { + Node attr = attrNodes.getNamedItem(attribute); + if (attr != null) { + return attr.getNodeValue(); + } + } + + return null; + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/Paragraph.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/Paragraph.java new file mode 100644 index 000000000000..3dee1eeff3b5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/Paragraph.java @@ -0,0 +1,862 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Paragraph.java,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import java.util.Vector; +import java.util.Enumeration; + +import java.awt.Color; + +import org.openoffice.xmerge.util.EndianConverter; +import org.openoffice.xmerge.util.ColourConverter; +import org.openoffice.xmerge.converter.xml.ParaStyle; +import org.openoffice.xmerge.converter.xml.TextStyle; + + +/** + * Represents a paragraph data structure within a Pocket Word document. + * + * @author Mark Murnane + * @version 1.1 + */ +class Paragraph implements PocketWordConstants { + /* + * The data elements of a Paragraph. + * + * As the 'unknown' values are not calculated they are declared static. + * They are not declared final because they do have a calcuable value. + */ + private static short unknown1 = 0x23; + private short dataWords = 0; + private short textLength = 0; + private short lengthWithFormatting = 0; + private short lines = 0; + + private static final short marker = (short)0xFFFF; + private static int unknown2 = 0x22; // May be two short values + + private short specialIndentation = 0; + private short leftIndentation = 0; + private short rightIndentation = 0; + + private byte bullets = 0; + private byte alignment = 0; + + private static int unknown3 = 0; + + // Will always have at least these formatting settings in each paragraph + private short defaultFont = 2; // Courier New for the time being + private short defaultSize = 10; + + + /* + * Remaining elements assist in calculating correct values for the paragraph + * representation. + */ + + private Vector textSegments = null; + + private Vector lineDescriptors = null; + + private ParaStyle pStyle = null; + + private boolean isLastParagraph = false; + + + /* + * Private class constructor used by all constructors. Ensures the proper + * initialisation of the Vector storing the paragraph's text. + */ + private Paragraph () { + textSegments = new Vector(0, 1); + } + + + /** + * <p>Constructor for use when converting from SXW format to Pocket Word + * format.</p> + * + * @param style Paragraph style object describing the formatting style + * of this paragraph. + */ + public Paragraph (ParaStyle style) { + this(); + + lineDescriptors = new Vector(0, 1); + pStyle = style; + } + + + /** + * <p>Constructor for use when converting from Pocket Word format to SXW + * format.</p> + * + * @param data Byte array containing byte data describing this paragraph + * from the Pocket Word file. + */ + public Paragraph (byte[] data) { + this(); + + /* + * Read in all fixed data from the array + * + * unknown1 appears at data[0] and data[1] + */ + dataWords = EndianConverter.readShort(new byte[] { data[2], data[3] } ); + textLength = EndianConverter.readShort(new byte[] { data[4], data [5] } ); + lengthWithFormatting = EndianConverter.readShort( + new byte[] { data[6], data[7] } ); + lines = EndianConverter.readShort(new byte[] { data[8], data [9] } ); + + /* + * The marker appears at data[10] and data[11]. + * + * The value of unknown2 is at data[12], data[13], data[14] and data[15]. + */ + + specialIndentation = EndianConverter.readShort(new byte[] { data[16], data[17] } ); + leftIndentation = EndianConverter.readShort(new byte[] { data[18], data [19] } ); + rightIndentation = EndianConverter.readShort(new byte[] { data[20], data [21] } ); + + bullets = data[22]; + alignment = data[23]; + + // The value of unknown3 is at data[24], data[25], data[26] and data[27]. + + /* + * The actual paragraph data is in the remainder of the byte sequence. + * + * Only the actual text seqence with the embedded formatting tags is + * relevant to the conversion from Pocket Word to SXW format. + */ + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + bos.write(data, 28, lengthWithFormatting); + parseText(bos.toByteArray()); + } + + + /* + * Processes the text portion of the raw paragraph data from the Pocket Word + * file. This data also includes formatting settings for the text in the + * paragraph. + * + * Formatting changes appear like XML/HTML tags. Formatted blocks are + * preceded by a sequence of bytes switching on a formatting change and + * followed by a sequence switching off that formatting change. + */ + private void parseText (byte[] data) { + + int totalLength = data.length; + + StringBuffer sb = new StringBuffer(""); + + // Setup text style information + int mask = TextStyle.BOLD | TextStyle.ITALIC | TextStyle.UNDERLINE + | TextStyle.STRIKETHRU; + + + String fontName = null; + int fontSize = 0; + Color textColour = null; + Color backColour = null; + int modifiers = 0; + + TextStyle ts = null; + + int attrsSet = 0; // If this is 0, we have no extra style + boolean inSequence = false; + boolean sawText = false; + + String s = new String(); // For debugging + + // Start from the very beginning + for (int i = 0; i < totalLength; i++) { + // Will encounter at least two codes first + if ((byte)(data[i] & 0xF0) == FORMATTING_TAG) { + if (sawText) { + // Style change so dump previous segment and style info + addTextSegment(sb.toString(), ts); + sb = new StringBuffer(""); + sawText = false; + } + + switch (data[i]) { + case FONT_TAG: + int index = EndianConverter.readShort( + new byte[] { data[i + 1], data[i + 2] } ); + + /* + * Standard font. + * + * Should really be one, but as the only supported font + * currently is Courier New, want to leave it at Courier + * New for round trip conversions. + * + * Also need to account for the fact that Tahoma is the + * correct standard font. + */ + if (fontName == null || fontName.equals("2")) { + if (index != 2 && index != 1) { + fontName = String.valueOf(index); + attrsSet++; + } + } + else { + // Font is set, but not the default + if (index == 2 || index == 1) { + fontName = "2"; + attrsSet--; + } + else { + fontName = String.valueOf(index); + } + } + i += 2; + break; + + + case FONT_SIZE_TAG: + int size = EndianConverter.readShort( + new byte[] { data[i + 1], data[i + 2] } ); + + if (size == 0) { + // Flags the end of the last paragraph + isLastParagraph = true; + i += 2; + break; + } + + // Standard size + if (fontSize == 0 || fontSize == 10) { + if (size != 10) { + fontSize = size; + attrsSet++; + } + } + else { + // Font size is set, but not to standard + if (size == 10) { + fontSize = 10; + attrsSet--; + } + else { + fontSize = size; + } + } + i += 2; + break; + + + case COLOUR_TAG: + if (data[i + 1] != 0) { + ColourConverter cc = new ColourConverter(); + textColour = cc.convertToRGB( + EndianConverter.readShort(new byte[] { data[i + 1], + data[i + 2] } )); + attrsSet++; + } + else { + textColour = null; + attrsSet--; + } + i += 2; + break; + + + case FONT_WEIGHT_TAG: + if (data[i + 1] == FONT_WEIGHT_BOLD + || data[i + 1] == FONT_WEIGHT_THICK) { + modifiers |= TextStyle.BOLD; + attrsSet++; + } + else { + // Its a bit field so subtracting should work okay. + modifiers ^= TextStyle.BOLD; + attrsSet--; + } + i += 2; + break; + + + case ITALIC_TAG: + if (data[i + 1] == (byte)0x01) { + modifiers |= TextStyle.ITALIC; + attrsSet++; + } + else { + modifiers ^= TextStyle.ITALIC; + attrsSet--; + } + i++; + break; + + + case UNDERLINE_TAG: + if (data[i + 1] == (byte)0x01) { + modifiers |= TextStyle.UNDERLINE; + attrsSet++; + } + else { + modifiers ^= TextStyle.UNDERLINE; + attrsSet--; + } + i++; + break; + + + case STRIKETHROUGH_TAG: + if (data[i + 1] == (byte)0x01) { + modifiers |= TextStyle.STRIKETHRU; + attrsSet++; + } + else { + modifiers ^= TextStyle.STRIKETHRU; + attrsSet--; + } + i++; + break; + + case HIGHLIGHT_TAG: + /* + * Highlighting is treated by OpenOffice as a + * background colour. + */ + if (data[i + 1] == (byte)0x01) { + backColour = Color.yellow; + attrsSet++; + } + else { + backColour = null; + attrsSet--; + } + i++; + break; + } + + inSequence = true; + continue; + } + + if (inSequence) { + // Style information has been changed. Create new style here + + inSequence = false; + if (attrsSet > 0) { + ts = new TextStyle(null, TEXT_STYLE_FAMILY, DEFAULT_STYLE, + mask, modifiers, fontSize, fontName, null); + ts.setColors(textColour, backColour); + } + else { + ts = null; + } + } + + /* + * C4 xx seems to indicate a control code. C4 00 indicates the end + * of a paragraph; C4 04 indicates a tab space. Only these two + * have been seen so far. + */ + if (data[i] == (byte)0xC4) { + /* + * Redundant nodes are sometimes added to the last paragraph + * because a new sequence is being processed when the flag is + * set. + * + * To avoid this, do nothing with the last paragraph unless no + * text has been added for it already. In that case, add the + * empty text segment being process to ensure that all + * paragraphs have at least one text segment. + */ + if (data[i + 1] == (byte)0x00) { + if (isLastParagraph && textSegments.size() > 0) { + return; + } + addTextSegment(sb.toString(), ts); + return; + } + sb.append("\t"); + sawText = true; + i++; + continue; + } + + sb.append((char)data[i]); + sawText = true; + s = sb.toString(); + } + } + + + /** + * <p>Adds details of a new text block to the <code>Paragraph</code> object. + * </p> + * + * @param text The text of the new block. + * @param style Text style object describing the formatting attached + * to this block of text. + */ + public void addTextSegment(String text, TextStyle style) { + textLength += text.length(); + textSegments.add(new ParagraphTextSegment(text, style)); + } + + + /** + * <p>This method alters the state of the <code>Paragraph</code> object to + * indicate whether or not it is the final paragraph in the document.</p> + * + * <p>It is used during conversion from SXW format to Pocket Word format. + * In Pocket Word files, the last paragraph finishes with a different byte + * sequence to other paragraphs.</p> + * + * @param isLast true if the Paragraph is the last in the document, + * false otherwise. + */ + public void setLastParagraph(boolean isLast) { + isLastParagraph = isLast; + } + + + /** + * <p>Complementary method to {@link #setLastParagraph(boolean) + * setLastParagraph}. Returns the terminal status of this + * <code>Paragraph</code> within the Pocket Word document.</p> + * + * @return true if the Paragraph is the last in the document; false otherwise. + */ + public boolean getLastParagraph () { + return isLastParagraph; + } + + + /** + * <p>This method returns the Pocket Word representation of this + * <code>Paragraph</code> in Little Endian byte order.</p> + * + * <p>Used when converting from SXW format to Pocket Word format.</p> + * + * @return <code>byte</code> array containing the formatted representation + * of this Paragraph. + */ + public byte[] getParagraphData() { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + postProcessText(); + + /* + * Need information about the paragraph segments in two places + * so calculate them first. + * + * The stream contains the text wrapped in any formatting sequences that + * are necessary. + */ + ByteArrayOutputStream segs = new ByteArrayOutputStream(); + + try { + for (int i = 0; i < textSegments.size(); i++) { + ParagraphTextSegment pts = (ParagraphTextSegment)textSegments.elementAt(i); + segs.write(pts.getData()); + } + } + catch (IOException ioe) { + // Should never happen in a memory based stream + } + + /* + * Number of data words for this paragraph descriptor: + * + * 26 is the number of bytes prior to the start of the segment. + * 3 comes from the C4 00 00 termintating sequence. + */ + dataWords = (short)(26 + segs.size() + 3 + 4); + if (isLastParagraph) { + dataWords += 6; + } + if (dataWords % 4 != 0) { + dataWords += (4 - (dataWords % 4)); + } + dataWords /= 4; + + /* + * The 8 bytes are made up of E6 ?0 00 and E5 ?0 00 at the start of the + * text along with the C4 00 that terminates it. + * + * In the event that the paragraph is the last one E6 00 00 is also + * present at the end of the text. Also, as we currently use a font + * other than the first in the index (Tahoma) E5 01 00 is also present. + * + * Make sure this is accurate when font specifications change + */ + lengthWithFormatting = (short)(segs.size() + (isLastParagraph ? 14 : 8)); + + try { + bos.write(EndianConverter.writeShort(unknown1)); + bos.write(EndianConverter.writeShort(dataWords)); + bos.write(EndianConverter.writeShort((short)(textLength + 1))); + bos.write(EndianConverter.writeShort(lengthWithFormatting)); + bos.write(EndianConverter.writeShort(lines)); + + bos.write(EndianConverter.writeShort(marker)); + bos.write(EndianConverter.writeInt(unknown2)); + + bos.write(EndianConverter.writeShort(specialIndentation)); + bos.write(EndianConverter.writeShort(leftIndentation)); + bos.write(EndianConverter.writeShort(rightIndentation)); + + bos.write(bullets); + + if (pStyle != null && pStyle.isAttributeSet(ParaStyle.TEXT_ALIGN)) { + switch (pStyle.getAttribute(ParaStyle.TEXT_ALIGN)) { + + case ParaStyle.ALIGN_RIGHT: + bos.write(0x01); + break; + + case ParaStyle.ALIGN_CENTER: + bos.write(0x02); + break; + + default: + bos.write(0x00); // Left align in all other circumstances + break; + } + } + else { + bos.write(0x00); + } + + bos.write(EndianConverter.writeInt(unknown3)); + + + /* + * Write out font and size. + * + * If font support is added then this should change as the information + * will have to be calculated from a Font table. + */ + bos.write(FONT_TAG); + bos.write(EndianConverter.writeShort(defaultFont)); + bos.write(FONT_SIZE_TAG); + bos.write(EndianConverter.writeShort(defaultSize)); + + // Write out the text segments + bos.write(segs.toByteArray()); + + /* + * If this is the last paragraph in the document then we need to make + * sure that the paragraph text is terminated correctly with an E6 00 00 + * before the C4 00 00. + */ + if (isLastParagraph) { + if (defaultFont != 1) { + // Must always go back to the first font. + bos.write(FONT_TAG); + bos.write(EndianConverter.writeShort((short)0x01)); + } + bos.write(FONT_SIZE_TAG); + bos.write(EndianConverter.writeShort((short)0x00)); + } + + bos.write(new byte[] { (byte)0xC4, 0x00, 0x00 } ); + + int padding = 0; + if (bos.size() % 4 != 0) { + padding = 4 - (bos.size() % 4); + } + for (int i = 0; i < padding; i++) { + bos.write(0x00); + } + + // Third byte should match first byte after 0xFF 0xFF + bos.write(new byte[] { 0x42, 0x00, 0x22, 0x00} ); + + /* + * Meaning of last two bytes seems to be the number of words describing + * lines. This is calculated at 10 bytes per descriptor. + * + * May have two extra padding bytes that need to be accounted for too + * The division below may lose 2 bytes (integer result). + */ + int wordsRemaining = (lineDescriptors.size() * 10) / 4; + if ((lineDescriptors.size() * 10) % 4 != 0) { + wordsRemaining++; + } + bos.write(EndianConverter.writeShort((short)wordsRemaining)); + + + // Now write out the line descriptors + for (int i = 0; i < lineDescriptors.size(); i++) { + LineDescriptor ld = (LineDescriptor)lineDescriptors.elementAt(i); + + bos.write(ld.getDescriptorInfo()); + } + + + if (!isLastParagraph) { + /* + * There may be a need to pad this. Will be writing at + * either start of 4 byte block or 2 bytes into it. + */ + if (bos.size() % 4 != 2) { + bos.write(EndianConverter.writeShort((short)0)); + } + bos.write(EndianConverter.writeShort((short)0x41)); + } + } + catch (IOException ioe) { + // Should never occur for a memory based stream + } + + return bos.toByteArray(); + } + + + /* + * This method handles the calculation of correct values for line lengths + * in each individual descriptor and the number of lines in the document. + * + * TODO: Update to take account of different font metrics. + */ + private void postProcessText() { + /* + * The post-processing ... + * + * For each line, we need to add a line descriptor and increment + * the number of lines in the paragraph data structure. + * + * To do this, make sure that no sequence goes over the given screen + * width unless the last char is a whitespace character. + */ + + // In courier, can have no more than 29 chars per line + + int chunkStart = 0; + StringBuffer sb = new StringBuffer(""); + + // Line Descriptor info should be eliminated each time + lineDescriptors = new Vector(1, 1); + lines = 0; + + for (int i = 0; i < textSegments.size(); i++) { + ParagraphTextSegment pts = (ParagraphTextSegment)textSegments.elementAt(i); + sb.append(pts.getText()); + } + + if (sb.length() == 0) { + lines = 1; + lineDescriptors.add(new LineDescriptor((short)1, (short)0)); + return; + } + + while (chunkStart < sb.length()) { + String text = ""; + + try { + text = sb.substring(chunkStart, chunkStart + 30); + } + catch (StringIndexOutOfBoundsException sioobe) { + // We have less than one line left so just add it + text = sb.substring(chunkStart); + lineDescriptors.add(new LineDescriptor((short)(text.length() + 1), (short)(text.length() * 36))); + chunkStart += text.length(); + lines++; + continue; + } + + int lastWhitespace = -1; + + for (int i = 29; i >= 0; i--) { + if (Character.isWhitespace(text.charAt(i))) { + lastWhitespace = i; + break; + } + } + + if (lastWhitespace != -1) { + // The line can be split + lineDescriptors.add(new LineDescriptor((short)(lastWhitespace + 1), (short)(lastWhitespace * 36))); + chunkStart += lastWhitespace + 1; + lines++; + } + else { + // The line is completely occupied by a single word + lineDescriptors.add(new LineDescriptor((short)29, (short)(29 * 36))); + chunkStart += 29; + lines++; + } + } + } + + + /** + * <p>Returns the number of lines in the <code>Paragraph</code>.</p> + * + * @return The number of lines in the document. + */ + public short getLines() { + postProcessText(); + + return lines; + } + + + /** + * <p>Toggles the flag indicating that the <code>Paragraph</code> is a + * bulleted paragraph.</p> + * + * @param isBulleted true to enable bulleting for this paragraph, false + * otherwise. + */ + public void setBullets(boolean isBulleted) { + if (isBulleted) { + bullets = (byte)0xFF; + } + else { + bullets = 0; + } + } + + /** + * <p>Returns the bulleting status of the <code>Paragraph</code>.</p> + * + * @return true if the paragraph is bulleted, false otherwise. + */ + public boolean isBulleted() { + if (bullets != 0) { + return true; + } + return false; + } + + + /** + * <p>Returns the number of text characters in the <code>Paragraph</code>, + * excluding formatting.</p> + * + * @return The length of the paragraph. + */ + public int getTextLength () { + return textLength; + } + + + /** + * <p>Returns an <code>Enumeration</code> over the individual text segments + * of the <code>Paragraph</code>.</p> + * + * @return An <code>Enumeration</code> of the text segments. + */ + public Enumeration getSegmentsEnumerator () { + return textSegments.elements(); + } + + + /** + * <p>Returns a paragraph style object that describes any of the paragraph + * level formatting used by this <code>Paragraph</code>.</p> + * + * @return Paragraph style object describing the <code>Paragraph</code>. + */ + public ParaStyle makeStyle() { + int attrs[] = new int[] { ParaStyle.MARGIN_LEFT, ParaStyle.MARGIN_RIGHT, + ParaStyle.TEXT_ALIGN }; + String values[] = new String[attrs.length]; + + /* + * Not interested in left or right indents just yet. Don't know + * how to calculate them. + */ + + switch (alignment) { + case 2: + values[2] = "center"; + break; + + case 1: + values[2] = "right"; + break; + + case 0: + default: + values[2] = "left"; + return null; // Not interested if its the default. + } + + return new ParaStyle(null, PARAGRAPH_STYLE_FAMILY, null, attrs, + values, null); + } + + + /* + * Class describing the data structures which appear following the text + * of a Paragraph. For each line on screen that the Paragraph uses, a + * LineDescriptor details how many characters are on the line and how much + * screen space they occupy. + * + * The screen space and character breaks are calculated during post-processing + * of the paragraph. See postProcessText(). + * + * The unit of measurement used for screen space is currently unknown. + */ + private class LineDescriptor { + private short characters = 0; + private int filler = 0; + private short screen_space = 0; + private short marker = 0; + + private LineDescriptor(short chars, short space) { + characters = chars; + screen_space = space; + marker = (short)0x040C; // Not a constant. Depends on font used. + } + + + private byte[] getDescriptorInfo(){ + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + try { + bos.write(EndianConverter.writeShort(characters)); + bos.write(EndianConverter.writeInt(filler)); + bos.write(EndianConverter.writeShort(screen_space)); + bos.write(EndianConverter.writeShort(marker)); + } + catch (IOException ioe) { + // Should never happen in a memory based stream. + } + + return bos.toByteArray(); + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/ParagraphTextSegment.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/ParagraphTextSegment.java new file mode 100644 index 000000000000..d2a460037771 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/ParagraphTextSegment.java @@ -0,0 +1,208 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ParagraphTextSegment.java,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.openoffice.xmerge.converter.xml.TextStyle; + +import org.openoffice.xmerge.util.EndianConverter; + +import org.openoffice.xmerge.util.ColourConverter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import java.awt.Color; + +/** + * This class represents a portion of text with a particular formatting style. + * The style may differ from the default style of the paragraph of which it + * is part. + * + * @author Mark Murnane + * @version 1.1 + */ +class ParagraphTextSegment implements PocketWordConstants { + + private String pText; + private TextStyle pStyle; + + + /** + * <p>Initialise a new <code>ParagraphTextSegment</p>. + * <p>Both parameters may be <code>null</code>.</p> + * + * @param data The text of this segment. + * @param style The style describing this segment. + */ + public ParagraphTextSegment (String data, TextStyle style) { + pText = data; + pStyle = style; + } + + /** + * <p>Sets the text for this segment.</p> + * + * @param data The text of this segment. + */ + public void setText (String data) { + pText = data; + } + + /** + * <p>Gets the text for this segment.</p> + * + * @return The text of this segment. + */ + public String getText () { + return pText; + } + + + /** + * <p>Sets the style for this segment.</p> + * + * @param data The style describing this segment. + */ + public void setStyle (TextStyle style) { + pStyle = style; + } + + + /** + * <p>Gets the style for this segment.</p> + * + * @return The style describing this segment. + */ + public TextStyle getStyle () { + return pStyle; + } + + + /** + * <p>Returns the string data for this text segment wrapped with the + * appropriate byte codes for the formatting settings used.</p> + * + * @return <code>byte</code> array containing formatted text in Pocket Word + * format. + */ + public byte[] getData () { + ByteArrayOutputStream data = new ByteArrayOutputStream(); + + boolean colourSet = false; + boolean boldSet = false; + boolean italicSet = false; + boolean underlineSet = false; + boolean strikeSet = false; + boolean highlightSet = false; + + // TODO: Font changes need to be worked out here + + try { + if (pStyle != null) { + if (pStyle.getFontColor() != null) { + ColourConverter cc = new ColourConverter(); + short colourCode = cc.convertFromRGB(pStyle.getFontColor()); + if (colourCode != 0) { // not black + data.write(COLOUR_TAG); + data.write(EndianConverter.writeShort(colourCode)); + colourSet = true; + } + } + if (pStyle.isSet(TextStyle.BOLD) && pStyle.getAttribute(TextStyle.BOLD)) { + data.write(new byte[] { FONT_WEIGHT_TAG, FONT_WEIGHT_BOLD, 0x00 } ); + boldSet = true; + } + if (pStyle.isSet(TextStyle.ITALIC) && pStyle.getAttribute(TextStyle.ITALIC)) { + data.write(new byte[] { ITALIC_TAG, 0x01 } ); + italicSet = true; + } + if (pStyle.isSet(TextStyle.UNDERLINE) && pStyle.getAttribute(TextStyle.UNDERLINE)) { + data.write(new byte[] { UNDERLINE_TAG, 0x01 } ); + underlineSet = true; + } + if (pStyle.isSet(TextStyle.STRIKETHRU) && pStyle.getAttribute(TextStyle.STRIKETHRU)) { + data.write(new byte[] { STRIKETHROUGH_TAG, 0x01 } ); + strikeSet = true; + } + if (pStyle.getBackgroundColor() != null) { + data.write(new byte[] { HIGHLIGHT_TAG, 0x01 } ); + highlightSet = true; + } + } + + + // Now write out the data + if (!pText.equals("\t")) { + data.write(pText.getBytes()); + } + else { + /* + * Tabs are a special case. They are represented by Pocket Word + * as the LE sequence 0xC4 0x04. + */ + data.write(new byte[] { (byte)0xC4, 0x04 } ); + } + + + // Now close out any of the settings changes + if (colourSet) { + /* + * Colours may change without changing back to black, but + * without knowing what the previous colour was, the only + * way to ensure correct conversion is to restore to black and + * let the next segment change the colour again. + */ + data.write(new byte[] { COLOUR_TAG, 0x00, 0x00 } ); + } + if (boldSet) { + data.write(new byte[] { FONT_WEIGHT_TAG, FONT_WEIGHT_NORMAL, 0x00 } ); + } + if (italicSet) { + data.write(new byte[] { ITALIC_TAG, 0x00 } ); + } + if (underlineSet) { + data.write(new byte[] { UNDERLINE_TAG, 0x00 } ); + } + if (strikeSet) { + data.write(new byte[] { STRIKETHROUGH_TAG, 0x00 } ); + } + if (highlightSet) { + data.write(new byte[] { HIGHLIGHT_TAG, 0x00 } ); + } + } + catch (IOException ioe) { + // Should never occur in a memory based stream + } + + return data.toByteArray(); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PluginFactoryImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PluginFactoryImpl.java new file mode 100644 index 000000000000..35e6b89a9ec6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PluginFactoryImpl.java @@ -0,0 +1,168 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PluginFactoryImpl.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + + +import java.io.InputStream; +import java.io.IOException; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.DocumentMergerFactory; +import org.openoffice.xmerge.ConverterCapabilities; + +import org.openoffice.xmerge.util.registry.ConverterInfo; + +import org.openoffice.xmerge.converter.xml.sxw.SxwPluginFactory; + + +/** + * Factory class used to create converters to/from the Pocket Word format. + * + * @author Mark Murnane + * @version 1.1 + */ +public final class PluginFactoryImpl extends SxwPluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory, + DocumentMergerFactory{ + + /** + * <p>Constructor that caches the <code>ConvertInfo</code> that + * corresponds to the registry information for this plug-in.</p> + * + * @param ci <code>ConvertInfo</code> object. + */ + public PluginFactoryImpl (ConverterInfo ci) { + super(ci); + } + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + /** + * <p>The <code>DocumentSerializer</code> is used to convert + * from the OpenOffice Writer <code>Document</code> format + * to the Pocket Word <code>Document</code> format.</p> + * + * <p>The <code>ConvertData</code> object is passed along to the + * created <code>DocumentSerializer</code> via its constructor. + * The <code>ConvertData</code> is read and converted when the + * the <code>DocumentSerializer</code> object's + * <code>serialize</code> method is called.</p> + * + * @param doc <code>Document</code> object that the created + * <code>DocumentSerializer</code> object uses + * as input. + * + * @return A <code>DocumentSerializer</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + return new DocumentSerializerImpl(doc); + } + + + /** + * The <code>DocumentDeserializer</code> is used to convert + * from the Pocket Word <code>Document</code> format to + * the OpenOffice Writer <code>Document</code> format.</p> + * + * The <code>ConvertData</code> object is passed along to the + * created <code>DocumentDeserializer</code> via its constructor. + * The <code>ConvertData</code> is read and converted when the + * the <code>DocumentDeserializer</code> object's + * <code>deserialize</code> method is called. + * </p> + * + * @param cd <code>ConvertData</code> object that the created + * <code>DocumentDeserializer</code> object uses as + * input. + * + * @return A <code>DocumentDeserializer</code> object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + return new DocumentDeserializerImpl(cd); + } + + + /** + * <p>Create a <code>Document</code> object that corresponds to + * the Pocket Word data passed in via the <code>InputStream</code> + * object. + * + * <p>This method will read from the given <code>InputStream</code> + * object. The returned <code>Document</code> object will contain + * the necessary data for the other objects created by the + * <code>PluginFactoryImpl</code> to process, like the + * <code>DocumentSerializerImpl</code> object and a + * <code>DocumentMerger</code> object.</p> + * + * @param name The <code>Document</code> name. + * @param is <code>InputStream</code> object corresponding + * to the <code>Document</code>. + * + * @return A <code>Document</code> object representing the + * Pocket Word format. + * + * @throws IOException If any I/O error occurs. + */ + + public Document createDeviceDocument(String name, InputStream is) + throws IOException { + PocketWordDocument pwd = new PocketWordDocument(name); + pwd.read(is); + return pwd; + } + + /** + * Returns an instance of <code>DocumentMergerImpl</code>, + * which is an implementation of the <code>DocumentMerger</code> + * interface. + * + * @param doc <code>Document</code> to merge. + * + * @return A DocumentMergerImpl object. + */ + public DocumentMerger createDocumentMerger(Document doc) { + ConverterCapabilities cc = converterCap; + DocumentMergerImpl merger = new DocumentMergerImpl(doc, cc); + return merger; + + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PocketWordConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PocketWordConstants.java new file mode 100644 index 000000000000..03af731f2122 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PocketWordConstants.java @@ -0,0 +1,98 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PocketWordConstants.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + + +/** + * Interface defining constants for Pocket Word attributes. + * + * @author Mark Murnane + * @version 1.1 + */ +public interface PocketWordConstants { + /** File extension for Pocket Word files. */ + public static final String FILE_EXTENSION = ".psw"; + + /** Name of the default style. */ + public static final String DEFAULT_STYLE = "Standard"; + + /** Family name for Paragraph styles. */ + public static final String PARAGRAPH_STYLE_FAMILY = "paragraph"; + + /** Family name for Text styles. */ + public static final String TEXT_STYLE_FAMILY = "text"; + + + /** + * Generic Pocket Word formatting code. + * + * Formatting codes are 0xEz, where z indicates the specific format code. + */ + public static final byte FORMATTING_TAG = (byte)0xE0; + + /** Font specification tag. The two bytes following inidicate which font. */ + public static final byte FONT_TAG = (byte)0xE5; + + /** Font size tag. The two bytes following specify font size in points. */ + public static final byte FONT_SIZE_TAG = (byte)0xE6; + + /** Colour tag. Two bytes following index a 4-bit colour table. */ + public static final byte COLOUR_TAG = (byte)0xE7; + + /** Font weight tag. Two bytes following indicate weighting of font. */ + public static final byte FONT_WEIGHT_TAG = (byte)0xE8; + + /** Normal font weight value. */ + public static final byte FONT_WEIGHT_NORMAL = (byte)0x04; + + /** Fine font weight value. */ + public static final byte FONT_WEIGHT_FINE = (byte)0x01; + + /** Bold font weight value. */ + public static final byte FONT_WEIGHT_BOLD = (byte)0x07; + + /** Thick font weight value. */ + public static final byte FONT_WEIGHT_THICK = (byte)0x09; + + /** Italic tag. Single byte following indicates whether italic is on. */ + public static final byte ITALIC_TAG = (byte)0xE9; + + /** Underline tag. Single byte following indicates whether underline is on. */ + public static final byte UNDERLINE_TAG = (byte)0xEA; + + /** Strikethrough tag. Single byte following indicates whether strikethrough is on. */ + public static final byte STRIKETHROUGH_TAG = (byte)0XEB; + + /** Highlighting tag. Single byte following indicates whether highlighting is on. */ + public static final byte HIGHLIGHT_TAG = (byte)0xEC; + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PocketWordDocument.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PocketWordDocument.java new file mode 100644 index 000000000000..8d4ad63fa82a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/PocketWordDocument.java @@ -0,0 +1,411 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PocketWordDocument.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +package org.openoffice.xmerge.converter.xml.sxw.pocketword; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.converter.xml.ParaStyle; +import org.openoffice.xmerge.converter.xml.TextStyle; + +import java.awt.Font; + +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +import java.util.Enumeration; +import java.util.Vector; + + +/** + * <p>Class representing a Pocket Word Document.</p> + * + * <p><code>PocketWordDocument</code> is used to create new Pocket Word documents + * and to read existing data to allow for conversion to OpenOffice Writer + * format.</p> + * + * @author Mark Murnane + * @version 1.1 + */ +public class PocketWordDocument implements Document, PocketWordConstants { + private String docName; + + private byte[] preamble; + private Vector fonts; + private DocumentDescriptor descriptor; + private Vector paragraphs; + + private ParaStyle pStyle; + private Paragraph currentPara; + + /* + * The trailer currently appears to be constant, but if its found to + * have a variable component, then this initialisation should be moved + * to an initTrailer() method. + * + * Padding is sometimes needed before the trailer to ensure the file + * ends on a 4-byte boundary, but this is handled in write(). + */ + private static final byte[] trailer = new byte[] { (byte)0x82, 0x00, + 0x09, 0x00, + 0x03, 0x00, + (byte)0x82, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00 }; + + + /** + * <p>Constructs a new Pocket Word Document.</p> + * + * <p>This new document does notcontain any information. Document data must + * either be added using appropriate methods, or an existing file can be + * {@link #read(InputStream) read} from an <code>InputStream</code>.</p> + * + * @param name The name of the <code>PocketWordDocument</code>. + */ + public PocketWordDocument(String name) { + + docName = trimDocumentName(name); + + preamble = new byte[52]; + fonts = new Vector(0, 1); + descriptor = new DocumentDescriptor(); + paragraphs = new Vector(0, 1); + } + + + /** + * <p>This method reads <code>byte</code> data from the InputStream and + * extracts font and paragraph data from the file.</p> + * + * @param is InputStream containing a Pocket Word data file. + * + * @throws IOException In case of any I/O errors. + */ + public void read(InputStream docData) throws IOException { + + if (docData == null) { + throw new IOException ("No input stream to convert"); + } + + // The preamble may become important for font declarations. + int readValue = docData.read(preamble); + // #i33702# check for an empty InputStream. + if(readValue == -1) { + System.err.println("Error:invalid input stream"); + return; + } + + byte[] font = new byte[80]; + int numfonts = 0; + do { + docData.read(font); + + String name = new String(font, 0, 64, "UTF-16LE"); + fonts.add(name.trim()); + + } while (!(font[76] == 5 && font[77] == 0 + && font[78] == 1 && font[79] == 0)); + + /* + * TODO: The document descriptor data that follows the fonts ends with + * a variable section containing data for each of the paragraphs. + * It may be possible to use this information to calculate staring + * positions for each paragraph rather than iterating through the + * entire byte stream. + */ + + int value; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + while ((value = docData.read()) != -1) { + bos.write(value); + } + + + byte[] contentData = bos.toByteArray(); + int start = 0, end = 0; + boolean sawMarker = false; + + for (int i = 0; i < contentData.length; i += 4) { + if (contentData[i + 2] == (byte)0xFF + && contentData[i + 3] == (byte)0xFF && !sawMarker) { + start = i - 8; + sawMarker = true; + continue; + } + + if (contentData[i + 2] == (byte)0xFF + && contentData[i + 3] == (byte)0xFF && sawMarker) { + end = i - 8; + ByteArrayOutputStream paragraph = new ByteArrayOutputStream(); + paragraph.write(contentData, start, end - start); + paragraphs.add(new Paragraph(paragraph.toByteArray())); + + // Reset the markers + sawMarker = false; + i -= 4; // Skip back + } + + } + + /* + * Special case, the last paragraph + * If we got here, and the marker is set then we saw the start of the + * last paragraph, but no following paragraph + */ + ByteArrayOutputStream paragraph = new ByteArrayOutputStream(); + if (contentData[contentData.length - 19] == 0) { + paragraph.write(contentData, start, contentData.length - start - 20); + } + else { + paragraph.write(contentData, start, contentData.length - start - 18); + } + paragraphs.add(new Paragraph(paragraph.toByteArray())); + } + + + /* + * Utility method to make sure the document name is stripped of any file + * extensions before use. + */ + private String trimDocumentName(String name) { + String temp = name.toLowerCase(); + + if (temp.endsWith(FILE_EXTENSION)) { + // strip the extension + int nlen = name.length(); + int endIndex = nlen - FILE_EXTENSION.length(); + name = name.substring(0,endIndex); + } + + return name; + } + + + /** + * <p>Method to provide access to all of the <code>Paragraph</code> objects + * in the <code>Document</code>.</p> + * + * @return <code>Enumeration</code> over the paragraphs in the document. + */ + public Enumeration getParagraphEnumeration() { + return paragraphs.elements(); + } + + + /** + * <p>Returns the <code>Document</code> name with no file extension.</p> + * + * @return The <code>Document</code> name with no file extension. + */ + public String getName() { + return docName; + } + + + /** + * <p>Returns the <code>Document</code> name with file extension.</p> + * + * @return The <code>Document</code> name with file extension. + */ + public String getFileName() { + return new String(docName + FILE_EXTENSION); + } + + + /** + * <p>Writes out the <code>Document</code> content to the specified + * <code>OutputStream</code>.</p> + * + * <p>This method may not be thread-safe. + * Implementations may or may not synchronize this + * method. User code (i.e. caller) must make sure that + * calls to this method are thread-safe.</p> + * + * @param os <code>OutputStream</code> to write out the + * <code>Document</code> content. + * + * @throws IOException If any I/O error occurs. + */ + public void write(OutputStream os) throws IOException { + DataOutputStream dos = new DataOutputStream(os); + + initPreamble(); + dos.write(preamble); + + loadFonts(); + for (int i = 0; i < fonts.size(); i++ ) { + ByteArrayOutputStream fontData = (ByteArrayOutputStream)fonts.elementAt(i); + dos.write(fontData.toByteArray()); + } + + + for (int i = 0; i < paragraphs.size(); i++) { + Paragraph para = (Paragraph)paragraphs.elementAt(i); + descriptor.addParagraph((short)para.getTextLength(), para.getLines()); + } + dos.write(descriptor.getDescriptor()); + + for (int i = 0; i < paragraphs.size(); i++ ) { + Paragraph para = (Paragraph)paragraphs.elementAt(i); + + // Last paragraph has some extra data + if (i + 1 == paragraphs.size()) { + para.setLastParagraph(true); + } + dos.write(para.getParagraphData()); + } + + + /* + * Before we write out the trailer, we need to make sure that it will + * lead to the file ending on a 4 byte boundary. + */ + if (dos.size() % 4 == 0) { + dos.write((byte)0x00); + dos.write((byte)0x00); + } + + dos.write(trailer); + + dos.flush(); + dos.close(); + } + + + /** + * <p>This method adds a new paragraph element to the document. No string + * data is added to the paragraph.</p> + * + * <p><b>N.B.</b> The newly added paragraph becomes the current paragraph and + * is used as the target for all subsequent calls to addParagraphData().</p> + * + * @param style Paragraph Style object describing the formatting for + * the new paragraph. Can be null. + * @param listElement true if this paragraph is to be bulleted; + * false otherwise. + */ + public void addParagraph(ParaStyle style, boolean listElement) { + /* For the moment, only support basic text entry in a single paragraph */ + Paragraph para = new Paragraph(style); + + paragraphs.add(para); + + pStyle = style; + currentPara = para; + + if (listElement) { + para.setBullets(true); + } + } + + + /** + * <p>This method adds text to the current paragraph.</p> + * + * <p>If no paragraphs exist within the document, it creates one.</p> + * + * @param data The string data for this segment. + * @param style Text Style object describing the formatting of this + * segment. Can be null. + */ + public void addParagraphData(String data, TextStyle style) { + if (currentPara == null) { + addParagraph(null, false); + } + currentPara.addTextSegment(data, style); + } + + + /* + * Preamble is the portion before font specification which never + * seems to change from one file, or one saved version, to the next. + * + * Bytes 18h and 19h seem to contain the number of fonts and should + * be modified when all of the fonts have been specified. + * These bytes are the first two on the fourth line below. + */ + private void initPreamble() { + preamble = new byte[] { 0x7B, 0x5C, 0x70, 0x77, 0x69, 0x15, 0x00, 0x00, + 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x2C, 0x00, 0x01, 0x00, 0x0A, 0x00, // Bytes 3-4 Font?? + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Bytes 1-2 # Fonts + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + } + + + /* + * This method writes the minimum font data that is used by the converter. + * Currently, all documents convert to 10 point Courier New. Tahoma is + * always mentioned in Pocket Word files, however, even if it is not used. + * + * TODO: Rewrite to allow for multiple fonts once font support issues + * have been resolved. + */ + private void loadFonts() { + ByteArrayOutputStream fontData = new ByteArrayOutputStream(); + + try { + fontData.write(new String("Tahoma").getBytes("UTF-16LE")); + fontData.write(new byte[52]); // Rest of font name? + fontData.write(new byte[] { 0x02, 0x00, 0x01, 0x00 } ); + fontData.write(new byte[] { 0x00, 0x00, 0x01, 0x00 } ); + fontData.write(new byte[] { 0x00, 0x00, 0x00, 0x00 } ); + fontData.write(new byte[] { 0x00, 0x00, 0x00, 0x00 } ); + + fonts.add(fontData); + + fontData = new ByteArrayOutputStream(); + + fontData.write(new String("Courier New").getBytes("UTF-16LE")); + fontData.write(new byte[42]); + fontData.write(new byte[] { 0x14, 0x00, 0x04, 0x00 } ); + fontData.write(new byte[] { 0x01, 0x00, 0x00, 0x00 } ); + fontData.write(new byte[] { 0x00, 0x00, 0x15, 0x00 } ); + + // Next part indicates that this is the last font + fontData.write(new byte[] { 0x05, 0x00, 0x01, 0x00 } ); + + fonts.add(fontData); + } + catch (IOException ioe) { + // Shouldn't happen as this is a memory based stream + } + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/build.xml new file mode 100644 index 000000000000..f12db13e755c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/build.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.6 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxs_pocketword" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxs_pocketword"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxw/pocketword"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/DocumentDescriptor.java"/> + <include name="${package}/DocumentDeserializerImpl.java"/> + <include name="${package}/DocumentSerializerImpl.java"/> + <include name="${package}/Paragraph.java"/> + <include name="${package}/ParagraphTextSegment.java"/> + <include name="${package}/PluginFactoryImpl.java"/> + <include name="${package}/PocketWordConstants.java"/> + <include name="${package}/PocketWordDocument.java"/> + <include name="${package}/DocumentMergerImpl.java"/> + <include name="${package}/ConverterCapabilitiesImpl.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/converter.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/converter.xml new file mode 100644 index 000000000000..e9ee658d27f3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/converter.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: converter.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + + +<converters> + <converter type="staroffice/sxw" version="1.1"> + <converter-display-name> + Pocket Word + </converter-display-name> + <converter-description> + OpenOffice Writer XML to/from Pocket Word conversion. + </converter-description> + <converter-vendor> + OpenOffice.org + </converter-vendor> + <converter-class-impl> + org.openoffice.xmerge.converter.xml.sxw.pocketword.PluginFactoryImpl + </converter-class-impl> + <converter-target type="application/x-pocket-word"/> + </converter> +</converters> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/package.html new file mode 100644 index 000000000000..65454f24773c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/pocketword/package.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxw.pocketword package</title> +</head> + +<body bgcolor="white"> + +<p>Plugin for the conversion of documents between StarWriter XML and + Pocket Word format.</p> +<p>This plugin suports conversion of most features supported by Pocket Word.</p> +<ul> + <li>Bold, Italic, Underline</li> + <li>Strikethrough</li> + <li>Highlight</li> + <li>Colours</li> + <li>Lists</li> + <li>Alignments</li> +</ul> + +<p>Additionally, work on fonts is currently underway.</p> + +<p>This plugin is based on the Windows CE 3.0 version of Pocket Word.<br> + Testing was carried out using Pocket PC 2000 and Pocket PC 2002 devices.</p> + +<p>It follows the {@link org.openoffice.xmerge} framework +for the conversion process.</p> + +</body> +</html> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/ConverterCapabilitiesImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..5470025a934f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/ConverterCapabilitiesImpl.java @@ -0,0 +1,96 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterCapabilitiesImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * <p>WordSmith implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarWriter XML to/from WordSmith conversions. + * The <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_DOCUMENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_DOCUMENT_CONTENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_HEADING.equals(tag)) + return true; + else if (OfficeConstants.TAG_ORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_UNORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_ITEM.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_HEADER.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPAN.equals(tag)) + return true; + else if (OfficeConstants.TAG_HYPERLINK.equals(tag)) + return true; + else if (OfficeConstants.TAG_LINE_BREAK.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPACE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TAB_STOP.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_SPACE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_SPACE_COUNT.equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DOCConstants.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DOCConstants.java new file mode 100644 index 000000000000..ef066386d4a4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DOCConstants.java @@ -0,0 +1,64 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DOCConstants.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +/** + * Constants used for encoding and decoding the WordSmith format. + * + * @author Herbie Ong, David Proulx + */ +interface DOCConstants { + + /** Constant for uncompressed version. */ + public static final short UNCOMPRESSED = 1; + + /** Constant for compressed version. */ + public static final short COMPRESSED = 2; + + /** Constant used for spare fields. */ + public static final int SPARE = 0; + + /** WordSmith record size. */ + public static final short TEXT_RECORD_SIZE = 4096; + + /** Constant for encoding scheme. */ + public static final String ENCODING = "8859_1"; + + /** Constant for TAB character. */ + public final static char TAB_CHAR = '\t'; + + /** Constant for EOL character. */ + public final static char EOL_CHAR = '\n'; + + /** Constant for SPACE character. */ + public final static char SPACE_CHAR = ' '; +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentDeserializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentDeserializerImpl.java new file mode 100644 index 000000000000..4c6c48822093 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentDeserializerImpl.java @@ -0,0 +1,568 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentDeserializerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.w3c.dom.*; + +import java.io.IOException; +import java.util.Enumeration; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PdbDecoder; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; + +import java.util.Vector; +import java.io.ByteArrayInputStream; + +import org.openoffice.xmerge.converter.xml.*; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.XmlUtil; + +/** + * <p>WordSmith implementation of + * org.openoffice.xmerge.DocumentDeserializer + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * The <code>deserialize</code> method uses a + * <code>DocDecoder</code> to read the WordSmith format into a + * <code>String</code> object, then it calls <code>buildDocument</code> + * to create a <code>SxwDocument</code> object from it. + * + * @author Herbie Ong, David Proulx + */ +public final class DocumentDeserializerImpl +implements DOCConstants, OfficeConstants, DocumentDeserializer { + + /** A Decoder object for decoding WordSmith format. */ + private WSDecoder decoder = null; + + WseFontTable fontTable = null; + WseColorTable colorTable = null; + StyleCatalog styleCat = null; + StyleCatalog oldStyleCat = null; + + /** A <code>ConvertData</code> object assigned to this object. */ + private ConvertData cd = null; + + + /** + * Constructor that assigns the given <code>ConvertData</code> + * to the object. + * + * @param cd A <code>ConvertData</code> object to read data for + * the conversion process by the deserialize method. + */ + public DocumentDeserializerImpl(ConvertData cd) { + this.cd = cd; + } + + + /** + * Convert the given <code>ConvertData</code> into a + * <code>SxwDocument</code> object. + * + * @return Resulting <code>Document</code> object. + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public Document deserialize() throws ConvertException, + IOException { + return deserialize(null, cd); + } + + + public Document deserialize(Document origDoc, ConvertData cd) + throws IOException { + + Document doc = null; + PalmDocument palmDoc = null; + Enumeration e = cd.getDocumentEnumeration(); + + while(e.hasMoreElements()) { + palmDoc = (PalmDocument) e.nextElement(); + PalmDB pdb = palmDoc.getPdb(); + Record[] recs = pdb.getRecords(); + decoder = new WSDecoder(); + Wse[] b = decoder.parseDocument(recs); + String docName = palmDoc.getName(); + doc = buildDocument(docName, b, origDoc); + } + return doc; + } + + + /** + * Temporary method to read existing <code>StyleCatalog</code> + * as a starting point. + * + * @param parentDoc The parent <code>Document</code>. + */ + private void readStyleCatalog(Document parentDoc) { + Element rootNode = null; + try { + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + parentDoc.write(bos); + SxwDocument sxwDoc = new SxwDocument("old"); + sxwDoc.read(new ByteArrayInputStream(bos.toByteArray())); + org.w3c.dom.Document domDoc = sxwDoc.getContentDOM(); + + String families[] = new String[3]; + families[0] = "text"; + families[1] = "paragraph"; + families[2] = "paragraph"; + Class classes[] = new Class[3]; + classes[0] = TextStyle.class; + classes[1] = ParaStyle.class; + classes[2] = TextStyle.class; + + NodeList nl = domDoc.getElementsByTagName(TAG_OFFICE_STYLES); + oldStyleCat.add(nl.item(0), families, classes, null, false); + nl = domDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + oldStyleCat.add(nl.item(0), families, classes, null, false); + nl = domDoc.getElementsByTagName(TAG_OFFICE_MASTER_STYLES); + oldStyleCat.add(nl.item(0), families, classes, null, false); + + } catch (Exception e) { + Debug.log(Debug.ERROR, "", e); + } + + } + + + /** + * Given an array of paragraph <code>Style</code> objects, see if + * there is exactly one which matches the text formatting + * <code>Style</code> of <code>tStyle</code>. + * + * @param paraStyles An array of paragraph <code>Style</code> + * objects. + * @param tStyle Text <code>Style</code> to match. + * + * @return The paragraph <code>Style</code> that matches. + */ + private ParaStyle matchParaByText(Style paraStyles[], TextStyle tStyle) { + int matchIndex = -1; + int matchCount = 0; + Style txtMatches[] = (Style[]) oldStyleCat.getMatching(tStyle); + if (txtMatches.length >= 1) { + for (int j = 0; j < txtMatches.length; j++) { + TextStyle t = (TextStyle)txtMatches[j]; + + if (!t.getFamily().equals("paragraph")) + continue; + + for (int k = 0; k < paraStyles.length; k++) { + if (t.getName().equals(paraStyles[k].getName())) { + matchCount++; + matchIndex = k; + } + } + } + } + if (matchCount == 1) + return (ParaStyle)paraStyles[matchIndex]; + else return null; + } + + + /** + * Take a <code>String</code> of text and turn it into a sequence + * of <code>Node</code> objects. + * + * @param text <code>String</code> of text. + * @param parentDoc Parent <code>Document</code>. + * + * @return Array of <code>Node</code> objects. + */ + private Node[] parseText(String text, org.w3c.dom.Document parentDoc) { + Vector nodeVec = new Vector(); + + // Break up the text from the WordSmith text run into Open + // Office text runs. There may be more runs in OO because + // runs of 2 or more spaces map to nodes. + while ((text.indexOf(" ") != -1) || (text.indexOf("\t") != 1)) { + + // Find the indices of tabs and multiple spaces, and + // figure out which of them occurs first in the string. + int spaceIndex = text.indexOf(" "); + int tabIndex = text.indexOf("\t"); + if ((spaceIndex == -1) && (tabIndex == -1)) + break; // DJP This should not be necessary. What is wrong + // with the while() stmt up above? + int closerIndex; // Index of the first of these + if (spaceIndex == -1) + closerIndex = tabIndex; + else if (tabIndex == -1) + closerIndex = spaceIndex; + else + closerIndex = (spaceIndex > tabIndex) ? tabIndex : spaceIndex; + + // If there is any text prior to the first occurrence of a + // tab or spaces, create a text node from it, then chop it + // off the string we're working with. + if (closerIndex > 0) { + String beginningText = text.substring(0, closerIndex); + Text textNode = parentDoc.createTextNode(beginningText); + nodeVec.addElement(textNode); + log("<TEXT>"); + log(beginningText); + log("</TEXT>"); + } + text = text.substring(closerIndex); + + // Handle either tab character or space sequence by creating + // an element for it, and then chopping out the text that + // represented it in "text". + if (closerIndex == tabIndex) { + Element tabNode = parentDoc.createElement(TAG_TAB_STOP); + nodeVec.add(tabNode); + text = text.substring(1); // tab is always a single character + log("<TAB/>"); + } else { + // Compute length of space sequence. + int nrSpaces = 2; + while ((nrSpaces < text.length()) + && text.substring(nrSpaces, nrSpaces + 1).equals(" ")) + nrSpaces++; + + Element spaceNode = parentDoc.createElement(TAG_SPACE); + spaceNode.setAttribute(ATTRIBUTE_SPACE_COUNT, new Integer(nrSpaces).toString()); + nodeVec.add(spaceNode); + text = text.substring(nrSpaces); + log("<SPACE count=\"" + nrSpaces + "\" />"); + } + } + + // No more tabs or space sequences. If there's any remaining + // text create a text node for it. + if (text.length() > 0) { + Text textNode = parentDoc.createTextNode(text); + nodeVec.add(textNode); + log("<TEXT>"); + log(text); + log("</TEXT>"); + } + + // Now create and populate an array to return the nodes in. + Node nodes[] = new Node[nodeVec.size()]; + for (int i = 0; i < nodeVec.size(); i++) + nodes[i] = (Node)nodeVec.elementAt(i); + return nodes; + } + + + /** + * Parses the text content of a WordSmith format and builds a + * <code>SXWDocument</code>. + * + * @param docName <code>Document</code> name + * @param str Text content of WordSmith format + * + * @return Resulting <code>SXWDocument</code> object. + * + * @throws IOException If any I/O error occurs. + */ + private SxwDocument buildDocument(String docName, Wse[] data, Document origDoc) + throws IOException { + + // create minimum office xml document. + SxwDocument sxwDoc = new SxwDocument(docName); + sxwDoc.initContentDOM(); + + org.w3c.dom.Document doc = sxwDoc.getContentDOM(); + + // Grab hold of the office:body tag, + // Assume there should be one. + // This is where top level paragraphs will append to. + NodeList list = doc.getElementsByTagName(TAG_OFFICE_BODY); + Node bodyNode = list.item(0); + + styleCat = new StyleCatalog(50); + oldStyleCat = new StyleCatalog(50); + if (origDoc != null) + readStyleCatalog(origDoc); + + Element currPara = null; + ParaStyle currParaStyle = null; + int newTextStyleNr = 0; + int newParaStyleNr = 0; + + // Now write out the document body by running through + // the list of WordSmith elements and processing each one + // in turn. + for (int i = 0; i < data.length; i++) { + + if (data[i].getClass() == WsePara.class) { + + currPara = doc.createElement(TAG_PARAGRAPH); + log("</PARA>"); + log("<PARA>"); + + WsePara p = (WsePara)data[i]; + + // Save info about the first text run, if there is one. + WseTextRun firstTextRun = null; + + if ((data.length >= i + 2) + && (data[i+1].getClass() == WseTextRun.class)) + firstTextRun = (WseTextRun)data[i+1]; + + Style matches[] = oldStyleCat.getMatching(p.makeStyle()); + + // See if we can find a unique match in the catalog + // of existing styles from the original document. + ParaStyle pStyle = null; + if (matches.length == 1) { + pStyle = (ParaStyle)matches[0]; + log("using an existing style"); + } else if ((matches.length > 1) && (firstTextRun != null)) { + pStyle = matchParaByText(matches, firstTextRun.makeStyle()); + log("resolved a para by looking @ text"); + } + + // If nothing found so far, try looking in the catalog + // of newly-created styles. + // DJP FIXME: if we need to add two para styles with the + // same para formatting info but different default text + // styles, this won't work! + if (pStyle == null) { + log("had " + matches.length + " matches in old catalog"); + matches = styleCat.getMatching(p.makeStyle()); + if (matches.length == 0) { + pStyle = p.makeStyle(); + String newName = new String("PPP" + ++newParaStyleNr); + pStyle.setName(newName); + styleCat.add(pStyle); + // DJP: write in the text format info here + log("created a new style"); + } else if (matches.length == 1) { + pStyle = (ParaStyle)matches[0]; + log("re-using a new style"); + } else if (firstTextRun != null) { + pStyle = matchParaByText(matches, firstTextRun.makeStyle()); + if (pStyle != null) { + log("resolved a (new) para by looking @ text"); + } else + log("Hey this shouldn't happen! - nr of matches is " + + matches.length); + } + } + + if (pStyle == null) + log("Unable to figure out a para style"); + + // Figured out a style to use. Specify the style in this + // paragraph's attributes. + currPara.setAttribute(ATTRIBUTE_TEXT_STYLE_NAME, pStyle.getName()); + + bodyNode.appendChild(currPara); + currParaStyle = pStyle; + } else if (data[i].getClass() == WseTextRun.class) { + WseTextRun tr = (WseTextRun)data[i]; + TextStyle trStyle = null; + Node trNodes[] = parseText(tr.getText(), doc); + + // First see if the formatting of this text run matches + // the default text formatting for this paragraph. If + // it does, then just make the text node(s) children of + // the current paragraph. + Style[] cps = new Style[1]; + cps[0] = currParaStyle; + if (matchParaByText(cps, tr.makeStyle()) != null) { + for (int ii = 0; ii < trNodes.length; ii++) { + currPara.appendChild(trNodes[ii]); + } + continue; + } + + // Check for existing, matching styles in the old style + // catalog. If exactly one is found, use it. Otherwise, + // check the new style catalog, and either use the style + // found or add this new one to it. + Style matches[] = oldStyleCat.getMatching(tr.makeStyle()); + if (matches.length == 1) + trStyle = (TextStyle)matches[0]; + else { + matches = styleCat.getMatching(tr.makeStyle()); + if (matches.length == 0) { + trStyle = tr.makeStyle(); + String newName = new String("TTT" + ++newTextStyleNr); + trStyle.setName(newName); + styleCat.add(trStyle); + } else if (matches.length == 1) + trStyle = (TextStyle)matches[0]; + else + log("multiple text style matches from new catalog"); + } + + // Create a text span node, set the style attribute, make the + // text node(s) its children, and append it to current paragraph's + // list of children. + Element textSpanNode = doc.createElement(TAG_SPAN); + textSpanNode.setAttribute(ATTRIBUTE_TEXT_STYLE_NAME, trStyle.getName()); + for (int ii = 0; ii < trNodes.length; ii++) { + textSpanNode.appendChild(trNodes[ii]); + } + currPara.appendChild(textSpanNode); + log("</SPAN>"); + } + + else if (data[i].getClass() == WseFontTable.class) { + fontTable = (WseFontTable)data[i]; + } + + else if (data[i].getClass() == WseColorTable.class) { + colorTable = (WseColorTable)data[i]; + } + } + + + //NodeList r = doc.getElementsByTagName(TAG_OFFICE_DOCUMENT); + NodeList r = doc.getElementsByTagName(TAG_OFFICE_DOCUMENT_CONTENT); + Node rootNode = r.item(0); + + // read the original document + org.w3c.dom.NodeList nl; + if (origDoc != null) { + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + origDoc.write(bos); + SxwDocument origSxwDoc = new SxwDocument("old"); + origSxwDoc.read(new ByteArrayInputStream(bos.toByteArray())); + org.w3c.dom.Document origDomDoc = origSxwDoc.getContentDOM(); + + XmlUtil xu = new XmlUtil(); + org.w3c.dom.DocumentFragment df; + org.w3c.dom.Node newNode; + + // copy font declarations from original document to the new document + nl = origDomDoc.getElementsByTagName(TAG_OFFICE_FONT_DECLS); + df = doc.createDocumentFragment(); + newNode = xu.deepClone(df, nl.item(0)); + rootNode.insertBefore(newNode, bodyNode); + + // copy style catalog from original document to the new document + nl = origDomDoc.getElementsByTagName(TAG_OFFICE_STYLES); + df = doc.createDocumentFragment(); + newNode = xu.deepClone(df, nl.item(0)); + rootNode.insertBefore(newNode, bodyNode); + + nl = origDomDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + df = doc.createDocumentFragment(); + newNode = xu.deepClone(df, nl.item(0)); + rootNode.insertBefore(newNode, bodyNode); + + nl = origDomDoc.getElementsByTagName(TAG_OFFICE_MASTER_STYLES); + df = doc.createDocumentFragment(); + newNode = xu.deepClone(df, nl.item(0)); + rootNode.insertBefore(newNode, bodyNode); + } + + // Original document not specified. We need to add font declarations. + // DJP: this might just be for debugging. Merger will probably put + // the "real" ones in. + // DJP: if really doing it this way, do it right: gather font names + // from style catalog(s). + else { + org.w3c.dom.Node declNode; + + log("<FONT-DECLS/>"); + + declNode = doc.createElement(TAG_OFFICE_FONT_DECLS); + rootNode.insertBefore(declNode, bodyNode); + org.w3c.dom.Element fontNode; + + fontNode = doc.createElement(TAG_STYLE_FONT_DECL); + fontNode.setAttribute(ATTRIBUTE_STYLE_NAME, "Arial"); + fontNode.setAttribute(ATTRIBUTE_FO_FONT_FAMILY, "Arial"); + fontNode.setAttribute(ATTRIBUTE_STYLE_FONT_PITCH, "variable"); + declNode.appendChild(fontNode); + + fontNode = doc.createElement(TAG_STYLE_FONT_DECL); + fontNode.setAttribute(ATTRIBUTE_STYLE_NAME, "Arioso"); + fontNode.setAttribute(ATTRIBUTE_FO_FONT_FAMILY, "Arioso"); + fontNode.setAttribute(ATTRIBUTE_STYLE_FONT_PITCH, "variable"); + declNode.appendChild(fontNode); + } + + + // Now add any new styles we have created in this document. + nl = doc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + Node autoStylesNode = nl.item(0); + if (autoStylesNode == null) { + autoStylesNode = doc.createElement(TAG_OFFICE_AUTOMATIC_STYLES); + log("<OFFICE-AUTOMATIC-STYLES/>"); + rootNode.insertBefore(autoStylesNode, bodyNode); + } + + Node newStyleCatNode = styleCat.writeNode(doc, "dummy"); + nl = newStyleCatNode.getChildNodes(); + int nNodes = nl.getLength(); + for (int i = 0; i < nNodes; i++) { + autoStylesNode.appendChild(nl.item(0)); + } + + oldStyleCat.dumpCSV(true); + styleCat.dumpCSV(true); + return sxwDoc; + } + + + /** + * Sends message to the log object. + * + * @param str Debug message. + */ + private void log(String str) { + + Debug.log(Debug.TRACE, str); + } + + + /* + public static void main(String args[]) { + + // DocumentDeserializerImpl d = new DocumentDeserializerImpl(new InputStream()); + + Node nodes[] = parseText("Tab here:\tThen some more text"); + } +*/ +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentMergerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentMergerImpl.java new file mode 100644 index 000000000000..09c2b998f5c1 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentMergerImpl.java @@ -0,0 +1,102 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentMergerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.MergeException; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.Difference; +import org.openoffice.xmerge.merger.NodeMergeAlgorithm; +import org.openoffice.xmerge.merger.Iterator; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.diff.ParaNodeIterator; +import org.openoffice.xmerge.merger.diff.IteratorLCSAlgorithm; +import org.openoffice.xmerge.merger.merge.DocumentMerge; +import org.openoffice.xmerge.merger.merge.CharacterBaseParagraphMerge; +import org.openoffice.xmerge.util.Debug; + + +/** + * Wordsmith implementation of <code>DocumentMerger</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.PluginFactoryImpl + * PluginFactoryImpl}.</p> + */ +public class DocumentMergerImpl implements DocumentMerger { + + private ConverterCapabilities cc_; + private org.openoffice.xmerge.Document orig = null; + + public DocumentMergerImpl(org.openoffice.xmerge.Document doc, ConverterCapabilities cc) { + cc_ = cc; + this.orig = doc; + } + + public void merge(org.openoffice.xmerge.Document modifiedDoc) throws MergeException { + + SxwDocument wdoc1 = (SxwDocument) orig; + SxwDocument wdoc2 = (SxwDocument) modifiedDoc; + + Document doc1 = wdoc1.getContentDOM(); + Document doc2 = wdoc2.getContentDOM(); + + Iterator i1 = new ParaNodeIterator(cc_, doc1.getDocumentElement()); + Iterator i2 = new ParaNodeIterator(cc_, doc2.getDocumentElement()); + + DiffAlgorithm diffAlgo = new IteratorLCSAlgorithm(); + + // find out the paragrah level diffs + Difference[] diffTable = diffAlgo.computeDiffs(i1, i2); + + if (Debug.isFlagSet(Debug.INFO)) { + Debug.log(Debug.INFO, "Diff Result: "); + + for (int i = 0; i < diffTable.length; i++) { + Debug.log(Debug.INFO, diffTable[i].debug()); + } + } + + // merge the paragraphs + NodeMergeAlgorithm charMerge = new CharacterBaseParagraphMerge(); + DocumentMerge docMerge = new DocumentMerge(cc_, charMerge); + + Iterator result = null; + + docMerge.applyDifference(i1, i2, diffTable); + } +} + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentSerializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentSerializerImpl.java new file mode 100644 index 000000000000..207f38d263a3 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/DocumentSerializerImpl.java @@ -0,0 +1,539 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentSerializerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import java.io.IOException; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.PdbEncoder; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PdbUtil; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.util.*; +import org.openoffice.xmerge.converter.xml.*; + +/** + * <p>WordSmith implementation of + * org.openoffice.xmerge.DocumentSerializer + * for the {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>The <code>serialize</code> method traverses the DOM + * document from the given <code>Document</code> object. It uses a + * <code>DocEncoder</code> object for the actual conversion of + * contents to the WordSmith format.</p> + * + * @author Herbie Ong, David Proulx + */ + +// DJP: take out "implements OfficeConstants" +public final class DocumentSerializerImpl +implements OfficeConstants, DocumentSerializer { + + /** A WSEncoder object for encoding to WordSmith. */ + private WSEncoder encoder = null; + + /** The <code>StyleCatalog</code>. */ + private StyleCatalog styleCat = null; + + private WseFontTable fontTable = new WseFontTable(); + private WseColorTable colorTable = new WseColorTable(); + + /** + * The <code>SxwDocument</code> object that this converter + * processes. + */ + private SxwDocument sxwDoc = null; + + /** + * Constructor. + * + * @param doc The <code>Document</code> to convert. + */ + public DocumentSerializerImpl(Document doc) { + sxwDoc = (SxwDocument) doc; + } + + + /** + * <p>Method to convert a <code>Document</code> into a + * <code>PalmDocument</code>.</p> + * + * <p>This method is not thread safe for performance reasons. + * This method should not be called from within two threads. + * It would be best to call this method only once per object + * instance.</p> + * + * <p>Note that the doc parameter needs to be an XML + * <code>Document</code>, else this method will throw a + * <code>ClassCastException</code>. I think this is a hack, + * but this is the only way to not modify most of the existing + * code right now.</p> + * + * @param doc Input should be an XML <code>Document</code> + * object + * @param os Output of <code>PalmDB</code> object + * + * @throws ConvertException If any conversion error occurs. + * @throws IOException If any I/O error occurs. + */ + public ConvertData serialize() + throws IOException { + + + // get the server document name + String docName = sxwDoc.getName(); + + // get DOM document + org.w3c.dom.Document domDoc = sxwDoc.getContentDOM(); + + // Create WordSmith encoder object. Add WordSmith header, + // empty font table to it. + encoder = new WSEncoder(); + encoder.addElement(fontTable); + encoder.addElement(colorTable); + + // Read the styles into the style catalog + String families[] = new String[3]; + families[0] = "text"; + families[1] = "paragraph"; + families[2] = "paragraph"; + Class classes[] = new Class[3]; + classes[0] = TextStyle.class; + classes[1] = ParaStyle.class; + classes[2] = TextStyle.class; + styleCat = new StyleCatalog(25); + + // Parse the input document + // DJP todo: eliminate multiple calls to add() when it can + // recurse properly. + NodeList nl = domDoc.getElementsByTagName(TAG_OFFICE_STYLES); + styleCat.add(nl.item(0), families, classes, null, false); + nl = domDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + styleCat.add(nl.item(0), families, classes, null, false); + nl = domDoc.getElementsByTagName(TAG_OFFICE_MASTER_STYLES); + styleCat.add(nl.item(0), families, classes, null, false); + + // Traverse to the office:body element. + // There should only be one. + NodeList list = domDoc.getElementsByTagName(TAG_OFFICE_BODY); + int len = list.getLength(); + if (len > 0) { + Node node = list.item(0); + traverseBody(node); + } + + // create a PalmDB object and ConvertData object. + // + Record records[] = encoder.getRecords(); + + ConvertData cd = new ConvertData(); + PalmDocument palmDoc = new PalmDocument(docName, + PdbUtil.intID("WrdS"), PdbUtil.intID("BDOC"), 0, + PalmDB.PDB_HEADER_ATTR_BACKUP, records); + cd.addDocument(palmDoc); + return cd; + } + + + /** + * This method traverses <i>office:body</i> element. + * + * @param node <i>office:body</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseBody(Node node) throws IOException { + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH) || + nodeName.equals(TAG_HEADING)) { + + traverseParagraph(child); + + } else if (nodeName.equals(TAG_UNORDERED_LIST)) { + + traverseList(child); + + } else if (nodeName.equals(TAG_ORDERED_LIST)) { + + traverseList(child); + + } else { + + Debug.log(Debug.INFO, "<OTHERS " /* + XmlDebug.nodeInfo(child) */ + " />"); + } + } + } + } + + } + + + /** + * This method traverses the <i>text:p</i> and <i>text:h</i> + * element <code>Node</code> objects. + * + * @param node A <i>text:p</i> or <i>text:h</i> <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseParagraph(Node node) throws IOException { + + String styleName = findAttribute(node, "text:style-name"); + ParaStyle pstyle = (ParaStyle)styleCat.lookup(styleName, "paragraph", + null, ParaStyle.class); + + // If the style does not exist in the style catalog for some reason, + // make up a default style and use it. We'll have to add this default + // style to the style catalog the first time it is used. + if (pstyle == null) { + styleName = "CONVERTER-DEFAULT"; + pstyle = (ParaStyle)styleCat.lookup(styleName, "paragraph", null, + ParaStyle.class); + if (pstyle == null) { + pstyle = new ParaStyle(styleName, "paragraph", null, + (String [])null, null, styleCat); + styleCat.add(pstyle); + styleCat.add(new TextStyle(styleName, "paragraph", null, + 0, 0, 12, "Times-Roman", styleCat)); + } + } + + pstyle = (ParaStyle)pstyle.getResolved(); + encoder.addElement(new WsePara(pstyle, styleCat)); + TextStyle defParaTextStyle = (TextStyle) + styleCat.lookup(styleName, "paragraph", null, TextStyle.class); + + traverseParaContents(node, defParaTextStyle); + } + + + /** + * This method traverses a paragraph content. Note that this + * method may recurse to call itself. + * + * @param node A paragraph or content <code>Node</code> + */ + private void traverseParaContents(Node node, TextStyle defTextStyle) { + + String styleName = findAttribute(node, "text:style-name"); + TextStyle style = (TextStyle) + styleCat.lookup(styleName, "text", null, TextStyle.class); + + if (node.hasChildNodes()) { + NodeList nodeList = node.getChildNodes(); + int nChildren = nodeList.getLength(); + + for (int i = 0; i < nChildren; i++) { + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.TEXT_NODE) { + + // this is for grabbing text nodes. + String s = child.getNodeValue(); + + if (s.length() > 0) { + if (style != null) + encoder.addElement(new WseTextRun(s, style, styleCat, + fontTable, colorTable)); + else + encoder.addElement(new WseTextRun(s, defTextStyle, + styleCat, fontTable, colorTable)); + } + + } else if (child.getNodeType() == Node.ELEMENT_NODE) { + + String childNodeName = child.getNodeName(); + + if (childNodeName.equals(TAG_SPACE)) { + + // this is for text:s tags. + NamedNodeMap map = child.getAttributes(); + Node attr = map.getNamedItem(ATTRIBUTE_SPACE_COUNT); + StringBuffer space = new StringBuffer(" "); + int count = 1; + + if (attr != null) { + try { + String countStr = attr.getNodeValue(); + count = Integer.parseInt(countStr.trim()); + } catch (NumberFormatException e) { + Debug.log(Debug.ERROR, "Problem parsing space tag", e); + } + } + + for (int j = 1; j < count; j++) + space.append(" "); + + encoder.addElement(new WseTextRun(space.toString(), + defTextStyle, + styleCat, fontTable, colorTable)); + Debug.log(Debug.INFO, "<SPACE count=\"" + count + "\" />"); + + } else if (childNodeName.equals(TAG_TAB_STOP)) { + + // this is for text:tab-stop + encoder.addElement(new WseTextRun("\t", defTextStyle, styleCat, + fontTable, colorTable)); + + Debug.log(Debug.INFO, "<TAB/>"); + + } else if (childNodeName.equals(TAG_LINE_BREAK)) { + + // this is for text:line-break + encoder.addElement(new WseTextRun("\n", defTextStyle, + styleCat, fontTable, colorTable)); + + Debug.log(Debug.INFO, "<LINE-BREAK/>"); + + } else if (childNodeName.equals(TAG_SPAN)) { + + // this is for text:span + Debug.log(Debug.INFO, "<SPAN>"); + traverseParaContents(child, defTextStyle); + Debug.log(Debug.INFO, "</SPAN>"); + + } else if (childNodeName.equals(TAG_HYPERLINK)) { + + // this is for text:a + Debug.log(Debug.INFO, "<HYPERLINK>"); + traverseParaContents(child, defTextStyle); + Debug.log(Debug.INFO, "<HYPERLINK/>"); + + } else if (childNodeName.equals(TAG_BOOKMARK) || + childNodeName.equals(TAG_BOOKMARK_START)) { + + Debug.log(Debug.INFO, "<BOOKMARK/>"); + + } else { + + Debug.log(Debug.INFO, "<OTHERS " /* + XmlDebug.nodeInfo(child) */ + " />"); + } + + } + + } + } + } + + + /** + * This method traverses list tags <i>text:unordered-list</i> and + * <i>text:ordered-list</i>. A list can only contain one optional + * <i>text:list-header</i> and one or more <i>text:list-item</i> + * elements. + * + * @param node A list <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseList(Node node) throws IOException { + + Debug.log(Debug.TRACE, "<LIST>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_LIST_ITEM)) { + + traverseListItem(child); + + } else if (nodeName.equals(TAG_LIST_HEADER)) { + + traverseListHeader(child); + + } else { + + Debug.log(Debug.ERROR, "<INVALID-XML-BUG " + " />"); + } + } + } + } + + Debug.log(Debug.TRACE, "</LIST>"); + } + + + /** + * This method traverses a <i>text:list-header</i> element. + * It contains one or more <i>text:p</i> elements. + * + * @param node A list header <code>Node</code>. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseListHeader(Node node) throws IOException { + + Debug.log(Debug.TRACE, "<LIST-HEADER>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH)) { + + traverseParagraph(child); + + } else { + + Debug.log(Debug.TRACE, "<INVALID-XML-BUG " + " />"); + } + } + } + } + + Debug.log(Debug.TRACE, "</LIST-HEADER>"); + } + + + /** + * This method will traverse a <i>text:list-item</i>. + * A list item may contain one or more of <i>text:p</i>, + * <i>text:h</i>, <i>text:section</i>, + * <i>text:ordered-list</i> and <i>text:unordered-list</i>. + * + * This method currently only implements grabbing <i>text:p</i>, + * <i>text:h</i>, <i>text:unordered-list</i> and + * <i>text:ordered-list</i>. + * + * @param Node <code>Node</code> to traverse. + * + * @throws IOException If any I/O error occurs. + */ + private void traverseListItem(Node node) throws IOException { + + Debug.log(Debug.TRACE, "<LIST-ITEM>"); + + if (node.hasChildNodes()) { + + NodeList nodeList = node.getChildNodes(); + int len = nodeList.getLength(); + + for (int i = 0; i < len; i++) { + + Node child = nodeList.item(i); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + + String nodeName = child.getNodeName(); + + if (nodeName.equals(TAG_PARAGRAPH)) { + + traverseParagraph(child); + + } else if (nodeName.equals(TAG_UNORDERED_LIST)) { + + traverseList(child); + + } else if (nodeName.equals(TAG_ORDERED_LIST)) { + + traverseList(child); + + } else { + + Debug.log(Debug.ERROR, "<INVALID-XML-BUG " + " />"); + } + } + } + } + + Debug.log(Debug.TRACE, "</LIST-ITEM>"); + } + + + /** + * Look up a <code>Node</code> object's named attribute and return + * its value + * + * @param node The <code>Node</code>. + * @param name The attribute name. + * + * @return The value of the named attribute + */ + private String findAttribute(Node node, String name) { + NamedNodeMap attrNodes = node.getAttributes(); + if (attrNodes != null) { + int len = attrNodes.getLength(); + for (int i = 0; i < len; i++) { + Node attr = attrNodes.item(i); + if (attr.getNodeName().equals(name)) + return attr.getNodeValue(); + } + } + return null; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/PluginFactoryImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/PluginFactoryImpl.java new file mode 100644 index 000000000000..56dd2a4fb53f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/PluginFactoryImpl.java @@ -0,0 +1,152 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PluginFactoryImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.DocumentMergerFactory; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxw.SxwPluginFactory; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.registry.ConverterInfo; + +import java.io.InputStream; +import java.io.IOException; + + +/** + * <p>WordSmith implementation of a <code>PluginFactory</code> that + * encapsulates conversion of StarWriter XML format to and from + * WordSmith format.</p> + * + * The superclass produces a particular + * {@link org.openoffice.xmerge.Document Document} + * object, i.e. + * {@link org.openoffice.xmerge.converter.xml.sxw.SxwDocument + * SxwDocument} that the converters in this class works with. Thus, + * this class only implements the methods that produces the converters, + * i.e. {@link + * org.openoffice.xmerge.DocumentSerializer + * DocumentSerializer} and {@link + * org.openoffice.xmerge.DocumentDeserializer + * DocumentDeserializer}; + * as well as the {@link + * org.openoffice.xmerge.ConverterCapabilities + * ConverterCapabilities} object that is specific to this format + * conversion. That superclass also produces a {@link + * org.openoffice.xmerge.DocumentMerger DocumentMerger} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.DocumentMergerImpl + * DocumentMergerImpl} which this class derives the functionality.</p> + * + * @author Herbie Ong, Dave Proulx + */ +public final class PluginFactoryImpl extends SxwPluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory, + DocumentMergerFactory { + + public PluginFactoryImpl(ConverterInfo ci) { + super(ci); + } + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + /** + * Returns an instance of <code>DocumentSerializerImpl</code>, which is + * an implementation of <code>DocumentSerializer</code> interface. + * + * @param doc <code>Document</code> object to be converted/serialized. + * + * @return A <code>DocumentSerializerImpl</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + + return new DocumentSerializerImpl(doc); + } + + + /** + * Returns an instance of <code>DocumentDeserializerImpl</code>, + * which is an implementation of <code>DocumentDeserializer</code> + * interface. + * + * @param cd <code>ConvertData</code> object for reading data + * which will be converted back to a + * <code>Document</code> object. + * + * @return A <code>DocumentDeserializerImpl</code> object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + + return new DocumentDeserializerImpl(cd); + } + + /** + * Returns an instance of <code>DocumentMergerImpl</code>, + * which is an implementation of the <code>DocumentMerger</code> + * interface. + * + * @param doc <code>Document</code> to merge. + * + * @return A DocumentMergerImpl object. + */ + public DocumentMerger createDocumentMerger(Document doc) { + + ConverterCapabilities cc = converterCap; + DocumentMergerImpl merger = new DocumentMergerImpl(doc, cc); + return merger; + } + + /** + * Returns an instance of the DeviceDocument + * which is an implementation of the <code>DocumentMerger</code> + * interface. + * + * @param doc <code>Document</code> to merge. + * + * @return A Device Document object + */ + public Document createDeviceDocument(String name, InputStream is) + throws IOException { + + PalmDocument palmDoc = new PalmDocument(is); + return palmDoc; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WSDecoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WSDecoder.java new file mode 100644 index 000000000000..77ba70f6ac2a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WSDecoder.java @@ -0,0 +1,355 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WSDecoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import org.openoffice.xmerge.util.Debug; + +import org.openoffice.xmerge.converter.palm.*; +import org.openoffice.xmerge.util.Resources; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.DocumentDeserializerImpl + * DocumentDeserializerImpl} to decode a WordSmith format. It currently + * decodes the text content into a single <code>String</code> object. + * + * @author Herbie Ong, David Proulx + */ +final class WSDecoder implements DOCConstants { + + /** For decoding purposes. */ + private final static int COUNT_BITS = 3; + + /** Resources object for I18N. */ + private Resources res = null; + + /** + * Default constructor creates a header and + * a text buffer for holding all the text in + * the DOC db. + */ + WSDecoder() { + res = Resources.getInstance(); + } + + /** + * Decode the text records into a single <code>byte</code> array. + * + * @param Record <code>Record</code> array holding WordSmith + * contents. + * + * @throws IOException If any I/O error occurs. + */ + byte[] parseRecords(Record[] recs) throws IOException { + + // read the header record + HeaderInfo header = readHeader(recs[0].getBytes()); + dumpHeader(header); + byte[][] byteArrays = new byte[recs.length - 1][]; + for (int i = 0; i < recs.length - 1; i++) byteArrays[i] = null; + + switch (header.version & ~4) { // DJP: "4" indicates OOB data is present. + // Add a constant to handle this, might also need code to handle it. + + case COMPRESSED: + case 3: // DJP: determined this empirically. Are Herbie's constants wrong? + for (int i = 1; i < recs.length; i++) { + byteArrays[i-1] = decompress(recs[i].getBytes(), + header.textRecordSize); + Debug.log(Debug.INFO, "processing " + byteArrays[i-1].length + " bytes"); + } + + break; + + case UNCOMPRESSED: + for (int i = 1; i < recs.length; i++) { + byteArrays[i-1] = recs[i].getBytes(); + Debug.log(Debug.INFO, "processing " + byteArrays[i-1].length + " bytes"); + } + + break; + + default: + throw new IOException(res.getString("UNKNOWN_DOC_VERSION")); + + } + + // Concatenate byteArrays[][] into a single byte array. + int length = 0; + for (int i = 0; i < recs.length - 1; i++) + length += byteArrays[i].length; + byte bigArray[] = new byte[length]; + int offset = 0; + for (int i = 0; i < recs.length - 1; i++) { + System.arraycopy(byteArrays[i], 0, bigArray, offset, + byteArrays[i].length); + offset += byteArrays[i].length; + } + return bigArray; + } + + + /** + * Decode the text records into a <code>Wse</code> array. + * + * @param Record[] <code>Record</code> array holding DOC + * contents. + * + * @throws IOException If any I/O error occurs. + */ + Wse[] parseDocument(Record[] recs) throws IOException { + + java.util.Vector v = new java.util.Vector(20, 20); + WseFontTable fontTable = null; + WseColorTable colorTable = null; + + // rawData is the document data to be parsed. + byte rawData[] = parseRecords(recs); + + // beginning of document has some header information, including + // optional font and color tables. + // DJP: maybe should add a new WSelement (docHeader) to hold + // header info. + // DJP: finish code here to parse header + if (rawData[0] != 2) throw new IOException(); + int nParagraphs = util.intFrom4bytes(rawData, 2); + int nAtoms = util.intFrom4bytes(rawData, 6); + int nChars = util.intFrom4bytes(rawData, 10); + int miscSize = util.intFrom4bytes(rawData, 14); + int curIndex = 18; + + while (curIndex < rawData.length) { + if (WsePara.isValid(rawData, curIndex)) { + v.add(new WsePara(rawData, curIndex)); + curIndex = WsePara.computeNewIndex(rawData, curIndex); + } else if (WseTextRun.isValid(rawData, curIndex)) { + v.add(new WseTextRun(rawData, curIndex, fontTable, colorTable)); + curIndex = WseTextRun.computeNewIndex(rawData, curIndex); + } else if (WseFontTable.isValid(rawData, curIndex)) { + fontTable = new WseFontTable(rawData, curIndex); + v.add(fontTable); + curIndex = WseFontTable.computeNewIndex(rawData, curIndex); + } else if (WseColorTable.isValid(rawData, curIndex)) { + colorTable = new WseColorTable(rawData, curIndex); + v.add(colorTable); + curIndex = WseColorTable.computeNewIndex(rawData, curIndex); + } else { + Debug.log(Debug.ERROR, "Unknown code " + rawData[curIndex]); + throw new IOException(); + } + } + + return (Wse[])v.toArray(new Wse[2]); + } + + + /** + * <p>Decompress the <code>byte</code> array.</p> + * + * <p>The resulting uncompressed <code>byte</code> array + * should be within <code>textRecordSize</code> length, + * definitely within twice the size it claims, else treat + * it as a problem with the encoding of that PDB and + * throw <code>IOException</code>.</p> + * + * @param bytes Compressed <code>byte</code> array + * @param textRecordSize Size of uncompressed <code>byte</code> + * array + * + * @throws IOException If <code>textRecordSize</codeL < + * <code>cBytes.length</code>. + */ + private byte[] decompress(byte[] cBytes, int textRecordSize) + throws IOException { + + // create byte array for storing uncompressed bytes + // it should be within textRecordSize range, definitely + // within twice of textRecordSize! if not, then + // an ArrayIndexOutOfBoundsException will get thrown, + // and it should be converted into an IOException, and + // treat it as a conversion error. + byte[] uBytes = new byte[textRecordSize*2]; + + int up = 0; + int cp = 0; + + try { + + while (cp < cBytes.length) { + + int c = cBytes[cp++] & 0xff; + + // codes 1...8 mean copy that many bytes + if (c > 0 && c < 9) { + + while (c-- > 0) + uBytes[up++] = cBytes[cp++]; + } + + // codes 0, 9...0x7F represent themselves + else if (c < 0x80) { + uBytes[up++] = (byte) c; + } + + // codes 0xC0...0xFF represent "space + ascii char" + else if (c >= 0xC0) { + uBytes[up++] = (byte) ' '; + uBytes[up++] = (byte) (c ^ 0x80); + } + + // codes 0x80...0xBf represent sequences + else { + c <<= 8; + c += cBytes[cp++] & 0xff; + int m = (c & 0x3fff) >> COUNT_BITS; + int n = c & ((1 << COUNT_BITS) - 1); + n += COUNT_BITS; + while (n-- > 0) { + uBytes[up] = uBytes[up - m]; + up++; + } + } + } + + } catch (ArrayIndexOutOfBoundsException e) { + + throw new IOException( + res.getString("DOC_TEXT_RECORD_SIZE_EXCEEDED")); + } + + // note that ubytes may be larger that the amount of + // uncompressed bytes, so trim it to another byte array + // with the exact size. + byte[] textBytes = new byte[up]; + System.arraycopy(uBytes, 0, textBytes, 0, up); + + return textBytes; + } + + + /** + * Read the header <code>byte</code> array. + * + * @param bytes <code>byte</code> array containing header + * record data. + * + * @return <code>HeaderInfo</code> object. + * + * @throws IOException If any I/O error occurs. + */ + private HeaderInfo readHeader(byte[] bytes) throws IOException { + + HeaderInfo header = new HeaderInfo(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + DataInputStream dis = new DataInputStream(bis); + + // Normally the first 2 bytes comprised of the version + // which should either be COMPRESSED or UNCOMPRESSED + // SmartDoc/Quickword would add a 0x01 to the first + // byte, thus their version would be 0x0101 for UNCOMPRESSED + // instead of 0x0001 and 0x0102 for UNCOMPRESSED instead of + // 0x0002. + + dis.readByte(); + header.version = dis.readByte(); + + // read extra 2 unused bytes + dis.readShort(); + + // Read the text length, this should be unsigned 4 bytes. + // We could store the read value into a long, but then + // our current buffer limit is the max positive of an int. + // That is a large enough limit, thus we shall stay with + // storing the value in an int. If it exceeds, then + // an IOException should be thrown. + header.textLen = dis.readInt(); + if (header.textLen < 0) { + throw new IOException(res.getString("DOC_TEXT_LENGTH_EXCEEDED")); + } + + // read the number of records - unsigned 2 bytes + header.textRecordCount = ((int) dis.readShort()) & 0x0000ffff; + + // read the record size - unsigned 2 bytes + header.textRecordSize = ((int) dis.readShort()) & 0x0000ffff; + + // read extra 4 unused bytes + dis.readInt(); + + return header; + } + + + /** + * Prints out header info into log. + * Used for debugging purposes only. + * + * @param header <code>HeaderInfo</code> structure. + */ + private void dumpHeader(HeaderInfo header) { + /* + log("<DOC_INFO "); + log("version=\"" + header.version + "\" "); + log("text-length=\"" + header.textLen + "\" "); + log("number-of-records=\"" + header.textRecordCount + "\" "); + log("record-size=\"" + header.textRecordSize + "\" />\n"); + */ + } + + + /** + * Inner class to store DOC header information. + */ + private class HeaderInfo { + + /** length of text section */ + int textLen = 0; + + /** number of text records */ + int textRecordCount = 0; + + /** + * size of a text record. This is normally the same as + * TEXT_RECORD_SIZE, but some applications may modify this. + */ + int textRecordSize = 0; + + /** compression type */ + int version = 0; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WSEncoder.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WSEncoder.java new file mode 100644 index 000000000000..58df6112a8f4 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WSEncoder.java @@ -0,0 +1,215 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WSEncoder.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.*; +import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.ArrayList; +import java.util.Vector; + +import org.openoffice.xmerge.converter.palm.*; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxw.wordsmith.DocumentDeserializerImpl + * DocumentDeserializerImpl} to encode the WordSmith format. + * + * @author David Proulx + */ + +// DJP: replace 4096 w/ a defined constant + +final class WSEncoder { + + /* DJP: These should probably go somewhere else! */ + /** Constant for uncompressed version. */ + public static final short UNCOMPRESSED = 1; + + /** Constant for compressed version. */ + public static final short COMPRESSED = 2; + + /** Constant used for spare fields. */ + public static final int SPARE = 0; + + /* WordSmith Header information. */ + private short version; + private int textLen; + private short maxRecSize; + private int textRecCount = 0; + + + /* WordSmith document elements. */ + WseHeader header = null; + WseFontTable ft = null; + WseColorTable ct = null; + private Vector elements; // paragraphs & text runs + + /* Totals for the WordSmith document. */ + int nrParagraphs = 0; + int nrAtoms = 0; + int nrChars = 0; + + + /** + * Default constructor creates a header and + * a text buffer for holding all the text in + * the WordSmith database. + */ + WSEncoder() { + version = 1; + textLen = 0; + maxRecSize = 4096; + elements = new Vector(); + } + + + /** + * This method adds a new element to the WordSmith document. + * + * @param elem WordSmith document element to add + */ + void addElement(Wse elem) { + if (elem.getClass() == WseHeader.class) + header = (WseHeader)elem; + else if (elem.getClass() == WseFontTable.class) + ft = (WseFontTable)elem; + else if (elem.getClass() == WseColorTable.class) + ct = (WseColorTable)elem; + else + elements.addElement(elem); + } + + + /** + * This method encodes the information given to + * an array of palm Records in the WordSmith database format. + * + * @return <code>Record</code> array holding WordSmith contents. + * + * @throws IOException If any I/O error occurs. + */ + Record[] getRecords() throws IOException { + + Vector allRecs = new Vector(); + int nElements = elements.size(); + + // Count up the number of paragraphs, atoms, and characters. + int currElement = 0; + while (currElement < nElements) { + Wse e = (Wse)elements.elementAt(currElement++); + if (e.getClass() == WsePara.class) + nrParagraphs++; + if (e.getClass() == WseTextRun.class) { + nrAtoms++; + nrChars += ((WseTextRun)e).getText().length(); + } + } + + byte[] currRec = new byte[4096]; + int currRecLen = 0; + + // This code assumes that the WordSmith header, font table, + // and color table total less than 4096 bytes. + header = new WseHeader(nrParagraphs, nrAtoms, nrChars, ft, ct); + System.arraycopy(header.getBytes(), 0, + currRec, currRecLen, header.getByteCount()); + currRecLen += header.getByteCount(); + + if (ft != null) { + System.arraycopy(ft.getBytes(), 0, currRec, currRecLen, + ft.getByteCount()); + currRecLen += ft.getByteCount(); + } + if (ct != null) { + System.arraycopy(ct.getBytes(), 0, currRec, currRecLen, + ct.getByteCount()); + currRecLen += ct.getByteCount(); + } + + currElement = 0; + while (currElement < nElements) { + Wse e = (Wse)elements.elementAt(currElement++); + int length = e.getByteCount(); + if ((length + currRecLen) <= 4096) { + System.arraycopy(e.getBytes(), 0, currRec, currRecLen, length); + currRecLen += length; + } else { + // Copy in enough to get to full size, then create a + // new Record and add it to the Vector. + int firstPartLen = 4096 - currRecLen; + System.arraycopy(e.getBytes(), 0, currRec, currRecLen, + firstPartLen); + Record r = new Record(currRec); + allRecs.addElement(r); + + // Put the remainder at the beginning of the next record + currRecLen = 0; + System.arraycopy(e.getBytes(), firstPartLen, currRec, + currRecLen, length - firstPartLen); + currRecLen += length - firstPartLen; + } + } + + // Processed all the elements. Write out any remaining partial record. + if (currRecLen > 0) { + byte[] partial = new byte[currRecLen]; + System.arraycopy(currRec, 0, partial, 0, currRecLen); + Record rr = new Record(partial); + allRecs.addElement(rr); + } + + + // Record 0 is the WordSmith header. Do it last since it + // contains totals for the entire document. It goes + // before everything else. + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeShort(version); + dos.writeShort(0); + dos.writeInt(textLen); + dos.writeShort(allRecs.size()); + dos.writeShort(maxRecSize); + dos.writeInt(0); + allRecs.insertElementAt(new Record(bos.toByteArray()), 0); + + // Convert Vector of Records to an array and return it. + int nRecs = allRecs.size(); + Record recs[] = new Record[nRecs]; + for (int i = 0; i < nRecs; i++) + recs[i] = (Record)allRecs.elementAt(i); + return recs; + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/Wse.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/Wse.java new file mode 100644 index 000000000000..1df80a427594 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/Wse.java @@ -0,0 +1,103 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Wse.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.IOException; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.xml.*; + + +/** + * This is the superclass for all elements in a WordSmith document. + * Elements can be paragraphs, text runs, font tables, or color tables. + * + * @author David Proulx + */ +abstract class Wse { + + /** + * Return true if <code>dataArray[startIndex]</code> is the start + * of a valid element of this type. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return true if <code>dataArray[startIndex]</code> is the + * start of a valid element of this type, false otherwise. + */ + static boolean isValid(byte dataArray[], int startIndex) { + return false; + } + + + /** + * Compute and return the index of the first <code>byte</code> + * following this element. It is assumed that the element + * starting at <code>dataArray[startIndex]</code> is valid. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return The index of the first <code>byte</code> following + * this element. + */ + static int computeNewIndex(byte dataArray[], int startIndex) { + return 0; + } + + + /** + * Return the total number of bytes needed to represent this + * object. + * + * @return The total number of bytes needed to represent this + * object. + */ + abstract int getByteCount(); + + + /** + * Return an <code>byte</code> array representing this element. + * + * @return An <code>bytes</code> array representing this element. + */ + abstract byte[] getBytes(); +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseColorTable.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseColorTable.java new file mode 100644 index 000000000000..8d36c5d8a9a8 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseColorTable.java @@ -0,0 +1,250 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WseColorTable.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.IOException; +import java.awt.Color; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.xml.*; + +/** + * This class represents a color table in a WordSmith document. + * + * @author David Proulx + */ +class WseColorTable extends Wse { + + private Color fgColors[]; + private Color bgColors[]; + + /** + * Constructor to use when going from DOM to WordSmith + */ + public WseColorTable() { + fgColors = new Color[16]; + bgColors = new Color[16]; + + // Always need these two! + fgColors[0] = Color.black; + bgColors[0] = Color.white; + + } + + /** + * Constructor to use when going from WordSmith to DOM. + * + * @param dataArray <code>byte</code> array. + * @param i The index. + */ + public WseColorTable(byte dataArray[], int i) { + fgColors = new Color[16]; + bgColors = new Color[16]; + + i += 2; // Skip leading "64" and table length field. + for (int k = 0; k < 16; k++) { + fgColors[k] = new Color(((int)dataArray[i+1]) & 0xFF, + ((int)dataArray[i+2]) & 0xFF, + ((int)dataArray[i+3]) & 0xFF); + i += 4; + } + for (int k = 0; k < 16; k++) { + bgColors[k] = new Color(((int)dataArray[i+1]) & 0xFF, + ((int)dataArray[i+2]) & 0xFF, + ((int)dataArray[i+3]) & 0xFF); + i += 4; + } + + } + + + /** + * Compute the index of the first <code>byte</code> following the + * paragraph descriptor, assuming that + * <code>dataArray[startIndex]</code> is the beginning of a valid + * paragraph descriptor. + * + * @param dataArray <code>byte</code array. + * @param startIndex The start index. + * + * @return The index of the first <code>byte</code> following the + * paragraph description. + */ + static int computeNewIndex(byte dataArray[], int startIndex) { + int tableLen = dataArray[startIndex + 1]; + tableLen &= 0xFF; // eliminate problems with sign-extension + return startIndex + tableLen + 2; + } + + + /** + * Return true if <code>dataArray[startIndex]</code> is the start + * of a valid paragraph descriptor. + * + * @param dataArray <code>byte</code> array. + * @param startIndex Start index. + * + * @return true if <code>dataArray[startIndex]</code> is the start + * of a valid paragraph descriptor, false otherwise. + */ + static boolean isValid(byte dataArray[], int startIndex) { + try { + if (dataArray[startIndex] != 64) + return false; + int len = dataArray[startIndex + 1]; + len &= 0xFF; // eliminate problems with sign-extension + int temp = dataArray[startIndex + (int)len + 2]; // probe end of table + } catch (ArrayIndexOutOfBoundsException e) { + return false; + } + return true; + } + + + /** + * Return the number of bytes needed to represent this color table. + * + * @return The byte count. + */ + int getByteCount() { + return (32 * 4) + 1 + 1; + } + + + /** + * Return a <code>byte</code> array representing this color table. + * + * @return <code>bytes</code> array representing this color table. + */ + byte[] getBytes() { + byte[] b = new byte[(32 * 4) + 1 + 1]; + b[0] = 0x40; + b[1] = (byte)128; + int i = 2; + // int indVal = 0xd8; + int indVal = 0; + + for (int j = 0; j < 16; j++) { + b[i++] = (byte)indVal++; + if (fgColors[j] != null) { + b[i++] = (byte)fgColors[j].getRed(); + b[i++] = (byte)fgColors[j].getGreen(); + b[i++] = (byte)fgColors[j].getBlue(); + } else { + b[i++] = (byte)0; + b[i++] = (byte)0; + b[i++] = (byte)0; + } + } + + for (int j = 0; j < 16; j++) { + b[i++] = (byte)indVal++; + if (bgColors[j] != null) { + b[i++] = (byte)bgColors[j].getRed(); + b[i++] = (byte)bgColors[j].getGreen(); + b[i++] = (byte)bgColors[j].getBlue(); + } else { + b[i++] = (byte)0xFF; + b[i++] = (byte)0xFF; + b[i++] = (byte)0xFF; + } + } + + return b; + } + + + /** + * Return the index of the specified foreground or background + * <code>Color</code>. (If the color is not already in the table, + * it will be added.) + * + * Note that the implementation of this may include a "margin of + * error" to prevent the color table from being filled up too + * quickly. + * + * @param c The <code>Color</code>. + * @param foreground true if foreground color, false if background + * color + * + * @return The index of the specified foreground or background + * <code>Color</code>. + * + * DJP: how to handle table overflow? + */ + int findColor(Color c, boolean foreground) { + + Color colorArray[] = foreground ? fgColors : bgColors; + + for (int i = 0; i < 16; i++) { + if (colorArray[i] != null) { + if (colorArray[i].equals(c)) + return i; + } + else + break; // hit a null entry - no more colors in table! + } + + // Color was not found in the table. Add it. + for (int i = 0; i < 16; i++) { + if (colorArray[i] == null) { + colorArray[i] = c; + return i; + } + } + return 0; // Default - we should never get here though. + } + + + /** + * Given an index, return the <code>Color</code> from the table. + * + * @param index The index + * @param foreground true if foreground color, false if background + * color + * + * @return The <code>Color</code> at the specified index. + */ + Color getColor(int index, boolean foreground) { + + Color colorArray[] = foreground ? fgColors : bgColors; + return colorArray[index]; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseFontTable.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseFontTable.java new file mode 100644 index 000000000000..120dfb86a16f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseFontTable.java @@ -0,0 +1,221 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WseFontTable.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.IOException; + +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.xml.*; + +/** + * <p>This class represents a font table in a WordSmith document. + * A font table is represented as follows:</p> + * + * <p><blockquote> + * binary "3"<br> + * two-byte length of the table of strings which follows<br> + * string table (null-terminated strings) representing font names + * </blockquote></p> + * + * @author David Proulx + */ +class WseFontTable extends Wse { + + java.util.Vector fontNames = new java.util.Vector(10); + + + /** + * Constructor for use when going from DOM to WordSmith. + */ + public WseFontTable() { + } + + + /** + * Constructor for use when going from WordSmith to DOM. + * + * @param dataArray <code>byte</code> array. + * @param i The index. + */ + public WseFontTable(byte dataArray[], int i) { + i++; + int tableLen = ((dataArray[i] << 8) | (dataArray[i+1] & 0xFF)); + i += 2; + while (tableLen > 0) { + int j = 0; + while (dataArray[i + j] != 0) j++; + fontNames.add(new String(dataArray, i, j)); + tableLen -= (j + 1); + i += (j + 1); + } + } + + + /** + * Add a new font to the table. + * + * @param newFontName The new font name. + */ + public void add(String newFontName) { + if (newFontName != null) + fontNames.add(newFontName); + } + + + /** + * Return a font name from the table, or null if invalid index. + * + * @param index The font name index. + * + * @return The font name. + */ + public String getFontName(int index) { + try { + return (String)fontNames.elementAt(index); + } catch (ArrayIndexOutOfBoundsException e) { + return null; + } + } + + /** + * Return the index of a font name in the table, or -1 if not found. + * + * @param fontName The font name. + * + * @return The index of the font name, or -1 if not found. + */ + public int getFontIndex(String fontName) { + int len = fontNames.size(); + for (int i = 0; i < len; i++) { + String name = (String) fontNames.elementAt(i); + if (name.equals(fontName)) + return i; + } + return -1; + } + + + /** + * Compute the index of the first <code>byte</code> following the + * paragraph descriptor, assuming that + * <code>dataArray[startIndex]</code> is the beginning of a valid + * paragraph descriptor. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return The index of the first <code>byte</code> following the + * paragraph description. + */ + static int computeNewIndex(byte dataArray[], int startIndex) { + startIndex++; // Skip the leading "3" + int tableLen = ((dataArray[startIndex] << 8) | (dataArray[startIndex+1] & 0xFF)); + tableLen &= 0xFFFF; // eliminate problems with sign-extension + return startIndex + tableLen + 2; + } + + + /** + * Return true if <code>dataArray[startIndex]</code> is the start of a + * valid paragraph descriptor. + * + * @param dataArray <code>byte</code> string. + * @param startIndex Start index. + * + * @return true if <code>dataArray[startIndex]</code> is the start + * of a valid paragraph descriptor, false otherwise. + */ + static boolean isValid(byte dataArray[], int startIndex) { + try { + if (dataArray[startIndex] != 3) + return false; + int len = ((dataArray[startIndex+1] << 8) + | (dataArray[startIndex+2] & 0xFF)); + len &= 0xFFFF; // eliminate problems with sign-extension + + if (dataArray[startIndex + len + 2] != 0) + return false; + } catch (ArrayIndexOutOfBoundsException e) { + return false; + } + return true; + } + + + /** + * Return the number of bytes needed to represent this font table. + * + * @return The number of bytes needed to represent this font table. + */ + int getByteCount() { + + int length = 3; // leading "3" plus 2 bytes for length. + int nFonts = fontNames.size(); + for (int i = 0; i < nFonts; i++) { + String name = (String)fontNames.elementAt(i); + length += name.length() + 1; // extra byte is for trailing "0" + } + return length; + } + + /** + * Return a <code>byte</code> array representing this font table. + * + * @return An <code>byte</code> array representing this font table. + */ + byte[] getBytes() { + + int length = getByteCount(); + int nFonts = fontNames.size(); + byte b[] = new byte[length]; + b[0] = 3; + length -= 3; + b[1] = (byte)(length >> 8); + b[2] = (byte)(length & 0xFF); + int indx = 3; + for (int i = 0; i < nFonts; i++) { + String name = (String)fontNames.elementAt(i); + byte bname[] = name.getBytes(); + System.arraycopy(bname, 0, b, indx, bname.length); + indx += bname.length; + b[indx++] = 0; + } + return b; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseHeader.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseHeader.java new file mode 100644 index 000000000000..009f1a975b2f --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseHeader.java @@ -0,0 +1,148 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WseHeader.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.IOException; +import java.io.DataOutputStream; +import java.io.ByteArrayOutputStream; + +/** + * This class represents a WordSmith document header. + * + * @author David Proulx + */ +class WseHeader extends Wse { + + private int nParagraphs = 0; + private int nAtoms = 0; + private int nChars = 0; + private int miscSize = 0; + + /** + * Constructor for use when going from DOM to WordSmith. + * + * @param nPara The number of paragraphs. + * @param nAtoms The number of atoms. + * @param nChars The number of characters. + * @param ft The font table. + * @param ct The color table. + */ + public WseHeader(int nPara, int nAtoms, int nChars, WseFontTable ft, + WseColorTable ct) { + nParagraphs = nPara; + this.nAtoms = nAtoms; + this.nChars = nChars; + if (ft != null) miscSize += ft.getByteCount(); + if (ct != null) miscSize += ct.getByteCount(); + } + + + /** + * Constructor for use when going from WordSmith to DOM. + * + * @param dataArray <code>byte</code> array. + * @param i Index. + */ + public WseHeader(byte dataArray[], int i) { + // DJP: write this! + } + + /** + * Return true if <code>dataArray[startIndex]</code> is the start + * of a document header. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The index. + * + * @return true if <code>dataArray[startIndex]</code> is the start + * of a document header, false otherwise. + */ + static boolean isValid(byte dataArray[], int startIndex) { + return ((dataArray[startIndex] == 2) + && (dataArray[startIndex + 1] == 4)); + } + + + /** + * Compute and return the index of the first <code>byte</code> + * following this element. It is assumed that the element + * starting at <code>dataArray[startIndex]</code> is valid. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return The first <code>byte</code> following this element. + */ + static int computeNewIndex(byte dataArray[], int startIndex) { + return startIndex + 18; + } + + + /** + * Return the total number of bytes needed to represent this. + * + * @return The total number of bytes needed to represent this. + */ + int getByteCount() { + return 18; + } + + + /** + * Return a <code>byte</code> array representing this element. + * + * @return A <code>byte</code> array representing this element. + */ + byte[] getBytes() { + DataOutputStream os; // Used for storing the data + ByteArrayOutputStream bs = null; // Used for storing the data + + try { + bs = new ByteArrayOutputStream(); + os = new DataOutputStream(bs); + os.write(2); // binary doc indicator + os.write(4); // binary header indicator + + os.writeInt(nParagraphs); + os.writeInt(nAtoms); + os.writeInt(nChars); + os.writeInt(miscSize); + + } catch (IOException e) { + e.printStackTrace(); + } + + if (bs != null) { + return bs.toByteArray(); + } else return null; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WsePara.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WsePara.java new file mode 100644 index 000000000000..8947aa7a1f47 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WsePara.java @@ -0,0 +1,302 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WsePara.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import java.io.IOException; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.xml.*; + + +/** + * This class represents a paragraph in a WordSmith document. + * (A paragraph is "5" followed by 12 bytes of attributes.) + * + * @author David Proulx + */ +class WsePara extends Wse { + + private byte spaceBefore = 0; + private byte spaceAfter = 0; + private byte leftIndent = 0; + private byte firstIndent = 0; + private byte rightIndent = 0; + private byte misc = 0; + private byte style = 0; + private byte lineSpace = 0; + private byte outline = 0; + private byte reserved = 0; + + private static final byte LS_EXACTLY = (byte)0xC0; + private static final byte LS_ATLEAST = (byte)0x80; + private static final byte LS_MULTIPLE = (byte)0x40; + private static final byte LS_VALUEMASK = (byte)0x3F; + + private static final byte ALIGN_RIGHT = (byte)2; + private static final byte ALIGN_LEFT = (byte)0; + private static final byte ALIGN_CENTER = (byte)1; + private static final byte ALIGN_JUST = (byte)3; + + private StyleCatalog sc = null; + + + /** + * Constructor for use when going from DOM to WordSmith. + * + * @param p The paragraph style. + * @param sc The <code>StyleCatalog</code>. + */ + public WsePara(ParaStyle p, StyleCatalog sc) { + this.sc = sc; + ParaStyle ps = (ParaStyle)p.getResolved(); + + if (ps.isAttributeSet(ParaStyle.MARGIN_LEFT)) { + double temp = ps.getAttribute(ParaStyle.MARGIN_LEFT) * 1.6 / 100; + leftIndent = (byte) temp; + if ((temp - leftIndent) > 0.5) leftIndent++; + } + + if (ps.isAttributeSet(ParaStyle.MARGIN_RIGHT)) { + double temp = ps.getAttribute(ParaStyle.MARGIN_RIGHT) * 1.6 / 100; + rightIndent = (byte) temp; + if ((temp - rightIndent) > 0.5) rightIndent++; + } + + if (ps.isAttributeSet(ParaStyle.TEXT_INDENT)) { + double temp = ps.getAttribute(ParaStyle.TEXT_INDENT) * 1.6 / 100; + firstIndent = (byte) temp; + if ((temp - firstIndent) > 0.5) firstIndent++; + } + + if (ps.isAttributeSet(ParaStyle.MARGIN_TOP)) { + double temp = ps.getAttribute(ParaStyle.MARGIN_TOP) * 1.6 / 100; + spaceBefore = (byte) temp; + if ((temp - spaceBefore) > 0.5) spaceBefore++; + } + + if (ps.isAttributeSet(ParaStyle.MARGIN_BOTTOM)) { + double temp = ps.getAttribute(ParaStyle.MARGIN_BOTTOM) * 1.6 / 100; + spaceAfter = (byte) temp; + if ((temp - spaceAfter) > 0.5) spaceAfter++; + } + + if (ps.isAttributeSet(ParaStyle.LINE_HEIGHT)) { + int lh = ps.getAttribute(ParaStyle.LINE_HEIGHT); + if ((lh & ~ParaStyle.LH_VALUEMASK) == 0) + lineSpace = (byte)(LS_MULTIPLE | (lh * 2)); + else if ((lh & ParaStyle.LH_PCT) != 0) { + lh = (lh & ParaStyle.LH_VALUEMASK) / 100; + lineSpace = (byte)(LS_MULTIPLE | (lh * 2)); + } + // DJP: handle other cases.... + } + + if (ps.isAttributeSet(ParaStyle.TEXT_ALIGN)) { + + int val = ps.getAttribute(ParaStyle.TEXT_ALIGN); + + switch (val) { + case ParaStyle.ALIGN_RIGHT: + misc = ALIGN_RIGHT; + break; + case ParaStyle.ALIGN_LEFT: + misc = ALIGN_LEFT; + break; + case ParaStyle.ALIGN_CENTER: + misc = ALIGN_CENTER; + break; + case ParaStyle.ALIGN_JUST: + misc = ALIGN_JUST; + break; + } + } + + } + + + /** + * Constructor for use when going from WordSmith to DOM. + * Assumes <code>dataArray[startIndex]</code> is the first + * <code>byte</code> of a valid WordSmith paragraph descriptor. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + */ + public WsePara(byte dataArray[], int startIndex) { + spaceBefore = dataArray[startIndex + 1]; + spaceAfter = dataArray[startIndex + 2]; + leftIndent = dataArray[startIndex + 3]; + firstIndent = dataArray[startIndex + 4]; + rightIndent = dataArray[startIndex + 5]; + misc = dataArray[startIndex + 6]; + style = dataArray[startIndex + 7]; + lineSpace = dataArray[startIndex + 8]; + outline = dataArray[startIndex + 9]; + } + + + /** + * Compute the index of the first <code>byte</code> following the + * paragraph descriptor, assuming that + * <code>dataArray[startIndex]</code> is the beginning of a valid + * paragraph descriptor. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return The index of the first <code>byte</code> following the + * paragraph description. + */ + static int computeNewIndex(byte dataArray[], int startIndex) { + return startIndex + 13; + } + + + /** + * Return true if <code>dataArray[startIndex]</code> is the start + * of a valid paragraph descriptor. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return true if <code>dataArray[startIndex]</code> is the start + * of a valid paragraph descriptor, false otherwise. + */ + static boolean isValid(byte dataArray[], int startIndex) { + return (dataArray[startIndex] == 5); + } + + /** + * Return the number of bytes needed to represent this paragraph. + * + * @return The number of bytes needed to represent this paragraph. + */ + int getByteCount() { + return 13; + } + + /** + * Return an <code>byte</code> array representing this paragraph. + * + * @return An <code>byte</code> array representing this paragraph. + */ + byte[] getBytes() { + byte b[] = new byte[13]; + + b[0] = 5; + b[1] = spaceBefore; + b[2] = spaceAfter; + b[3] = leftIndent; + b[4] = firstIndent; + b[5] = rightIndent; + b[6] = misc; + b[7] = style; + b[8] = lineSpace; + b[9] = outline; + b[10] = reserved; + b[11] = 0; + b[12] = 0; + + return b; + } + + /** + * Return a <code>ParaStyle</code> that reflects the formatting of + * this run. + * + * @return A <code>ParaStyle</code> that reflects the formatting + * of this run. + */ + ParaStyle makeStyle() { + /* Csaba: Commented out the LINE_HEIGHT syle, because there was no + incoming data for that style. It was resulting a zero line + height in the xml document, ie. the doc looked empty. + */ + int attrs[] = { ParaStyle.MARGIN_LEFT, ParaStyle.MARGIN_RIGHT, + ParaStyle.TEXT_INDENT, //ParaStyle.LINE_HEIGHT, + ParaStyle.MARGIN_TOP, ParaStyle.MARGIN_BOTTOM, + ParaStyle.TEXT_ALIGN }; + String values[] = new String[attrs.length]; + double temp; + + temp = leftIndent / 1.6; + values[0] = (new Double(temp)).toString() + "mm"; + + temp = rightIndent / 1.6; + values[1] = (new Double(temp)).toString() + "mm"; + + temp = firstIndent / 1.6; + values[2] = (new Double(temp)).toString() + "mm"; + +/* if ((lineSpace & LS_MULTIPLE) != 0) { + temp = (lineSpace & LS_VALUEMASK) / 2; + temp *= 100; + values[3] = (new Double(temp)).toString() + "%"; + } else { + values[3] = (new Double(temp)).toString() + "mm"; + // DJP: handle other cases + } +*/ + temp = spaceBefore / 1.6; +// values[4] = (new Double(temp)).toString() + "mm"; + values[3] = (new Double(temp)).toString() + "mm"; + + temp = spaceAfter / 1.6; +// values[5] = (new Double(temp)).toString() + "mm"; + values[4] = (new Double(temp)).toString() + "mm"; + + switch (misc) { + +// case ALIGN_RIGHT: values[6] = "right"; break; +// case ALIGN_LEFT: values[6] = "left"; break; +// case ALIGN_CENTER:values[6] = "center"; break; +// case ALIGN_JUST: values[6] = "justified"; break; + + case ALIGN_RIGHT: values[5] = "right"; break; + case ALIGN_LEFT: values[5] = "left"; break; + case ALIGN_CENTER:values[5] = "center"; break; + case ALIGN_JUST: values[5] = "justified"; break; + } + ParaStyle x = new ParaStyle(null, "paragraph", null, attrs, + values, sc); + + return x; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseTextRun.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseTextRun.java new file mode 100644 index 000000000000..b1b6fa934e78 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/WseTextRun.java @@ -0,0 +1,327 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: WseTextRun.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.openoffice.xmerge.converter.xml.TextStyle; +import org.openoffice.xmerge.converter.xml.StyleCatalog; +import java.awt.Color; + +/** + * <p>This class represents a text run (aka text atom) in a WordSmith + * document.</p> + * + * <p>WordSmith represents a text run as follows:</p> + * + * <p><ul><li> + * 1 byte Value of "1", indicating beginning of a text atom + * </li><li> + * 2 bytes Length of text (does not include attributes, this length field, + * etc) + * </li><li> + * 1 byte Font index - Index in the font table of font to be used + * </li><li> + * 1 byte Font size (DJP: get details of representation) + * </li><li> + * 1 byte Color index - Index in the color table of font color to be used + * </li><li> + * 1 byte Modifiers - bit flags for bold, italic, etc + * </li><li> + * n bytes Text - the actual text + * </li></ul></p> + * + * @author David Proulx + */ +class WseTextRun extends Wse { + + /** Font specifier. This is an index into the font table. */ + private byte fontIndex = 0; + private String fontName = null; + + /** Size of the font. */ + private byte fontSize = 0; + + /** + * Color of the font. This is an index into the color table. + * High nibble is background color index, low nibble is font color + * index. + */ + private byte colorIndex = 0; + + /** + * Reference to color table for color lookups. + */ + private WseColorTable ct; + + /** + * The modifiers for the text run. (Mostly) Bitwise flags. The "_TOKEN" + * values are not yet implemented in this converter. They may not even + * be implemented in WordSmith yet. + */ + private byte modifiers = 0; + final public static int BOLD = 0x01; + final public static int ITALIC = 0x02; + final public static int UNDERLINE = 0x04; + final public static int STRIKETHRU = 0x08; + final public static int SUPERSCRIPT = 0x10; + final public static int SUBSCRIPT = 0x20; + final public static int LINK = 0x40; + final public static int CUSTOM_TOKEN = 0x80; + final public static int IMAGE_TOKEN = 0x80; + final public static int BOOKMARK_TOKEN = 0x81; + final public static int ANNOTATION_TOKEN = 0x82; + final public static int LINK_TOKEN = 0x83; + + /** The actual text. */ + private String text; + + StyleCatalog sc; + + + /** + * Constructor for use when going from DOM to WordSmith. + * + * @param txt The text. + * @param t The text style. + * @param sc The <code>StyleCatalog</code>. + * @param ft The font table. + * @param ct The color Table. + */ + public WseTextRun(String txt, TextStyle t, StyleCatalog sc, + WseFontTable ft, WseColorTable ct) { + + this.sc = sc; + this.ct = ct; + + TextStyle ts = (TextStyle)t.getResolved(); + + if (ts.isSet(TextStyle.BOLD) && ts.getAttribute(TextStyle.BOLD)) + modifiers |= BOLD; + if (ts.isSet(TextStyle.ITALIC) && ts.getAttribute(TextStyle.ITALIC)) + modifiers |= ITALIC; + if (ts.isSet(TextStyle.UNDERLINE) && ts.getAttribute(TextStyle.UNDERLINE)) + modifiers |= UNDERLINE; + if (ts.isSet(TextStyle.STRIKETHRU) && ts.getAttribute(TextStyle.STRIKETHRU)) + modifiers |= STRIKETHRU; + if (ts.isSet(TextStyle.SUPERSCRIPT) && ts.getAttribute(TextStyle.SUPERSCRIPT)) + modifiers |= SUPERSCRIPT; + if (ts.isSet(TextStyle.SUBSCRIPT) && ts.getAttribute(TextStyle.SUBSCRIPT)) + modifiers |= SUBSCRIPT; + + fontSize = (byte)(ts.getFontSize() * 2); + fontName = ts.getFontName(); + fontIndex = (byte)ft.getFontIndex(fontName); + if (fontIndex == -1) { + ft.add(fontName); + fontIndex = (byte)ft.getFontIndex(fontName); + } + + // Figure out the color index. + Color c = t.getFontColor(); + if (c == null) + c = Color.black; + colorIndex = (byte)ct.findColor(c, true); + c = t.getBackgroundColor(); + if (c == null) + c = Color.white; + colorIndex |= (byte)(ct.findColor(c, false) << 4); + + text = txt; + } + + + /** + * Standard constructor for use when going from WordSmith to DOM. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * @param ft The font table. + * @param ct The color table. + */ + public WseTextRun(byte dataArray[], int startIndex, WseFontTable ft, + WseColorTable ct) { + + this.ct = ct; + + startIndex++; // Skip the leading "1" + + int textLen = ((dataArray[startIndex] << 8) + | (dataArray[startIndex+1] & 0xFF)); + startIndex += 2; + + fontIndex = dataArray[startIndex++]; + if (ft != null) + fontName = ft.getFontName(fontIndex); + + fontSize = dataArray[startIndex++]; + + colorIndex = dataArray[startIndex++]; + modifiers = dataArray[startIndex++]; + + text = new String(dataArray, startIndex, textLen); + startIndex += textLen; // skip the text + } + + + /** + * Given a <code>byte</code> sequence, assumed to be a text run, + * compute the index of the first byte past the text run. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index + * + * @return The index of the first <code>byte</code> past the + * text run. + */ + public static int computeNewIndex(byte dataArray[], int startIndex) { + + startIndex++; // Skip the leading "1" + + int textLen = ((dataArray[startIndex] << 8) + | (dataArray[startIndex+1] & 0xFF)); + startIndex += 2; + + startIndex += 4; // skip attributes + // text = new String(dataArray, startIndex, textLen); + startIndex += textLen; // skip the text + return startIndex; + } + + + /** + * Return true if the sequence starting at + * <code>dataArray[startIndex]</code> is a valid text run. + * + * @param dataArray <code>byte</code> array. + * @param startIndex The start index. + * + * @return true if the sequence starting at + * <code>dataArray[startIndex]</code> is a valid + * text run, false otherwise. + */ + public static boolean isValid(byte dataArray[], int startIndex) { + return (dataArray[startIndex] == 1); + } + + /** + * Return the number of bytes needed to represent this text run. + * + * @return The number of bytes needed to represent this text run. + */ + int getByteCount() { + return text.length() + 7; + } + + + /** + * Return an <code>byte</code> array representing this text run. + * + * @return An <code>byte</code> array representing this text run. + */ + byte[] getBytes() { + short textLen = (short)text.length(); + byte b[] = new byte[textLen + 7]; + b[0] = 1; + b[1] = (byte)(textLen >> 8); + b[2] = (byte)(textLen & 0xFF); + b[3] = fontIndex; + b[4] = fontSize; + b[5] = colorIndex; + b[6] = modifiers; + byte[] txtBytes = text.getBytes(); + System.arraycopy(txtBytes, 0, b, 7, textLen); + return b; + } + + + /** + * Return the text of this run. + * + * @return The text of this run. + */ + public String getText() { + return text; + } + + + /** + * Return a <code>TextStyle</code> that reflects the formatting + * of this run. + * + * @return A <code>TextStyle</code> that reflects the formatting + * of this run. + */ + public TextStyle makeStyle() { + int mod = 0; + if ((modifiers & BOLD) != 0) mod |= TextStyle.BOLD; + if ((modifiers & ITALIC) != 0) mod |= TextStyle.ITALIC; + if ((modifiers & UNDERLINE) != 0) mod |= TextStyle.UNDERLINE; + if ((modifiers & STRIKETHRU) != 0) + mod |= TextStyle.STRIKETHRU; + if ((modifiers & SUPERSCRIPT) != 0) mod |= TextStyle.SUPERSCRIPT; + if ((modifiers & SUBSCRIPT) != 0) mod |= TextStyle.SUBSCRIPT; + + int mask = TextStyle.BOLD | TextStyle.ITALIC + | TextStyle.UNDERLINE + | TextStyle.STRIKETHRU | TextStyle.SUPERSCRIPT + | TextStyle.SUBSCRIPT; + + TextStyle x = new TextStyle(null, "text", null, mask, + mod, (int)(fontSize/2), fontName, sc); + + // If color table is available, set the colors. + if (ct != null) { + Color fc = ct.getColor(colorIndex & 0xF, true); + Color bc = ct.getColor(colorIndex >> 4, false); + x.setColors(fc, bc); + } + + return x; + } + + + /** + * Display debug information. + */ + public void dump() { + System.out.print("TEXT RUN: fontIndex = " + fontIndex + + " fontsize = " + fontSize + + " colorIndex = " + colorIndex + + " "); + if ((modifiers & BOLD) != 0) System.out.print("BOLD,"); + if ((modifiers & ITALIC) != 0) System.out.print("ITALIC,"); + if ((modifiers & UNDERLINE) != 0) System.out.print("UNDERLINE,"); + if ((modifiers & STRIKETHRU) != 0) System.out.print("STRIKETHRU,"); + if ((modifiers & SUPERSCRIPT) != 0) System.out.print("SUPERSCRIPT,"); + if ((modifiers & SUBSCRIPT) != 0) System.out.print("SUBSCRIPT,"); + System.out.println("\n" + text); + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/build.xml new file mode 100644 index 000000000000..5b48ae6ddc1e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/build.xml @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcxs_wordsmith" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcxs_wordsmith"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../.."/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/sxw/wordsmith"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/DOCConstants.java"/> + <include name="${package}/textRecord.java"/> + <include name="${package}/util.java"/> + <include name="${package}/WSDecoder.java"/> + <include name="${package}/WseColorTable.java"/> + <include name="${package}/WseFontTable.java"/> + <include name="${package}/Wse.java"/> + <include name="${package}/WseHeader.java"/> + <include name="${package}/WSEncoder.java"/> + <include name="${package}/WsePara.java"/> + <include name="${package}/WseTextRun.java"/> + <include name="${package}/DocumentMergerImpl.java"/> + <include name="${package}/DocumentSerializerImpl.java"/> + <include name="${package}/DocumentDeserializerImpl.java"/> + <include name="${package}/ConverterCapabilitiesImpl.java"/> + <include name="${package}/PluginFactoryImpl.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/converter.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/converter.xml new file mode 100644 index 000000000000..9285730569db --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/converter.xml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<converters> + <converter type="staroffice/sxw" version="1.0"> + <converter-display-name> + WordSmith + </converter-display-name> + <converter-description> + StarWriter XML to/from WordSmith conversion + </converter-description> + <converter-vendor>OpenOffice.org</converter-vendor> + <converter-class-impl> + org.openoffice.xmerge.converter.xml.sxw.wordsmith.PluginFactoryImpl + </converter-class-impl> + <converter-target type="application/x-wordsmith" /> + </converter> +</converters> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/makefile.mk new file mode 100644 index 000000000000..6cfbb307ba85 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/makefile.mk @@ -0,0 +1,36 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJNAME=converter +TARGET=cv_jcsscdcxs_wordsmith +PRJ=../../../../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/textRecord.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/textRecord.java new file mode 100644 index 000000000000..0083899dce0e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/textRecord.java @@ -0,0 +1,118 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: textRecord.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +import org.openoffice.xmerge.util.Debug; +import java.io.IOException; +import java.io.DataOutputStream; +import java.io.ByteArrayOutputStream; + +/** + * This class represents a single text record in a WordSmith document. + * A record is composed of one or more "WordSmith elements", which + * include: WordSmith header, font table, color table, paragraphs, + * and text runs. + * + * @author David Proulx + */ + +class textRecord { + + java.util.Vector elements; + + + /** + * Default constructor + */ + textRecord() { + elements = new java.util.Vector(10); + } + + + /** + * Add an element + * + * @param elem The element to add + */ + void addElement(Wse elem) { + elements.add(elem); + } + + + /** + * Return the number of bytes needed to represent the current + * contents of this text record. + * + * @return The number of bytes needed to represent the current + * contents of this text record. + */ + int getByteCount() { + int totalBytes = 0; + int nElements = elements.size(); + for (int i = 0; i < nElements; i++) { + Wse e = (Wse)elements.elementAt(i); + totalBytes += e.getByteCount(); + } + return totalBytes; + } + + + /** + * Return the contents of this record as a <code>byte</code> array. + * + * @return the contents of this record as a <code>byte</code> array. + */ + byte[] getBytes() { + DataOutputStream os = null; // Used for storing the data + ByteArrayOutputStream bs = null; // Used for storing the data + byte ftBytes[] = null; + byte ctBytes[] = null; + + try { + bs = new ByteArrayOutputStream(); + os = new DataOutputStream(bs); + int nElements = elements.size(); + for (int i = 0; i < nElements; i++) { + Wse e = (Wse)elements.get(i); + os.write(e.getBytes()); + } + + } catch (IOException e) { + e.printStackTrace(); + } + + if (bs != null) + return bs.toByteArray(); + else + return null; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/util.java b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/util.java new file mode 100644 index 000000000000..d123c0a72b56 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/sxw/wordsmith/util.java @@ -0,0 +1,71 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: util.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxw.wordsmith; + +/** + * WordSmith utility class. + * + * @author David Proulx + */ +class util { + + /** + * Convert 2 bytes to an integer. + * + * @param data <code>byte</code> data to convert. + * @param index Index to convert. + * + * @return Converted integer. + */ + static int intFrom2bytes(byte[] data, int index) { + return (((data[index] & 0xFF) << 8) + | (data[index+1] & 0xFF)); + + } + + + /** + * Convert 4 bytes to an integer. + * + * @param data <code>byte</code> data to convert. + * @param index Index to convert. + * + * @return Converted integer. + */ + static int intFrom4bytes(byte[] data, int index) { + return (((data[index] & 0xFF) << 24) + | ((data[index + 1] & 0xFF) << 16) + | ((data[index + 2] & 0xFF) << 8) + | (data[index+3] & 0xFF)); + + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/ConverterCapabilitiesImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..f292bc78f40a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/ConverterCapabilitiesImpl.java @@ -0,0 +1,96 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterCapabilitiesImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.xslt; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * <p>Xslt implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.xslt.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarWriter XML to/from XSLT supported formats conversions. The + * <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_DOCUMENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_DOCUMENT_CONTENT.equals(tag)) + return true; + else if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_HEADING.equals(tag)) + return true; + else if (OfficeConstants.TAG_ORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_UNORDERED_LIST.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_ITEM.equals(tag)) + return true; + else if (OfficeConstants.TAG_LIST_HEADER.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPAN.equals(tag)) + return true; + else if (OfficeConstants.TAG_HYPERLINK.equals(tag)) + return true; + else if (OfficeConstants.TAG_LINE_BREAK.equals(tag)) + return true; + else if (OfficeConstants.TAG_SPACE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TAB_STOP.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_SPACE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_SPACE_COUNT.equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentDeserializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentDeserializerImpl.java new file mode 100644 index 000000000000..236afccd5646 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentDeserializerImpl.java @@ -0,0 +1,257 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentDeserializerImpl.java,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.xslt; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; + +import java.io.InputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; + + + + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.converter.dom.DOMDocument; +//import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +import org.openoffice.xmerge.converter.xml.xslt.GenericOfficeDocument; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.registry.ConverterInfo; + +// Imported TraX classes +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.dom.DOMSource; +//import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.transform.URIResolver; +import javax.xml.transform.Source; + + +// +//import org.apache.xalan.serialize.Serializer; +//import org.apache.xalan.serialize.SerializerFactory; +//import org.apache.xalan.templates.OutputProperties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +// Imported java classes +import java.io.FileNotFoundException; + + +/** + * <p>Xslt implementation of + * org.openoffice.xmerge.DocumentSerializer + * for the {@link + * org.openoffice.xmerge.converter.xml.xslt.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>The <code>serialize</code> method transforms the DOM + * document from the given <code>Document</code> object by + * means of a supplied Xsl Stylesheet.</p> + * + * @author Aidan Butler + */ +public final class DocumentDeserializerImpl + implements DocumentDeserializer,URIResolver { + + /** A <code>ConvertData</code> object assigned to this object. */ + private InputStream is = null; + private ConvertData cd = null; + private PluginFactoryImpl pluginFactory = null; + + /** + * Constructor that assigns the given <code>ConvertData</code> + * to this object. + * + * @param pf A <code>PluginFactoryImpl</code> object. + * + * @param cd A <code>ConvertData</code> object to read data for + * the conversion process by the <code>deserialize</code> + * method. + */ + public DocumentDeserializerImpl(PluginFactoryImpl pf,ConvertData cd) { + this.cd = cd; + pluginFactory = pf; + } + + + + /* + * This method performs the xslt transformation on the supplied <code> + * Document</code> and returns a <code>ByteArrayOutputStream</code> object. + * + * Xslt transformation code + * + * @returns baos A <code>ByteArrayOutputStream</code> object containing + * the result of the Xslt transformation. + * @throws TransformerException,TransformerConfigurationException + * , FileNotFoundException,IOException + * + */ + public Document deserialize() throws ConvertException, IOException { + log("\nFound the XSLT deserializer"); + Enumeration enumer = cd.getDocumentEnumeration(); + org.w3c.dom.Document domDoc=null; + DOMDocument docOut=null; + GenericOfficeDocument doc = null; + ByteArrayOutputStream baos =null; + GenericOfficeDocument sxwDoc = new GenericOfficeDocument("output"); + while (enumer.hasMoreElements()) { + docOut = (DOMDocument) enumer.nextElement(); + } + domDoc = docOut.getContentDOM(); + try{ + baos = transform(domDoc); + sxwDoc.initContentDOM(); + DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); + dFactory.setNamespaceAware(true); + DocumentBuilder dBuilder = dFactory.newDocumentBuilder(); + sxwDoc.setContentDOM(dBuilder.parse(new ByteArrayInputStream(baos.toByteArray()))); + + } + catch(Exception e){ + System.out.println("The following error occurred:"+e); + } + return sxwDoc; + } + + public Source resolve(String href,String base) + throws TransformerException{ + //System.out.println("\nhref "+href+"\nbase "+base); + if (href !=null){ + if(href.equals("javax.xml.transform.dom.DOMSource")|| href.equals("")) + return null; + try{ + ConverterInfo ci = pluginFactory.getConverterInfo(); + String newhRef ="jar:"+ci.getJarName()+"!/"+href; + //System.out.println("\n Looking For "+ newhRef); + StreamSource sheetFile= new StreamSource(newhRef); + return sheetFile; + } + catch (Exception e){ + System.out.println("\nException in Xslt Resolver " +e); + return null; + } + } + else + return null; + } + + /* + * This method performs the xslt transformation on the supplied Dom Tree. + * + * Xslt transformation code + * + * @throws TransformerException,TransformerConfigurationException + * , FileNotFoundException,IOException + * + */ + private ByteArrayOutputStream transform(org.w3c.dom.Document xmlDoc) + throws TransformerException,TransformerConfigurationException + , FileNotFoundException,IOException{ + + log("\nTransforming..."); + ConverterInfo ci = pluginFactory.getConverterInfo(); + ByteArrayOutputStream baos= new ByteArrayOutputStream(); + try{ + DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); + dFactory.setNamespaceAware(true); + DocumentBuilder dBuilder = dFactory.newDocumentBuilder(); + + String teststr = ci.getXsltDeserial(); + teststr= teststr.substring(0,6); + org.w3c.dom.Document xslDoc=null; + if ((teststr.equals("http:/"))||(teststr.equals("file:/")) + ||(teststr.equals("jar://"))){ + log(ci.getXsltDeserial()); + xslDoc= dBuilder.parse(ci.getXsltDeserial()); + + } + else{ + log(ci.getJarName()+"!/"+ci.getXsltDeserial()); + xslDoc = dBuilder.parse( + "jar:"+ci.getJarName()+"!/"+ci.getXsltDeserial()); + } + + + DOMSource xslDomSource = new DOMSource(xslDoc); + DOMSource xmlDomSource = new DOMSource(xmlDoc); + + //call the tranformer using the XSL, Source and Result dom. + TransformerFactory tFactory = TransformerFactory.newInstance(); + tFactory.setURIResolver(this); + Transformer transformer = tFactory.newTransformer(xslDomSource); + transformer.transform(xmlDomSource,new StreamResult(baos)); + /* + // Serialize for output to standard out + Serializer serializer = SerializerFactory.getSerializer + (OutputProperties.getDefaultMethodProperties("xml")); + serializer.setOutputStream(System.out); + serializer.asDOMSerializer().serialize(xmlDomResult.getNode()); + */ + + log("\n** Transform Complete ***"); + + } + catch (StackOverflowError sOE){ + System.out.println("\nERROR : Stack Overflow Error During Transformation\n Try increasing the stack size by passing the -Xss1m option to the JRE."); + throw sOE; + } + catch(Exception e){ + System.out.println("An error occured in the transformation : "+e); + } + return baos; + } + + /** + * Sends message to the log object. + * + * @param str Debug message. + */ + private void log(String str) { + + Debug.log(Debug.TRACE, str); + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentMergerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentMergerImpl.java new file mode 100644 index 000000000000..042e4c37a377 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentMergerImpl.java @@ -0,0 +1,102 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentMergerImpl.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.xslt; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.MergeException; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.xslt.GenericOfficeDocument; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.Difference; +import org.openoffice.xmerge.merger.NodeMergeAlgorithm; +import org.openoffice.xmerge.merger.Iterator; +import org.openoffice.xmerge.merger.DiffAlgorithm; +import org.openoffice.xmerge.merger.diff.ParaNodeIterator; +import org.openoffice.xmerge.merger.diff.IteratorLCSAlgorithm; +import org.openoffice.xmerge.merger.merge.DocumentMerge; +import org.openoffice.xmerge.merger.merge.CharacterBaseParagraphMerge; +import org.openoffice.xmerge.util.Debug; + + +/** + * Xslt implementation of <code>DocumentMerger</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.xslt.PluginFactoryImpl + * PluginFactoryImpl}.</p> + */ +public class DocumentMergerImpl implements DocumentMerger { + + private ConverterCapabilities cc_; + private org.openoffice.xmerge.Document orig = null; + + public DocumentMergerImpl(org.openoffice.xmerge.Document doc, ConverterCapabilities cc) { + cc_ = cc; + this.orig = doc; + } + + public void merge(org.openoffice.xmerge.Document modifiedDoc) throws MergeException { + + GenericOfficeDocument wdoc1 = (GenericOfficeDocument) orig; + GenericOfficeDocument wdoc2 = (GenericOfficeDocument) modifiedDoc; + + Document doc1 = wdoc1.getContentDOM(); + Document doc2 = wdoc2.getContentDOM(); + + Iterator i1 = new ParaNodeIterator(cc_, doc1.getDocumentElement()); + Iterator i2 = new ParaNodeIterator(cc_, doc2.getDocumentElement()); + + DiffAlgorithm diffAlgo = new IteratorLCSAlgorithm(); + + // find out the paragrah level diffs + Difference[] diffTable = diffAlgo.computeDiffs(i1, i2); + + if (Debug.isFlagSet(Debug.INFO)) { + Debug.log(Debug.INFO, "Diff Result: "); + + for (int i = 0; i < diffTable.length; i++) { + Debug.log(Debug.INFO, diffTable[i].debug()); + } + } + + // merge the paragraphs + NodeMergeAlgorithm charMerge = new CharacterBaseParagraphMerge(); + DocumentMerge docMerge = new DocumentMerge(cc_, charMerge); + + Iterator result = null; + + docMerge.applyDifference(i1, i2, diffTable); + } +} + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentSerializerImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentSerializerImpl.java new file mode 100644 index 000000000000..ec41df8d5945 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/DocumentSerializerImpl.java @@ -0,0 +1,312 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocumentSerializerImpl.java,v $ + * $Revision: 1.10 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.xslt; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.*; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.util.Enumeration; +import java.util.Properties; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.converter.xml.xslt.GenericOfficeDocument; +import org.openoffice.xmerge.converter.dom.DOMDocument; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.registry.ConverterInfo; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +// Imported TraX classes +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.stream.StreamSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.URIResolver; +import javax.xml.transform.Source; + +// +import org.apache.xalan.serialize.Serializer; +import org.apache.xalan.serialize.SerializerFactory; +import org.apache.xalan.templates.OutputProperties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +// Imported java classes +import java.io.FileNotFoundException; +import java.io.File; +import java.net.URI; + +/** + * <p>Xslt implementation of + * org.openoffice.xmerge.DocumentSerializer + * for the {@link + * org.openoffice.xmerge.converter.xml.xslt.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>The <code>serialize</code> method transforms the DOM + * document from the given <code>Document</code> object by + * means of a supplied Xsl Stylesheet.</p> + * + * @author Aidan Butler + */ + + +public final class DocumentSerializerImpl + implements DocumentSerializer,OfficeConstants,URIResolver { + + + /** SXW <code>Document</code> object that this converter processes. */ + private GenericOfficeDocument sxwDoc = null; + + private PluginFactoryImpl pluginFactory = null; + + /** + * Constructor. + * + * @param pf A <code>PluginFactoryImpl</code> + * @param doc A SXW <code>Document</code> to be converted. + */ + public DocumentSerializerImpl(PluginFactoryImpl pf,Document doc) { + pluginFactory=pf; + sxwDoc = (GenericOfficeDocument) doc; + } + + + /** + * Method to convert a <code>Document</code> with an xsl stylesheet. + * It creates a <code>Document</code> object, which is then transformed + * with the Xslt processer. A <code>ConvertData </code> object is + * constructed and returned. + * + * @returns cd A <code>ConvertData</code> object. + * @throws ConvertException If any I/O error occurs. + * @throws IOException If any I/O error occurs. + */ + public ConvertData serialize() throws ConvertException, IOException { + String docName = sxwDoc.getName(); + org.w3c.dom.Document domDoc = sxwDoc.getContentDOM(); + org.w3c.dom.Document metaDoc = sxwDoc.getMetaDOM(); + org.w3c.dom.Document styleDoc = sxwDoc.getStyleDOM(); + ByteArrayOutputStream baos= new ByteArrayOutputStream(); + ConvertData cd = new ConvertData(); + Node offnode = (Node)domDoc.getDocumentElement(); + if (!(offnode.getNodeName()).equals("office:document")){ + try{ + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder= builderFactory.newDocumentBuilder(); + DOMImplementation domImpl = builder.getDOMImplementation(); + DocumentType docType =domImpl.createDocumentType("office:document","-//OpenOffice.org//DTD OfficeDocument 1.0//EN",null); + org.w3c.dom.Document newDoc = domImpl.createDocument("http://openoffice.org/2000/office","office:document",docType); + + + Element rootElement=newDoc.getDocumentElement(); + rootElement.setAttribute("xmlns:office","http://openoffice.org/2000/office"); + rootElement.setAttribute("xmlns:style","http://openoffice.org/2000/style" ); + rootElement.setAttribute("xmlns:text","http://openoffice.org/2000/text"); + rootElement.setAttribute("xmlns:table","http://openoffice.org/2000/table"); + + rootElement.setAttribute("xmlns:draw","http://openoffice.org/2000/drawing"); + rootElement.setAttribute("xmlns:fo","http://www.w3.org/1999/XSL/Format" ); + rootElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink" ); + rootElement.setAttribute("xmlns:dc","http://purl.org/dc/elements/1.1/" ); + rootElement.setAttribute("xmlns:meta","http://openoffice.org/2000/meta" ); + rootElement.setAttribute("xmlns:number","http://openoffice.org/2000/datastyle" ); + rootElement.setAttribute("xmlns:svg","http://www.w3.org/2000/svg" ); + rootElement.setAttribute("xmlns:chart","http://openoffice.org/2000/chart" ); + rootElement.setAttribute("xmlns:dr3d","http://openoffice.org/2000/dr3d" ); + rootElement.setAttribute("xmlns:math","http://www.w3.org/1998/Math/MathML" ); + rootElement.setAttribute("xmlns:form","http://openoffice.org/2000/form" ); + rootElement.setAttribute("xmlns:script","http://openoffice.org/2000/script" ); + rootElement.setAttribute("xmlns:config","http://openoffice.org/2001/config" ); + rootElement.setAttribute("office:class","text" ); + rootElement.setAttribute("office:version","1.0"); + + + NodeList nodeList; + Node tmpNode; + Node rootNode = (Node)rootElement; + if (metaDoc !=null){ + nodeList= metaDoc.getElementsByTagName(TAG_OFFICE_META); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + } if (styleDoc !=null){ + nodeList= styleDoc.getElementsByTagName(TAG_OFFICE_STYLES); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + }if (domDoc !=null){ + nodeList= domDoc.getElementsByTagName(TAG_OFFICE_AUTOMATIC_STYLES); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + nodeList= domDoc.getElementsByTagName(TAG_OFFICE_BODY); + if (nodeList.getLength()>0){ + tmpNode = newDoc.importNode(nodeList.item(0),true); + rootNode.appendChild(tmpNode); + } + } + domDoc=newDoc; + }catch(Exception e){ + System.out.println("\nAn Exception occurred with Xslt Serializer"+e); + } + + } + + try{ + baos=transform(domDoc); + } + catch (Exception e){ + System.out.println("\n Error with Xslt\n"); + } + + String ext = pluginFactory.getDeviceFileExtension(); + DOMDocument resultDomDoc=(DOMDocument)pluginFactory.createDeviceDocument(docName,new ByteArrayInputStream(baos.toByteArray())); + cd.addDocument (resultDomDoc); + return cd; + } + + public Source resolve(String href,String base) + throws TransformerException{ + //System.out.println("\nhref "+href+"\nbase "+base); + if (href !=null){ + if(href.equals("javax.xml.transform.dom.DOMSource")|| href.equals("")) + return null; + try{ + ConverterInfo ci = pluginFactory.getConverterInfo(); + String newhRef ="jar:"+ci.getJarName()+"!/"+href; + //System.out.println("\n Looking For "+ newhRef); + StreamSource sheetFile= new StreamSource(newhRef); + return sheetFile; + } + catch (Exception e){ + System.out.println("\nException in Xslt Resolver " +e); + return null; + } + } + else + return null; + } + + + /* + * This method performs the sxl transformation on the supplied <code> + * Document</code> and returns a <code>DOMResult</code> object. + * + * Xslt transformation code + * + * @returns baos A <code>ByteArrayOutputStream</code> object containing + * the result of the Xslt transformation. + * @throws TransformerException,TransformerConfigurationException + * , FileNotFoundException,IOException + * + */ + + + private ByteArrayOutputStream transform(org.w3c.dom.Document domDoc) + throws TransformerException,TransformerConfigurationException + , FileNotFoundException,IOException{ + //System.out.println("\nTransforming..."); + ConverterInfo ci = pluginFactory.getConverterInfo(); + //DOMResult xmlDomResult = new DOMResult(); + ByteArrayOutputStream baos= new ByteArrayOutputStream(); + try{ + + DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); + dFactory.setNamespaceAware(true); + + DocumentBuilder dBuilder = dFactory.newDocumentBuilder(); + String teststr = ci.getXsltSerial(); + + teststr= teststr.substring(0,6); + org.w3c.dom.Document xslDoc=null; + if ((teststr.equals("http:/"))||(teststr.equals("file:/")) + ||(teststr.equals("jar://"))){ + System.out.println(ci.getXsltSerial()); + xslDoc= dBuilder.parse(ci.getXsltSerial()); + + } + else{ + //System.out.println(ci.getJarName()+"!/"+ci.getXsltSerial()); + xslDoc = dBuilder.parse( + "jar:"+ci.getJarName()+"!/"+ci.getXsltSerial()); + } + + DOMSource xslDomSource = new DOMSource(xslDoc); + DOMSource xmlDomSource = new DOMSource(domDoc); + + //call the tranformer using the XSL, Source and Result. + TransformerFactory tFactory = TransformerFactory.newInstance(); + tFactory.setURIResolver(this); + Transformer transformer = tFactory.newTransformer(xslDomSource); + + transformer.transform(xmlDomSource, new StreamResult(baos)); + + /* + transformer.transform(xmlDomSource, xmlDomResult); //Removed this impl because the DocType was not being written out + + // Serialize for output to standard out + Serializer serializer = SerializerFactory.getSerializer + (OutputProperties.getDefaultMethodProperties("xml")); + //serializer.setOutputStream(System.out); + serializer.setOutputStream(baos); + serializer.asDOMSerializer().serialize(xmlDomResult.getNode()); + //serializer.asDOMSerializer().serialize(xmlDomSource.getNode()); + + + //System.out.println("\n** Transform Complete ***"); + */ + } + catch(Exception e){ + System.out.println("An error occured in the transformation : "+e); + } + return baos; + } + + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/GenericOfficeDocument.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/GenericOfficeDocument.java new file mode 100644 index 000000000000..636f3caa453a --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/GenericOfficeDocument.java @@ -0,0 +1,98 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: GenericOfficeDocument.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.xslt; + +import org.w3c.dom.Document; +import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * This class is an implementation of <code>OfficeDocument</code> for + * the generic office format. + */ +public class GenericOfficeDocument extends OfficeDocument { + + /** + * Constructor with arguments to set <code>name</code>. + * + * @param name The name of the <code>Document</code> + */ + public GenericOfficeDocument(String name) { + super(name); + } + + + /** + * Constructor with arguments to set <code>name</code>, the + * <code>namespaceAware</code> flag, and the <code>validating</code> + * flag. + * + * @param name The name of the <code>Document</code>. + * @param namespaceAware The value of the <code>namespaceAware</code> + * flag. + * @param validating The value of the <code>validating</code> flag. + */ + public GenericOfficeDocument(String name, boolean namespaceAware, boolean validating) { + + super(name, namespaceAware, validating); + } + + /** + * Returns the Office file extension for the generic format. + * + * @return The Office file extension for the generic format. + */ + protected String getFileExtension() { + return ""; + } + + /** + * Returns the Office attribute for the generic format. + * + * @return The Office attribute for the generic format. + */ + protected String getOfficeClassAttribute() { + + return ""; + } + + /** + * Method to return the MIME type of the document. + * + * @return String The document's MIME type. + */ + protected String getDocumentMimeType() { + /* TODO: Determine the MIME-type from the input. */ + return ""; + } + +} + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/PluginFactoryImpl.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/PluginFactoryImpl.java new file mode 100644 index 000000000000..12f9cbec4e79 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/PluginFactoryImpl.java @@ -0,0 +1,207 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PluginFactoryImpl.java,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.xslt; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.PluginFactory; +import org.openoffice.xmerge.converter.dom.DOMDocument; +//import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; +//import org.openoffice.xmerge.converter.xml.OfficeDocument; +import org.openoffice.xmerge.converter.xml.xslt.GenericOfficeDocument; +import org.openoffice.xmerge.util.registry.ConverterInfo; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.DocumentMergerFactory; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.util.registry.ConverterInfo; + +import java.io.InputStream; +import java.util.Enumeration; +import java.io.InputStream; +import java.io.IOException; +import java.util.Properties; + +/** + * <p>Xslt implementation of the <code>PluginFactory</code>. + * This encapsulates conversion of StarWriter XML format to and from + * a supported format.</p> + * + * <p>The superclass produces a particular + * {@link org.openoffice.xmerge.Document Document} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxw.SxwDocument + * SxwDocument} that the converters in this class work with. Thus, + * this class only implements the methods that produces the converters, + * i.e. {@link + * org.openoffice.xmerge.DocumentSerializer + * DocumentSerializer} and {@link + * org.openoffice.xmerge.DocumentDeserializer + * DocumentDeserializer}</p> + * + * @author Aidan Butler + */ +public final class PluginFactoryImpl extends PluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory, DocumentMergerFactory +{ + + public PluginFactoryImpl (ConverterInfo ci) { + super(ci); + } + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + /** + * Returns an instance of <code>DocumentSerializerImpl</code>, + * which is an implementation of the <code>DocumentSerializer</code> + * interface. + * + * @param doc <code>Document</code> object to be + * converted/serialized. + * + * @return A <code>DocumentSerializerImpl</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + return new DocumentSerializerImpl(this,doc); + } + + + /** + * Returns an instance of <code>DocumentDeserializerImpl</code>, + * which is an implementation of the <code>DocumentDeserializer</code> + * interface. + * + * @param is <code>ConvertData</code> object. + * + * @return A DocumentDeserializerImpl object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + + return new DocumentDeserializerImpl(this,cd); + } + + public org.openoffice.xmerge.Document createDeviceDocument(java.lang.String str, java.io.InputStream inputStream) throws java.io.IOException { + String ext = this.getDeviceFileExtension(); + DOMDocument domDoc = new DOMDocument(str,ext); + domDoc.read(inputStream); + return domDoc; + } + + + public Document createOfficeDocument(String name, InputStream is) + throws IOException { + + // read zipped XML stream + GenericOfficeDocument doc = new GenericOfficeDocument(name); + doc.read(is); + return doc; + } + + public Document createOfficeDocument(String name, InputStream is,boolean isZip) + throws IOException { + + // read zipped XML stream + GenericOfficeDocument doc = new GenericOfficeDocument(name); + doc.read(is,isZip); + return doc; + } + + /** + * Returns a <code>String</code> containing the file extension of a + * <code>Document</code>. This method uses a properties file to determine + * a mapping from the device mime in the <code>ConverterInfo</code> to a + * particular file extension. If a mapping is not specified, the default + * is ".txt". + * + * @return <code>String</code>. + */ + + + public String getDeviceFileExtension(){ + Class c = this.getClass(); + InputStream is = c.getResourceAsStream("XsltPlugin.properties"); + Properties props = new Properties(); + String ext= ".txt"; + String mimeType = null; + ConverterInfo ci = this.getConverterInfo(); + Enumeration enumer = ci.getDeviceMime(); + while (enumer.hasMoreElements()) { + mimeType= (String) enumer.nextElement(); + } + try { + props.load(is); + + String info = props.getProperty(mimeType); + if (info != null) { + ext = info; + } + } catch (Exception e) { + + // It is okay for the property file to not exist. + // + } + return ext; + } + + /** + * Returns an instance of <code>DocumentMergerImpl</code>, + * which is an implementation of the <code>DocumentMerger</code> + * interface. + * + * @param doc <code>Document</code> to merge. + * + * @return A DocumentMergerImpl object. + */ + public DocumentMerger createDocumentMerger(Document doc) { + ConverterCapabilities cc = converterCap; + DocumentMergerImpl merger = new DocumentMergerImpl(doc, cc); + return merger; + + } + +} + + + + + + + + + + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/XsltPlugin.properties b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/XsltPlugin.properties new file mode 100644 index 000000000000..434824138fc6 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/XsltPlugin.properties @@ -0,0 +1,40 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: XsltPlugin.properties,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + + +# +# XsltPlugin.properties +# + +#This file allows users to specify the mime-type to file extension mappings + +# e.g text/html=.html +text/html=.html diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/build.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/build.xml new file mode 100644 index 000000000000..d39f31baaa31 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/build.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.5 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="xmrg_jooxcx_xslt" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- project prefix, used for targets and build.lst --> + <property name="prj.prefix" value="xmrg"/> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="xmrg_jooxcx_xslt"/> + + <!-- relative path to project directory --> + <property name="prj" value="../../../../../../../"/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="${prj}/java"/> + + <!-- path component for current java package --> + <property name="package" + value="org/openoffice/xmerge/converter/xml/xslt/"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for javac tasks --> + <path id="classpath"> + <pathelement location="${build.class}"/> + <pathelement location="${solar.jar}/xalan.jar"/> + <pathelement location="${solar.jar}/parser.jar"/> + <pathelement location="${solar.jar}/jaxp.jar"/> + <pathelement location="${solar.jar}/xerces.jar"/> + </path> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <!-- ================================================================= --> + <!-- solar build environment targets --> + <!-- ================================================================= --> + + <target name="build_dir" unless="build.dir"> + <property name="build.dir" value="${out}"/> + </target> + + <target name="solar" depends="build_dir" if="solar.update"> + <property name="solar.properties" + value="${solar.bin}/solar.properties"/> + </target> + + <target name="init" depends="solar"> + <property name="build.compiler" value="classic"/> + <property file="${solar.properties}"/> + <property file="${build.dir}/class/solar.properties"/> + </target> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile"/> + + <!-- prepare output directories --> + <target name="prepare" depends="init" if="build.class"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + </target> + + <!-- compile java sources in ${package} --> + <target name="compile" depends="prepare" if="build.class"> + <javac srcdir="${java.dir}" + destdir="${build.class}" + debug="${debug}" + deprecation="${deprecation}" + optimize="${optimize}"> + <classpath refid="classpath"/> + <include name="${package}/DocumentDeserializerImpl.java"/> + <include name="${package}/DocumentSerializerImpl.java"/> + <include name="${package}/GenericOfficeDocument.java"/> + <include name="${package}/PluginFactoryImpl.java"/> + </javac> + <copy todir="${build.class}/${package}"> + <fileset dir="."> + <include name="*.properties"/> + </fileset> + </copy> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/*.class"/> + </patternset> + </fileset> + </delete> + </target> + +</project> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/converter.xml b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/converter.xml new file mode 100644 index 000000000000..e374786b53ec --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/converter.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: converter.xml,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<!--<!DOCTYPE converters SYSTEM "converter.dtd">--> +<converters> + <converter type="staroffice/sxw" version="1.0"> + <converter-display-name> + XSLT Transformation + </converter-display-name> + <converter-description> + Converter which performs xslt transformations + </converter-description> + <converter-vendor>OpenOffice.org</converter-vendor> + <converter-class-impl> + org.openoffice.xmerge.converter.xml.xslt.PluginFactoryImpl + </converter-class-impl> + <converter-xslt-serialize> + sofftohtml.xsl + </converter-xslt-serialize> + <converter-xslt-deserialize> + htmltosoff.xsl + </converter-xslt-deserialize> + <converter-target type="text/html" /> + </converter> +</converters> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/DBFilter.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/DBFilter.java new file mode 100644 index 000000000000..6d472e61e44c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/DBFilter.java @@ -0,0 +1,573 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DBFilter.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +//Standard Java classes +import java.util.Enumeration; +import java.util.Vector; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import com.sun.star.xml.XImportFilter; +import com.sun.star.xml.XExportFilter; +import java.io.*; +import java.util.regex.*; + +// Imported TraX classes +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.transform.URIResolver; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.OutputKeys; + +//StarOffice Interfaces and UNO +import com.sun.star.uno.AnyConverter; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.lang.XServiceName; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; +import com.sun.star.frame.XConfigManager; +import com.sun.star.xml.sax.InputSource; +import com.sun.star.xml.sax.XParser; +import com.sun.star.io.XInputStream; +import com.sun.star.io.XOutputStream; +import com.sun.star.xml.sax.XDocumentHandler; + +//Uno to java Adaptor +import com.sun.star.lib.uno.adapter.*; + +/** This outer class provides an inner class to implement the service + * description, a method to instantiate the + * component on demand (__getServiceFactory()), and a method to give + * information about the component (__writeRegistryServiceInfo()). + */ +public class DBFilter { + + + private static XMultiServiceFactory xMSF; + + /** This inner class provides the component as a concrete implementation + * of the service description. It implements the needed interfaces. + * @implements XTypeProvider + */ + public static class _DBFilter implements + XImportFilter, + XExportFilter, + XServiceName, + XServiceInfo, + XDocumentHandler, + XTypeProvider { + + private boolean indent; + private XInputStream xInStream; + private XOutputStream xOutStream; + private XOutputStream xos; + private String sExportStyleSheet; + private String doctype_public; + private String doctype_system; + + public _DBFilter() + { + indent = false; + xInStream = null; + xOutStream = null; + xos = null; + sExportStyleSheet = null; + doctype_public = null; + doctype_system = null; + } + + /** The component will be registered under this name. + */ + static private final String __serviceName = "com.sun.star.documentconversion.DBFilter"; + + public com.sun.star.uno.Type[] getTypes() { + Type[] typeReturn = {}; + + try { + typeReturn = new Type[] { + new Type( XTypeProvider.class ), + new Type( XExportFilter.class ), + new Type( XImportFilter.class ), + new Type( XServiceName.class ), + new Type( XServiceInfo.class ) }; + } + catch( Exception exception ) { + + } + + return( typeReturn ); + } + + + public boolean importer(com.sun.star.beans.PropertyValue[] aSourceData, + com.sun.star.xml.sax.XDocumentHandler xDocHandler, + java.lang.String[] msUserData) throws com.sun.star.uno.RuntimeException,com.sun.star.lang.IllegalArgumentException { + /* + System.out.println("\nFound the Java Importer!\n"); + + System.out.println("\n"+msUserData[0]); + System.out.println("\n"+msUserData[1]); + System.out.println("\n"+msUserData[2]); + System.out.println("\n"+msUserData[3]); + System.out.println("\n"+xDocHandler); + System.out.println("\n"+msUserData[4]); + System.out.println("\n"+msUserData[5]); + */ + String sFileName=null; + String udImport =msUserData[2]; + String sImportStyleSheet =msUserData[4]; + sExportStyleSheet =msUserData[5]; + com.sun.star.io.XInputStream xis=null; + com.sun.star.beans.PropertyValue[] pValue = aSourceData; + + for (int i = 0 ; i < pValue.length; i++) + { + try{ + //System.out.println("\n"+pValue[i].Name+" "+pValue[i].Value); + if (pValue[i].Name.compareTo("InputStream")==0){ + xis=(com.sun.star.io.XInputStream)AnyConverter.toObject(new Type(com.sun.star.io.XInputStream.class), pValue[i].Value); + } + else if (pValue[i].Name.compareTo("FileName")==0){ + sFileName=(String)AnyConverter.toObject(new Type(java.lang.String.class), pValue[i].Value); + } + else if (pValue[i].Name.compareTo("Indent")==0){ //to be changed to new value for indentation from XSLT UI + indent=(boolean)AnyConverter.toBoolean(pValue[i].Value); + } + else if (pValue[i].Name.compareTo("DocType_Public")==0){ + doctype_public = AnyConverter.toString(pValue[i].Value); + } + else if (pValue[i].Name.compareTo("DocType_System")==0){ + doctype_system = AnyConverter.toString(pValue[i].Value); + } } + catch(com.sun.star.lang.IllegalArgumentException AnyExec){ + System.out.println("\nIllegalArgumentException "+AnyExec); + } + + } + + try{ + + Object xCfgMgrObj=xMSF.createInstance("com.sun.star.config.SpecialConfigManager"); + XConfigManager xCfgMgr = (XConfigManager) UnoRuntime.queryInterface( + XConfigManager.class , xCfgMgrObj ); + String PathString=xCfgMgr.substituteVariables("$(progurl)" ); + PathString= PathString.concat("/"); + Object xPipeObj=xMSF.createInstance("com.sun.star.io.Pipe"); + xInStream = (XInputStream) UnoRuntime.queryInterface( + XInputStream.class , xPipeObj ); + xOutStream = (XOutputStream) UnoRuntime.queryInterface( + XOutputStream.class , xPipeObj ); + if (!sImportStyleSheet.equals("")){ + if (!sImportStyleSheet.startsWith("file:")&&!sImportStyleSheet.startsWith("http:") + &&!sExportStyleSheet.startsWith("shttp:") + &&!sExportStyleSheet.startsWith("jar:")){ + sImportStyleSheet=PathString.concat(sImportStyleSheet); + } + } + convert (xis,xOutStream,sImportStyleSheet,true); + xOutStream.closeOutput(); + Object xSaxParserObj=xMSF.createInstance("com.sun.star.xml.sax.Parser"); + XParser xParser = (XParser) UnoRuntime.queryInterface( + XParser.class , xSaxParserObj ); + InputSource aInput = new InputSource(); + if (sFileName==null) + sFileName=" "; + aInput.sSystemId = sFileName; + aInput.aInputStream =xInStream; + xParser.setDocumentHandler ( xDocHandler ); + xParser.parseStream ( aInput ); + xInStream.closeInput(); + + } + catch (Exception AnyExec){ + //e.printStackTrace(); + System.out.println("\nException "+AnyExec); + throw new com.sun.star.uno.RuntimeException(AnyExec.getMessage()); + } + return true; + } + + + + public boolean exporter(com.sun.star.beans.PropertyValue[] aSourceData, + java.lang.String[] msUserData) throws com.sun.star.uno.RuntimeException,com.sun.star.lang.IllegalArgumentException { + /* + System.out.println("\nFound the Exporter!\n"); + + System.out.println("\n0"+msUserData[0]); + System.out.println("\n1"+msUserData[1]); + System.out.println("\n2"+msUserData[2]); + System.out.println("\n3"+msUserData[3]); + + System.out.println("\n4"+msUserData[4]); + System.out.println("\n5"+msUserData[5]); + */ + String udImport =msUserData[2]; + sExportStyleSheet =msUserData[5]; + com.sun.star.beans.PropertyValue[] pValue = aSourceData; + for (int i = 0 ; i < pValue.length; i++) + { + try{ + //System.out.println("\n"+pValue[i].Name+" "+pValue[i].Value); + if (pValue[i].Name.compareTo("OutputStream")==0){ + xos=(com.sun.star.io.XOutputStream)AnyConverter.toObject(new Type(com.sun.star.io.XOutputStream.class), pValue[i].Value); + // System.out.println(pValue[i].Name+" "+xos); + } + else if (pValue[i].Name.compareTo("Indent")==0){ //to be changed to new value for indentation from XSLT UI + indent=(boolean)AnyConverter.toBoolean(pValue[i].Value); + } + else if (pValue[i].Name.compareTo("DocType_Public")==0){ + doctype_public = AnyConverter.toString(pValue[i].Value); + } + else if (pValue[i].Name.compareTo("DocType_System")==0){ + doctype_system = AnyConverter.toString(pValue[i].Value); + } + + } + catch(com.sun.star.lang.IllegalArgumentException AnyExec){ + System.out.println("\nIllegalArgumentException "+AnyExec); + } + } + + + try{ + + Object xCfgMgrObj=xMSF.createInstance("com.sun.star.config.SpecialConfigManager"); + XConfigManager xCfgMgr = (XConfigManager) UnoRuntime.queryInterface( + XConfigManager.class , xCfgMgrObj ); + + String PathString=xCfgMgr.substituteVariables("$(progurl)" ); + PathString= PathString.concat("/"); + Object xPipeObj=xMSF.createInstance("com.sun.star.io.Pipe"); + xInStream = (XInputStream) UnoRuntime.queryInterface( + XInputStream.class , xPipeObj ); + xOutStream = (XOutputStream) UnoRuntime.queryInterface( + XOutputStream.class , xPipeObj ); + if (!sExportStyleSheet.equals("")){ + if (!sExportStyleSheet.startsWith("file:")&&!sExportStyleSheet.startsWith("http:") + &&!sExportStyleSheet.startsWith("shttp:") + &&!sExportStyleSheet.startsWith("jar:")){ + sExportStyleSheet=PathString.concat(sExportStyleSheet); + } + } + } + catch (Exception AnyExec){ + System.out.println("Exception "+AnyExec); + throw new com.sun.star.uno.RuntimeException(AnyExec.getMessage()); + } + return true; + } + + public String replace(String origString, String origChar, String replaceChar){ + String tmp=""; + int index=origString.indexOf(origChar); + if(index !=-1){ + while (index !=-1){ + String first =origString.substring(0,index); + first=first.concat(replaceChar); + tmp=tmp.concat(first); + origString=origString.substring(index+1,origString.length()); + index=origString.indexOf(origChar); + if(index==-1) { + tmp=tmp.concat(origString); + } + } + } + return tmp; + } + + public String needsMask(String origString){ + + if (origString.indexOf("&")!=-1){ + origString=replace(origString,"&","&"); + } + if (origString.indexOf("\"")!=-1){ + origString=replace(origString,"\"","""); + } + if (origString.indexOf("<")!=-1){ + origString=replace(origString,"<","<"); + } + if (origString.indexOf(">")!=-1){ + origString=replace(origString,">",">"); + } + return origString; + } + + + + public void startDocument (){ + } + + public void endDocument() + { + convert (xInStream,xos,sExportStyleSheet,false); + } + + public void startElement (String str, com.sun.star.xml.sax.XAttributeList xattribs) + { + + str="<".concat(str); + if (xattribs !=null) + { + str= str.concat(" "); + int len=xattribs.getLength(); + for (short i=0;i<len;i++) + { + str=str.concat(xattribs.getNameByIndex(i)); + str=str.concat("=\""); + //str=str.concat(xattribs.getValueByIndex(i)); + str=str.concat(needsMask(xattribs.getValueByIndex(i))); + str=str.concat("\" "); + } + } + str=str.concat(">"); + //System.out.println(str); + try{ + //xOutStream.writeBytes(str.getBytes()); + xOutStream.writeBytes(str.getBytes("UTF-8")); + } + catch (Exception e){ + System.out.println("\n"+e); + } + + } + + public void endElement(String str){ + str="</".concat(str); + str=str.concat(">"); + str=str.concat("\n"); + try{ + xOutStream.writeBytes(str.getBytes("UTF-8")); + } + catch (Exception e){ + System.out.println("\n"+e); + } + // System.out.println(str); + + } + public void characters(String str){ + str=needsMask(str); + try{ + xOutStream.writeBytes(str.getBytes("UTF-8")); + } + catch (Exception e){ + System.out.println("\n"+e); + } + + } + + public void ignorableWhitespace(String str){ + + + } + public void processingInstruction(String aTarget, String aData){ + + } + + public void setDocumentLocator(com.sun.star.xml.sax.XLocator xLocator){ + + } + + private String maskEntities(String xmlString){ + Pattern testpattern = Pattern.compile("<!ENTITY [a-zA-Z0-9#]* "); + Matcher testmatch= testpattern.matcher(xmlString); + //System.out.println("\nStarting replace"); + int offset=0; + while (testmatch.find(offset)){ + String newstring = xmlString.substring(testmatch.start()+9,testmatch.end()-1); + offset= testmatch.end(); + //System.out.println("\nReplacing " +newstring); + + xmlString=xmlString.replaceAll("&"+newstring+";","<entity name=\""+newstring+"\">"+"&"+newstring+";"+"</entity>"); + testmatch = testmatch.reset(); + testmatch= testpattern.matcher(xmlString); + //System.out.println("\nFound Pattern "+testmatch.replaceFirst("<entity>"+newstring+"</entity>")); + newstring= ""; + } + return xmlString; + } + + public void convert (com.sun.star.io.XInputStream xml, + com.sun.star.io.XOutputStream device,String sStyleSheet,boolean importing ) throws com.sun.star.uno.RuntimeException { + XInputStreamToInputStreamAdapter xis =new XInputStreamToInputStreamAdapter(xml); + XOutputStreamToOutputStreamAdapter xos = + new XOutputStreamToOutputStreamAdapter(device); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + String xmlFile=null; + try{ + //call the tranformer using the XSL, Source and Result dom. + TransformerFactory tFactory = TransformerFactory.newInstance(); + //tFactory.setURIResolver(this); + Transformer transformer =null; + transformer = tFactory.newTransformer( new StreamSource(sStyleSheet)); + if(indent){ // required for displaying XML correctly in XSLT UI + transformer.setOutputProperty("indent", "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "1"); + } + if(null != doctype_public){ + transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype_public); + } + if(null != doctype_system){ + transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype_system); + } + if (importing) + { + byte tmpArr[]=new byte[1000]; + while (xis.available()>0){ + int read = xis.read(tmpArr); + baos.write(tmpArr,0,read); + tmpArr =new byte[1000]; + } + xmlFile = maskEntities(baos.toString("UTF-8")); + + //xmlFile = baos.toString("UTF-8"); + if (xmlFile.indexOf("<!DOCTYPE")!=-1){ + String tag= xmlFile.substring(xmlFile.lastIndexOf("/")+1,xmlFile.lastIndexOf(">")); + String entities = ""; + if(xmlFile.indexOf("[",xmlFile.indexOf("<!DOCTYPE"))!=-1){ + if(xmlFile.indexOf("[",xmlFile.indexOf("<!DOCTYPE")) < xmlFile.indexOf(">",xmlFile.indexOf("<!DOCTYPE"))){ + entities = xmlFile.substring(xmlFile.indexOf("[",xmlFile.indexOf("<!DOCTYPE")),xmlFile.indexOf("]",xmlFile.indexOf("<!DOCTYPE"))+1); + } + } + String newDocType = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE "+tag+" "+entities+">"; + xmlFile= xmlFile.substring(xmlFile.indexOf("<"+tag,0), xmlFile.lastIndexOf(">")+1); + xmlFile= newDocType.concat(xmlFile); + //throw new com.sun.star.uno.RuntimeException(xmlFile); + } + ByteArrayInputStream bais = new ByteArrayInputStream(xmlFile.getBytes("UTF-8")); + transformer.transform(new StreamSource(bais),new StreamResult(xos)); + } + else + transformer.transform(new StreamSource(xis),new StreamResult(xos)); + } + catch (TransformerConfigurationException transConfExc) + { + throw new com.sun.star.uno.RuntimeException(transConfExc.getMessage()); + } + catch (TransformerException transExc){ + //System.out.println("\nException "+ e); + throw new com.sun.star.uno.RuntimeException(transExc.getMessage()); + } + catch (Exception e){ + System.out.println("\nException "+ e); + throw new com.sun.star.uno.RuntimeException(e.getMessage()); + } + } + + + + + // Implement methods from interface XTypeProvider + public byte[] getImplementationId() { + byte[] byteReturn = {}; + + byteReturn = new String( "" + this.hashCode() ).getBytes(); + + return( byteReturn ); + } + + // Implement method from interface XServiceName + public String getServiceName() { + return( __serviceName ); + } + + // Implement methods from interface XServiceInfo + public boolean supportsService(String stringServiceName) { + return( stringServiceName.equals( __serviceName ) ); + } + + public String getImplementationName() { + return( _DBFilter.class.getName() ); + } + + public String[] getSupportedServiceNames() { + String[] stringSupportedServiceNames = { __serviceName }; + return( stringSupportedServiceNames ); + } + } + + /** + * Returns a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * + * @return returns a <code>XSingleServiceFactory</code> for creating the + * component + * + * @param implName the name of the implementation for which a + * service is desired + * @param multiFactory the service manager to be used if needed + * @param regKey the registryKey + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) { + XSingleServiceFactory xSingleServiceFactory = null; + xMSF= multiFactory; + if (implName.equals(_DBFilter.class.getName()) ) { + xSingleServiceFactory = FactoryHelper.getServiceFactory(_DBFilter.class, + _DBFilter.__serviceName, + multiFactory, + regKey); + } + + return xSingleServiceFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + + return FactoryHelper.writeRegistryServiceInfo(_DBFilter.class.getName(), + _DBFilter.__serviceName, regKey); + } +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/Manifest b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/Manifest new file mode 100644 index 000000000000..108fba617702 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/Manifest @@ -0,0 +1 @@ +RegistrationClassName: DBFilter diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/Readme.txt b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/Readme.txt new file mode 100644 index 000000000000..d67b2aaeeac9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/Readme.txt @@ -0,0 +1,14 @@ +DBFilter Readme +=============== + +The DocBook filter (DBFilter) is essentially teh XSLTFilter that is +delivered with Openoffice, except that it contains an extra routine +for Masking DOCTYPE Entity declarations. In this way, Entities +which are referenced inside the XML Document to be imported, +are converted into an <entity name="ent_name"> tag. In this way, +the entities can be imported into OOo as "set" and "get" variables. + +On Export, these variables can be written out once again as correct +Enity decls and Entity references. + +
\ No newline at end of file diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/makefile.mk new file mode 100644 index 000000000000..b2c709523a97 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbookfilter/makefile.mk @@ -0,0 +1,64 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ = ..$/.. +PRJNAME = filter +#PACKAGE = com$/sun$/star$/documentconversion$/DBFilter +TARGET =DBFilter +# --- Settings ----------------------------------------------------- +.INCLUDE: settings.mk +CLASSDIR!:=$(CLASSDIR)$/$(TARGET) +#USE_UDK_EXTENDED_MANIFESTFILE=TRUE +#USE_EXTENDED_MANIFESTFILE=TRUE +JARFILES = sandbox.jar ridl.jar unoil.jar jurt.jar juh.jar +JAVAFILES = $(subst,$(CLASSDIR)$/, $(subst,.class,.java $(JAVACLASSFILES))) +CUSTOMMANIFESTFILE = Manifest +#JARMANIFEST = Manifest + +#JARDIR=$(CLASSDIR) + +JARCOMPRESS = TRUE +JARCLASSDIRS = DBFilter*.class +JARTARGET = $(TARGET).jar + + +# --- Files -------------------------------------------------------- +JAVACLASSFILES=$(CLASSDIR)$/DBFilter.class +#---Manifest ------------------------------------------------------- +#$(OUT)$/class$/$(TARGET)$/META-INF: META-INF +# + $(COPY) $(COPYRECURSE) META-INF $(OUT)$/class$/DBFilter$/META-INF +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk +$(JAVACLASSFILES) : $(CLASSDIR) + +$(CLASSDIR) : + $(MKDIR) $(CLASSDIR) + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbooktosoffheadings.xsl b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbooktosoffheadings.xsl new file mode 100644 index 000000000000..831cea906b57 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/docbooktosoffheadings.xsl @@ -0,0 +1,1729 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: docbooktosoffheadings.xsl,v $ + + $Revision: 1.7 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:office="http://openoffice.org/2000/office" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="http://openoffice.org/2000/meta" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" xmlns:config="http://openoffice.org/2001/config" version="1.0" office:class="text" office:version="1.0"> + <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/> + <!--<xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-public="-//OASIS//DTD DocBook XML V4.1.2//EN" doctype-system="http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"/>--> + <xsl:decimal-format name="staff" digit="D"/> + + <xsl:variable name="doc_type"> + <xsl:choose> + <xsl:when test="/article"> + <xsl:text>article</xsl:text> + </xsl:when> + <xsl:when test="/chapter"> + <xsl:text>chapter</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:variable> + + + <xsl:template match="/"> + <xsl:element name="office:document"> + <office:meta> + <meta:generator>StarOffice 6.1 (Solaris Sparc)</meta:generator> + <dc:title> + <xsl:choose> + <xsl:when test="contains( $doc_type, 'chapter' )"> + <xsl:value-of select="/chapter/chapterinfo/title"/> + </xsl:when> + <xsl:when test="contains( $doc_type, 'article' )"> + <xsl:value-of select="/article/articleinfo/title"/> + </xsl:when> + </xsl:choose> + <!--<xsl:value-of select="$doc_type"/>--> + <!--<xsl:value-of select="/article/articleinfo/title"/>--> + + </dc:title> + <dc:description/> + <dc:subject/> + <meta:creation-date>2002-07-15T12:38:53</meta:creation-date> + <dc:date> + <xsl:choose> + <xsl:when test="contains( $doc_type, 'chapter' )"> + <xsl:value-of select="/chapter/chapterinfo/pubdate"/> + </xsl:when> + <xsl:when test="contains( $doc_type, 'article' )"> + <xsl:value-of select="/article/articleinfo/pubdate"/> + </xsl:when> + </xsl:choose> + <!--<xsl:value-of select="article/articleinfo/pubdate"/>--> + + </dc:date> + <dc:language> + <xsl:choose> + <xsl:when test="contains( $doc_type, 'chapter' )"> + <xsl:value-of select="chapter/@lang"/> + </xsl:when> + <xsl:when test="contains( $doc_type, 'article' )"> + <xsl:value-of select="article/@lang"/> + </xsl:when> + </xsl:choose> + <!--<xsl:value-of select="article/@lang"/>--> + + </dc:language> + <meta:editing-cycles>21</meta:editing-cycles> + <meta:editing-duration>P1DT0H11M54S</meta:editing-duration> + <meta:user-defined meta:name="Info 1"/> + <meta:user-defined meta:name="Info 2"/> + <meta:user-defined meta:name="Info 3"/> + <meta:user-defined meta:name="Info 4"/> + <meta:document-statistic meta:table-count="1" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="42" meta:word-count="144" meta:character-count="820"/> + </office:meta> + <office:automatic-styles> + <style:style style:name="fr1" style:family="graphics" style:parent-style-name="Graphics"> + <style:properties style:horizontal-pos="center" style:horizontal-rel="paragraph" style:mirror="none" fo:clip="rect(0cm 0cm 0cm 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="1" draw:color-inversion="false" draw:transparency="-100%" draw:color-mode="standard"/> + </style:style> + <style:style style:name="Table1" style:family="table"> + <style:properties style:width="14.649cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:properties style:column-width="2.93cm" style:rel-column-width="13107*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border-left="0.002cm solid #000000" fo:border-right="none" fo:border-top="0.002cm solid #000000" fo:border-bottom="0.002cm solid #000000"/> + </style:style> + <style:style style:name="Table1.E1" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border="0.002cm solid #000000"/> + </style:style> + <style:style style:name="Table1.A2" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border-left="0.002cm solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.002cm solid #000000"/> + </style:style> + <style:style style:name="Table1.E2" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border-left="0.002cm solid #000000" fo:border-right="0.002cm solid #000000" fo:border-top="none" fo:border-bottom="0.002cm solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Text body" style:list-style-name="Ordered List"/> + <style:style style:name="T1" style:family="text" style:parent-style-name="Source Text"> + <style:properties fo:font-style="normal"/> + </style:style> + <style:page-master style:name="pm1"> + <style:properties fo:page-width="20.999cm" fo:page-height="29.699cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2.54cm" fo:margin-bottom="2.54cm" fo:margin-left="3.175cm" fo:margin-right="3.175cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:properties> + <style:header-style/> + <style:footer-style/> + </style:page-master> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-master-name="pm1"/> + </office:master-styles> + <office:body> + <xsl:call-template name="entities"/> + <xsl:apply-templates/> + </office:body> + </xsl:element> + </xsl:template> + + +<xsl:template name="entities"> + <xsl:element name="text:variable-decls"> + <xsl:for-each select="/descendant::entity"> + <xsl:variable name="entname"><xsl:value-of select="@name"/></xsl:variable> + <xsl:if test="not(preceding::entity[@name = $entname])"> + <xsl:element name="text:variable-decl"> + <xsl:attribute name="text:value-type"> + <xsl:text>string</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:text>entitydecl_</xsl:text><xsl:value-of select="@name"/> + </xsl:attribute> + </xsl:element> + </xsl:if> + </xsl:for-each> + </xsl:element> +</xsl:template> + + + +<xsl:template match="entity"> + <xsl:variable name="entname"><xsl:value-of select="@name"/></xsl:variable> + <xsl:choose> + <xsl:when test="not(preceding::entity[@name = $entname])"> + <xsl:element name="text:variable-set"> + <xsl:attribute name="text:value-type"> + <xsl:text>string</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:text>entitydecl_</xsl:text><xsl:value-of select="@name"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:element name="text:variable-get"> + <xsl:attribute name="text:value-type"> + <xsl:text>string</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:text>entitydecl_</xsl:text><xsl:value-of select="@name"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + +</xsl:template> + + + + <!-- table start --> + + <xsl:template match="table"> + <xsl:variable name="tabletitle"> + <xsl:value-of select="title"/> + </xsl:variable> + <xsl:element name="table:table"> + <xsl:attribute name="table:name"/> + <xsl:attribute name="table:style-name">Table1</xsl:attribute> + <xsl:attribute name="table:name"> + <xsl:value-of select="@id"/> + </xsl:attribute> + <blah>blah</blah> + <xsl:apply-templates/> + </xsl:element> + <xsl:if test="not($tabletitle='')"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">Table</xsl:attribute> + <xsl:value-of select="$tabletitle"/> + </xsl:element> + </xsl:if> + </xsl:template> + + + <xsl:template match="tgroup"> + <xsl:element name="table:table-column"> + <xsl:attribute name="table:style-name">Table1.A</xsl:attribute> + <xsl:choose> + <xsl:when test="@cols >0"> + <xsl:attribute name="table:number-columns-repeated"> + <xsl:value-of select="@cols"/> + </xsl:attribute> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="table:number-columns-repeated"> + <xsl:value-of select="count(child::tbody/row/entry) div count(child::tbody/row) "/> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="thead"> + <xsl:element name="table:table-header-rows"> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="tbody"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="row"> + <xsl:element name="table:table-row"> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="entry"> + <xsl:element name="table:table-cell"> + <xsl:if test="ancestor-or-self::thead"> + <xsl:attribute name="table:style-name">Table1.A1</xsl:attribute> + </xsl:if> + <xsl:if test="not(ancestor-or-self::thead)"> + <xsl:attribute name="table:style-name">Table1.A2</xsl:attribute> + </xsl:if> + <xsl:choose> + <xsl:when test="@spanname"> + <!--<xsl:if test="@spanname">--> + + <xsl:variable name="sname"> + <xsl:value-of select="@spanname"/> + </xsl:variable> + <xsl:attribute name="table:number-columns-spanned"> + <xsl:variable name="colnamestart"> + <xsl:value-of select="ancestor::tgroup/spanspec[@spanname=$sname]/@namest"/> + </xsl:variable> + <xsl:variable name="colnameend"> + <xsl:value-of select="ancestor::tgroup/spanspec[@spanname=$sname]/@nameend"/> + </xsl:variable> + <xsl:variable name="colnumstart"> + <xsl:value-of select="ancestor::tgroup/colspec[@colname=$colnamestart]/@colnum"/> + </xsl:variable> + <xsl:variable name="colnumend"> + <xsl:value-of select="ancestor::tgroup/colspec[@colname=$colnameend]/@colnum"/> + </xsl:variable> + <xsl:value-of select="$colnumend - $colnumstart + 1"/> + </xsl:attribute> + </xsl:when> + <xsl:when test="@namest and @nameend"> + <!--<xsl:if test="@namest and @nameend">--> + + <xsl:variable name="colnamestart"> + <xsl:value-of select="@namest"/> + </xsl:variable> + <xsl:variable name="colnameend"> + <xsl:value-of select="@nameend"/> + </xsl:variable> + <xsl:attribute name="table:number-columns-spanned"> + <xsl:variable name="colnumstart"> + <xsl:value-of select="ancestor::tgroup/colspec[@colname=$colnamestart]/@colnum"/> + </xsl:variable> + <xsl:variable name="colnumend"> + <xsl:value-of select="ancestor::tgroup/colspec[@colname=$colnameend]/@colnum"/> + </xsl:variable> + <xsl:value-of select="$colnumend - $colnumstart + 1"/> + </xsl:attribute> + </xsl:when> + </xsl:choose> + <!-- + <xsl:if test="not(@namest = '' ) "> + <xsl:attribute name="table:number-columns-spanned"> + <xsl:value-of select="(substring-after(@nameend,'c')-substring-after(@namest,'c'))+1"/> + + </xsl:attribute> + </xsl:if> + --> + + <xsl:choose> + <xsl:when test="not(child::para)"> + <xsl:element name="text:p"> + <xsl:if test="ancestor-or-self::thead"> + <xsl:attribute name="text:style-name">Table Heading</xsl:attribute> + </xsl:if> + <xsl:if test="ancestor-or-self::tbody"> + <xsl:attribute name="text:style-name">Table Contents</xsl:attribute> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + </xsl:template> + + + <xsl:template match="subtitle"> + <xsl:choose> + <xsl:when test="parent::table"> + <xsl:apply-templates/> + </xsl:when> + <xsl:when test="parent::informaltable"> + <xsl:apply-templates/> + </xsl:when> + <xsl:otherwise> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">Section SubTitle</xsl:attribute> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="title"> + <xsl:choose> + <xsl:when test="parent::figure"/> + <xsl:when test="parent::table"/> + <xsl:when test="parent::sect1"/> + <xsl:when test="parent::sect2"/> + <xsl:when test="parent::sect3"/> + <xsl:when test="parent::sect4"/> + <xsl:when test="parent::sect5"/> + <xsl:when test="parent::informaltable"> + <xsl:apply-templates/> + </xsl:when> + <xsl:otherwise> + <xsl:element name="text:p"> + <xsl:choose> + <xsl:when test="parent::appendix"> + <xsl:attribute name="text:style-name">Appendix Title</xsl:attribute> + </xsl:when> + </xsl:choose> + <xsl:apply-templates/> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="articleinfo"> + <xsl:element name="text:section"> + <xsl:attribute name="text:style-name">ArticleInfo</xsl:attribute> + <xsl:attribute name="text:name">ArticleInfo</xsl:attribute> + <xsl:if test="/article/articleinfo/subtitle !=''"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">Document SubTitle</xsl:attribute> + <xsl:value-of select="/article/articleinfo/subtitle"/> + </xsl:element> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="chapterinfo"> + <xsl:element name="text:section"> + <xsl:attribute name="text:style-name">ChapterInfo</xsl:attribute> + <xsl:attribute name="text:name">ChapterInfo</xsl:attribute> + <xsl:if test="/chapter/chapterinfo/title !='' "> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">Document Title</xsl:attribute> + <xsl:value-of select="/chapter/chapterinfo/title"/> + </xsl:element> + <xsl:if test="/chapter/chapterinfo/subtitle !=''"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">Document SubTitle</xsl:attribute> + <xsl:value-of select="/chapter/chapterinfo/subtitle"/> + </xsl:element> + </xsl:if> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="appendix"> + <xsl:element name="text:section"> + <xsl:attribute name="text:style-name">Appendix</xsl:attribute> + <xsl:attribute name="text:name">Appendix</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + <!-- +<xsl:template match="author"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="firstname"> + <xsl:element name="text:variable-set"> + <xsl:attribute name="text:name"> + <xsl:if test="ancestor::articleinfo/author"> + <xsl:text disable-output-escaping="yes">articleinfo.author</xsl:text><xsl:value-of select="count(parent::author[preceding-sibling::author])"/><xsl:text disable-output-escaping="yes">.firstname</xsl:text><xsl:value-of select="count(preceding-sibling::firstname)"/> + </xsl:if> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> +</xsl:template> +--> + + <xsl:template match="articleinfo/title | chapterinfo/title"> + <!-- <xsl:element name="text:variable-decls"> + <xsl:element name="text:variable-decl"> + <xsl:attribute name="text:value-type"> + <xsl:text>string</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:text disable-output-escaping="yes">articleinfo.title</xsl:text> + </xsl:attribute> + </xsl:element> + + </xsl:element> + <xsl:element name="text:p"> + <xsl:element name="text:variable-set"> + <xsl:attribute name="text:value-type"> + <xsl:text>string</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:text disable-output-escaping="yes">articleinfo.title</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:element> + --> + </xsl:template> + + + <xsl:template match="articleinfo/title"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">Document Title</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> +</xsl:template> + +<xsl:template match="date"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>date_</xsl:text><xsl:value-of select="count(preceding::date)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>date_</xsl:text><xsl:value-of select="count(preceding::date)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="revision"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>revision_</xsl:text><xsl:value-of select="count(preceding::revision)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>revision_</xsl:text><xsl:value-of select="count(preceding::revision)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="revnumber"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>revnumber_</xsl:text><xsl:value-of select="count(preceding::revnumber)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>revnumber_</xsl:text><xsl:value-of select="count(preceding::revnumber)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="revdescription"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>revdescription_</xsl:text><xsl:value-of select="count(preceding::revdescription)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>revdescription_</xsl:text><xsl:value-of select="count(preceding::revdescription)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="revhistory"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>revhistory_</xsl:text><xsl:value-of select="count(preceding::revhistory)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>revhistory_</xsl:text><xsl:value-of select="count(preceding::revhistory)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:line-break"/> + </xsl:element> +</xsl:template> + +<xsl:template match="legalnotice"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>legalnotice_</xsl:text><xsl:value-of select="count(preceding::legalnotice)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>legalnotice_</xsl:text><xsl:value-of select="count(preceding::legalnotice)"/> + </xsl:attribute> + </xsl:element> + </xsl:element> +</xsl:template> + +<xsl:template match="legalnotice/title"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>title_</xsl:text><xsl:value-of select="count(preceding::legalnotice/title)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>title_</xsl:text><xsl:value-of select="count(preceding::legalnotice/title)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="para[ancestor::articleinfo]"> + <xsl:element name="text:s"/> + + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>para_</xsl:text><xsl:value-of select="count(preceding::para[ancestor::articleinfo])"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>para_</xsl:text><xsl:value-of select="count(preceding::para[ancestor::articleinfo])"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + + +<xsl:template match="articleinfo/subtitle"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>subtitle_</xsl:text><xsl:value-of select="count(preceding::articleinfo/subtitle)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>subtitle_</xsl:text><xsl:value-of select="count(preceding::articleinfo/subtitle)"/> + </xsl:attribute> + </xsl:element> + </xsl:element> +</xsl:template> + +<xsl:template match="articleinfo/edition"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>edition_</xsl:text><xsl:value-of select="count(preceding::articleinfo/edition)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>edition_</xsl:text><xsl:value-of select="count(preceding::articleinfo/edition)"/> + </xsl:attribute> + </xsl:element> + </xsl:element> +</xsl:template> + +<xsl:template match="articleinfo/releaseinfo"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>releaseinfo_</xsl:text><xsl:value-of select="count(preceding::articleinfo/releaseinfo)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>releaseinfo_</xsl:text><xsl:value-of select="count(preceding::articleinfo/releaseinfo)"/> + </xsl:attribute> + </xsl:element> + </xsl:element> +</xsl:template> + + +<xsl:template match="author/firstname"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>firstname_</xsl:text><xsl:value-of select="count(preceding::author/firstname)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>firstname_</xsl:text><xsl:value-of select="count(preceding::author/firstname)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + +</xsl:template> + + + +<xsl:template match="year[ancestor::articleinfo]"> + <xsl:element name="text:s"/> + + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>year_</xsl:text><xsl:value-of select="count(preceding::year[ancestor::articleinfo])"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>year_</xsl:text><xsl:value-of select="count(preceding::year[ancestor::articleinfo])"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + +</xsl:template> + +<xsl:template match="authorgroup"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>authorgroup_</xsl:text><xsl:value-of select="count(preceding::authorgroup)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>authorgroup_</xsl:text><xsl:value-of select="count(preceding::authorgroup)"/> + </xsl:attribute> + </xsl:element> + </xsl:element> +</xsl:template> + +<xsl:template match="articleinfo/copyright/holder"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>holder_</xsl:text><xsl:value-of select="count(preceding::articleinfo/copyright/holder)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>holder_</xsl:text><xsl:value-of select="count(preceding::articleinfo/copyright/holder)"/> + </xsl:attribute> + </xsl:element> + <!--<xsl:element name="text:s"/>--> + <xsl:element name="text:line-break"/> +</xsl:template> + +<xsl:template match="articleinfo/copyright"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>copyright_</xsl:text><xsl:value-of select="count(preceding::articleinfo/copyright)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>copyright_</xsl:text><xsl:value-of select="count(preceding::articleinfo/copyright)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + </xsl:element> +</xsl:template> + + +<xsl:template name="affiliation"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>affiliation_</xsl:text><xsl:value-of select="count(preceding::affiliation)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>affiliation_</xsl:text><xsl:value-of select="count(preceding::affiliation)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="author/affiliation/address"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>address_</xsl:text><xsl:value-of select="count(preceding::author/affiliation/address)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>address_</xsl:text><xsl:value-of select="count(preceding::author/affiliation/address)"/> + </xsl:attribute> + </xsl:element> +</xsl:element> +</xsl:template> + +<xsl:template match="authorgroup"> + <xsl:element name="text:p"> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>authorgroup_</xsl:text><xsl:value-of select="count(preceding::authorgroup)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>authorgroup_</xsl:text><xsl:value-of select="count(preceding::authorgroup)"/> + </xsl:attribute> + </xsl:element> +</xsl:element> +</xsl:template> + + +<xsl:template match="author"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>author_</xsl:text><xsl:value-of select="count(preceding::author)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>author_</xsl:text><xsl:value-of select="count(preceding::author)"/> + </xsl:attribute> + </xsl:element> + <!--<xsl:element name="text:s"/>--> + <xsl:element name="text:line-break"/> +</xsl:template> + +<xsl:template match="author/affiliation"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>affiliation_</xsl:text><xsl:value-of select="count(preceding::author/affiliation)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>affiliation_</xsl:text><xsl:value-of select="count(preceding::author/affiliation)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + +<xsl:template match="author/affiliation/address"> + <xsl:element name="text:s"/> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>address_</xsl:text><xsl:value-of select="count(preceding::author/affiliation/address)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>address_</xsl:text><xsl:value-of select="count(preceding::author/affiliation/address)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> +</xsl:template> + + +<xsl:template match="email[ancestor::articleinfo]"> + <xsl:element name="text:s"/> + + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>email_</xsl:text><xsl:value-of select="count(preceding::email[ancestor::articleinfo])"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>email_</xsl:text><xsl:value-of select="count(preceding::email[ancestor::articleinfo])"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + +</xsl:template> + +<xsl:template match="author/affiliation/orgname"> + <xsl:element name="text:s"/> + + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>orgname_</xsl:text><xsl:value-of select="count(preceding::author/affiliation/orgname)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>orgname_</xsl:text><xsl:value-of select="count(preceding::author/affiliation/orgname)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + +</xsl:template> + + +<xsl:template match="author/surname"> + <xsl:element name="text:s"/> + + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>surname_</xsl:text><xsl:value-of select="count(preceding::author/surname)"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>surname_</xsl:text><xsl:value-of select="count(preceding::author/surname)"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="text:s"/> + + +</xsl:template> + + + + <xsl:template match="para"> + <xsl:choose> + <xsl:when test="ancestor::varlistentry"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">VarList Term</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:element name="text:p"> + <xsl:choose> + <xsl:when test="ancestor-or-self::footnote"> + <xsl:attribute name="text:style-name"> + <xsl:text>Footnote</xsl:text> + </xsl:attribute> + </xsl:when> + <xsl:when test="ancestor-or-self::informaltable"> + <xsl:if test="ancestor-or-self::informaltable"> + <xsl:attribute name="text:style-name">Table Contents</xsl:attribute> + </xsl:if> + <xsl:if test="ancestor-or-self::thead "> + <xsl:attribute name="text:style-name">Table Heading</xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:when test="ancestor-or-self::table"> + <xsl:if test="ancestor-or-self::table"> + <xsl:attribute name="text:style-name">Table Contents</xsl:attribute> + </xsl:if> + <xsl:if test="ancestor-or-self::thead "> + <xsl:attribute name="text:style-name">Table Heading</xsl:attribute> + </xsl:if> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="text:style-name">Text body</xsl:attribute> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="@id"> + <xsl:call-template name="test.id"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="section"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level"> + <xsl:value-of select="count(ancestor-or-self::section) "/> + </xsl:attribute> + <xsl:value-of select="child::title"/> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="abstract"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level">1</xsl:attribute> + <xsl:text>abstract</xsl:text> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="appendix"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level">1</xsl:attribute> + <xsl:text>appendix</xsl:text> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="sect1"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level">1</xsl:attribute> + <xsl:choose> + <xsl:when test="@id"> + <xsl:call-template name="test.id"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="child::title"/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="sect2"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level">2</xsl:attribute> + <xsl:choose> + <xsl:when test="@id"> + <xsl:call-template name="test.id"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="child::title"/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="sect3"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level">3</xsl:attribute> + <xsl:choose> + <xsl:when test="@id"> + <xsl:call-template name="test.id"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="child::title"/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="sect4"> + <xsl:element name="text:h"> + <xsl:attribute name="text:level">4</xsl:attribute> + <xsl:choose> + <xsl:when test="@id"> + <xsl:call-template name="test.id"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="child::title"/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + <xsl:apply-templates/> + </xsl:template> + <!--<xsl:template match="sect5"> + <xsl:element name="text:section"> + <xsl:attribute name="text:style-name">Sect1</xsl:attribute> + <xsl:attribute name="text:name"><xsl:value-of select="@id"/></xsl:attribute> + <xsl:apply-templates/> + </xsl:element> +</xsl:template>--> + + <xsl:template match="informaltable"> + <xsl:element name="table:table"> + <xsl:attribute name="table:name"/> + <xsl:attribute name="table:style-name">Table1</xsl:attribute> + <xsl:attribute name="table:name"> + <xsl:value-of select="@id"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + <xsl:template match="indexterm"/> + + + <xsl:template match="figure"> + <xsl:apply-templates/> + </xsl:template> + <!-- lists Section --> + + <xsl:template match="itemizedlist"> + <xsl:element name="text:unordered-list"> + <xsl:attribute name="text:style-name">UnOrdered List</xsl:attribute> + <xsl:attribute name="text:continue-numbering">false</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="variablelist"> + <xsl:element name="text:unordered-list"> + <xsl:attribute name="text:style-name">Var List</xsl:attribute> + <xsl:attribute name="text:continue-numbering">false</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="orderedlist"> + <xsl:element name="text:ordered-list"> + <xsl:attribute name="text:style-name">Ordered List</xsl:attribute> + <xsl:attribute name="text:continue-numbering">false</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="term"> + <xsl:if test="parent::varlistentry"> + <text:list-item> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">VarList Term</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </text:list-item> + </xsl:if> + </xsl:template> + + + <xsl:template match="listitem"> + <xsl:choose> + <xsl:when test="parent::varlistentry"> + <text:list-item> + <xsl:apply-templates/> + </text:list-item> + </xsl:when> + <xsl:otherwise> + <text:list-item> + <xsl:apply-templates/> + </text:list-item> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + <!-- end of lists--> + + <xsl:template match="menuchoice"> + <xsl:variable name="pos"><xsl:value-of select="count(preceding::menuchoice)"/></xsl:variable> + <xsl:element name="text:bookmark-start"> + <xsl:attribute name="text:name"> + <xsl:text>menuchoice_</xsl:text><xsl:value-of select="$pos"/> + </xsl:attribute> + </xsl:element> + <xsl:apply-templates/> + <xsl:element name="text:bookmark-end"> + <xsl:attribute name="text:name"> + <xsl:text>menuchoice_</xsl:text><xsl:value-of select="$pos"/> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template match="guimenuitem"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiMenuItem</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="guibutton"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiButton</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="guisubmenu"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiSubMenu</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + +<!-- Change Made By Kevin Fowlks (fowlks@msu.edu) June 4th, 2003 --> + <xsl:template match="emphasis"> + <xsl:element name="text:span"> + <xsl:choose> + <xsl:when test="@role"> + <xsl:attribute name="text:style-name">Emphasis Bold</xsl:attribute> + <xsl:apply-templates/> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="text:style-name">Emphasis</xsl:attribute> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </xsl:element> + </xsl:template> + +<!-- Change Made By Kevin Fowlks (fowlks@msu.edu) June 16th, 2003 --> + <xsl:template match="quote"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">Citation</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + <xsl:template match="guimenu"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiMenu</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="guisubmenu"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiSubMenu</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="guilabel"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiLabel</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="guibutton"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">GuiButton</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="keycap"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">KeyCap</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="keysym"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">KeySym</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="keycombo"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">KeyCombo</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="command"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">Command</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="application"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">Application</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="filename"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">FileName</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="systemitem"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">SystemItem</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="computeroutput"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name">ComputerOutput</xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="inlinegraphic"> + <xsl:element name="draw:image"> + <xsl:attribute name="draw:style-name"> + <xsl:text>fr1</xsl:text> + </xsl:attribute> + <xsl:attribute name="draw:name"/> + <xsl:attribute name="text:anchor-type"/> + <xsl:attribute name="draw:z-index"/> + <xsl:attribute name="xlink:href"> + <xsl:value-of select="@fileref"/> + </xsl:attribute> + <xsl:attribute name="xlink:type"/> + <xsl:attribute name="svg:width"> + <!--<xsl:value-of select="@width"/>--> + + <xsl:text>1cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="svg:height"> + <xsl:text>1cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:show"> + <xsl:text>embed</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:actuate"> + <xsl:text>onLoad</xsl:text> + </xsl:attribute> + <xsl:attribute name="draw:filter-name"> + <xsl:text disable-output-escaping="yes"><All formats></xsl:text> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template match="footnote"> + <xsl:element name="text:footnote"> + <!--<xsl:element name="text:footnote-citation">Aidan</xsl:element>--> + + <xsl:element name="text:footnote-body"> + <xsl:apply-templates/> + </xsl:element> + </xsl:element> + </xsl:template> + + + <xsl:template match="highlight"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name"> + <xsl:text>Highlight</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="ulink"> + <xsl:element name="text:a"> + <xsl:attribute name="xlink:type"> + <xsl:text>simple</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:href"> + <xsl:value-of select="@url"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="link"> + <xsl:element name="text:a"> + <xsl:attribute name="xlink:type"> + <xsl:text>simple</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:href"> + <xsl:text>#</xsl:text> + <xsl:value-of select="@linkend"/> + <xsl:text>%7Cregion</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="olink"> + <xsl:element name="text:a"> + <xsl:attribute name="xlink:type"> + <xsl:text>simple</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:href"> + <xsl:value-of select="@targetdocent"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + <!-- xref maps to reference-ref i.e an OOo insert reference + xref is an empty element, reference-ref spans the object to be referenced --> + <xsl:template match="xref"> + <xsl:element name="text:reference-ref"> + <xsl:attribute name="text:reference-format"> + <xsl:text>text</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:ref-name"> + <xsl:value-of select="@linkend"/> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <!-- the DocBook elements that have been "xreffed" contain an ID attribute that is linked to by an xref @linkend or @endterm --> + <!-- the @id can also be pointed to by an indexterm --> + + <xsl:template name="test.id"> + <xsl:if test="@id"> + <xsl:variable name="id.val"> + <xsl:value-of select="@id"/> + </xsl:variable> + + <xsl:element name="text:reference-mark-start"> + <xsl:attribute name="text:name"> + <xsl:value-of select="@id"/> + </xsl:attribute> + </xsl:element> + + <xsl:choose> + <xsl:when test="self::para"> + <xsl:apply-templates/> + </xsl:when> + <xsl:otherwise> + <!-- sect* --> + <xsl:value-of select="child::title"/> + </xsl:otherwise> + </xsl:choose> + + <xsl:element name="text:reference-mark-end"> + <xsl:attribute name="text:name"> + <xsl:value-of select="@id"/> + </xsl:attribute> + </xsl:element> + + </xsl:if> + </xsl:template> + + + <xsl:template match="indexterm"> + <xsl:if test="@class = 'startofrange'"> + <xsl:element name="text:alphabetical-index-mark-start"> + <xsl:attribute name="text:id"> + <xsl:value-of select="@id"/> + </xsl:attribute> + <!--<xsl:if test="primary">--> + + <xsl:attribute name="text:key1"> + <xsl:value-of select="primary"/> + </xsl:attribute> + <!--</xsl:if>--> + + <xsl:if test="secondary">--> + <xsl:attribute name="text:key2"> + <xsl:value-of select="secondary"/> + </xsl:attribute> + </xsl:if> + </xsl:element> + </xsl:if> + <xsl:if test="@class = 'endofrange'"> + <xsl:element name="text:alphabetical-index-mark-end"> + <xsl:attribute name="text:id"> + <xsl:value-of select="@startref"/> + </xsl:attribute> + </xsl:element> + </xsl:if> + </xsl:template> + + + <xsl:template match="index"> + <xsl:element name="text:alphabetical-index"> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Sect1</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:protected"> + <xsl:text disable-output-escaping="yes">true</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:value-of select="title"/> + </xsl:attribute> + <xsl:element name="text:alphabetical-index-source"> + <xsl:attribute name="text:main-entry-style-name"> + <xsl:text disable-output-escaping="yes">Main index entry</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:sort-algorithm"> + <xsl:text disable-output-escaping="yes">alphanumeric</xsl:text> + </xsl:attribute> + <xsl:attribute name="fo:language"> + <xsl:text disable-output-escaping="yes">en</xsl:text> + </xsl:attribute> + <xsl:attribute name="fo:country"> + <xsl:text disable-output-escaping="yes">IE</xsl:text> + </xsl:attribute> + <xsl:element name="text:index-title-template"> + <xsl:attribute name="text:style-name">Index Heading</xsl:attribute> + <xsl:value-of select="title"/> + </xsl:element> + <xsl:element name="text:alphabetical-index-entry-template"> + <xsl:attribute name="text:outline-level"> + <xsl:text disable-output-escaping="yes">separator</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index Separator</xsl:text> + </xsl:attribute> + <xsl:element name="text:index-entry-text"/> + </xsl:element> + <xsl:element name="text:alphabetical-index-entry-template"> + <xsl:attribute name="text:outline-level"> + <xsl:text disable-output-escaping="yes">1</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index 1</xsl:text> + </xsl:attribute> + <xsl:element name="text:index-entry-text"/> + <xsl:element name="text:index-entry-tab-stop"> + <xsl:attribute name="style:type"> + <xsl:text disable-output-escaping="yes">left</xsl:text> + </xsl:attribute> + <xsl:attribute name="style:position"> + <xsl:text disable-output-escaping="yes">0cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="style:leader-char"> + <xsl:text disable-output-escaping="yes"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + <xsl:element name="text:alphabetical-index-entry-template"> + <xsl:attribute name="text:outline-level"> + <xsl:text disable-output-escaping="yes">2</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index 2</xsl:text> + </xsl:attribute> + <xsl:element name="text:index-entry-text"/> + <xsl:element name="text:index-entry-tab-stop"> + <xsl:attribute name="style:type"> + <xsl:text disable-output-escaping="yes">left</xsl:text> + </xsl:attribute> + <xsl:attribute name="style:position"> + <xsl:text disable-output-escaping="yes">0cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="style:leader-char"> + <xsl:text disable-output-escaping="yes"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + <xsl:element name="text:alphabetical-index-entry-template"> + <xsl:attribute name="text:outline-level"> + <xsl:text disable-output-escaping="yes">3</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index 3</xsl:text> + </xsl:attribute> + <xsl:element name="text:index-entry-text"/> + <xsl:element name="text:index-entry-tab-stop"> + <xsl:attribute name="style:type"> + <xsl:text disable-output-escaping="yes">left</xsl:text> + </xsl:attribute> + <xsl:attribute name="style:position"> + <xsl:text disable-output-escaping="yes">0cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="style:leader-char"> + <xsl:text disable-output-escaping="yes"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + </xsl:element> + + <xsl:element name="text:index-body"> + <xsl:element name="text:index-title"> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Sect1</xsl:text> + </xsl:attribute> + <xsl:attribute name="text:name"> + <xsl:text disable-output-escaping="yes">Alphabetical Index1_Head</xsl:text> + </xsl:attribute> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index Heading</xsl:text> + </xsl:attribute> + <xsl:value-of select="title"/> + </xsl:element> + </xsl:element> + <xsl:apply-templates select="indexentry"/> + </xsl:element> + </xsl:element> + </xsl:template> + + + <xsl:template match="indexentry"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index 1</xsl:text> + </xsl:attribute> + <xsl:value-of select="primaryie"/> + <xsl:element name="text:tab-stop"/> + </xsl:element> + <xsl:if test="secondaryie"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name"> + <xsl:text disable-output-escaping="yes">Index 2</xsl:text> + </xsl:attribute> + <xsl:value-of select="secondaryie"/> + <xsl:element name="text:tab-stop"/> + </xsl:element> + </xsl:if> + </xsl:template> + + + <xsl:template match="note"> + <office:annotation> + <text:p> + <xsl:apply-templates/> + </text:p> + </office:annotation> + </xsl:template> + + + <xsl:template match="imageobject"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="textobject"/> + + + <xsl:template match="caption"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="imagedata"> + <xsl:element name="draw:image"> + <xsl:attribute name="draw:style-name"> + <xsl:text>fr1</xsl:text> + </xsl:attribute> + <xsl:attribute name="draw:name"/> + <xsl:attribute name="text:anchor-type"/> + <xsl:attribute name="draw:z-index"/> + <xsl:attribute name="xlink:href"> + <xsl:value-of select="@fileref"/> + </xsl:attribute> + <xsl:attribute name="xlink:type"/> + <xsl:attribute name="svg:width"> + <!--<xsl:value-of select="@width"/>--> + + <xsl:text>1cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="svg:height"> + <xsl:text>1cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:show"> + <xsl:text>embed</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:actuate"> + <xsl:text>onLoad</xsl:text> + </xsl:attribute> + <xsl:attribute name="draw:filter-name"> + <xsl:text disable-output-escaping="yes"><All formats></xsl:text> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template match="audioobject"> + <xsl:element name="draw:plugin"> + <xsl:attribute name="draw:style-name"> + <xsl:text>fr1</xsl:text> + </xsl:attribute> + <xsl:attribute name="draw:name"/> + <xsl:attribute name="text:anchor-type"/> + <xsl:attribute name="draw:z-index"/> + <xsl:attribute name="xlink:href"> + <xsl:value-of select="@fileref"/> + </xsl:attribute> + <xsl:attribute name="xlink:type"/> + <xsl:attribute name="svg:width"> + <!--<xsl:value-of select="@width"/>--> + + <xsl:text>1cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="svg:height"> + <xsl:text>1cm</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:show"> + <xsl:text>embed</xsl:text> + </xsl:attribute> + <xsl:attribute name="xlink:actuate"> + <xsl:text>onLoad</xsl:text> + </xsl:attribute> + <xsl:attribute name="draw:filter-name"> + <xsl:text disable-output-escaping="yes"><All formats></xsl:text> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template match="remark"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="mediaobject"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name"> + <xsl:text>Mediaobject</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="superscript"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name"> + <xsl:text>SuperScript</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="subscript"> + <xsl:element name="text:span"> + <xsl:attribute name="text:style-name"> + <xsl:text>SubScript</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="comment()"> + <xsl:element name="text:p"> + <xsl:attribute name="text:style-name">XMLComment</xsl:attribute> + <xsl:value-of select="."/> + </xsl:element> + </xsl:template> +</xsl:stylesheet> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/literallayout.java b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/literallayout.java new file mode 100644 index 000000000000..0559a77418c5 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/literallayout.java @@ -0,0 +1,138 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: literallayout.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package org.openoffice.xmerge.converter.xml.xslt.docbook; +import java.lang.String; + + +public class literallayout{ + + public static String RemoveSpaces(String test){ + System.out.println("\nWorking... Length=" +test.length()); + int i=0; + int paraBreak=10000; + String result=""; + char data[]={10}; + char tab[]={13}; + if(test!=null){ + String strArr[]= test.split(new String(data)); + test=""; + + while (i< strArr.length ){ + //System.out.println("Trying "+ i); + + if (test.length()+strArr[i].length()> paraBreak){ + test=test.concat("</text:p><text:p text:style-name=\"Preformatted Text\" text:name=\"Preformatted Text\">"); + paraBreak+=10000; + } + strArr[i]=needsMask(strArr[i]).concat("<text:line-break/>"); + strArr[i]=needsSecondMask(strArr[i]); + test=test.concat(strArr[i]); + i++; + } + + System.out.println(test.length()); + + } + else{ + test=""; + } + System.out.println("\nDone"); + return test; + } + + public static String needsMask(String origString){ + if (origString.indexOf("&")!=-1){ + origString=replaceStr(origString,"&","&"); + } + if (origString.indexOf("\"")!=-1){ + origString=replaceStr(origString,"\"","""); + } + if (origString.indexOf("<")!=-1){ + origString=replaceStr(origString,"<","<"); + } + if (origString.indexOf(">")!=-1){ + origString=replaceStr(origString,">",">"); + } + return origString; + + } + + public static String needsSecondMask(String origString){ + char data[]={10}; + char tab[]={9}; + if (origString.indexOf(" ")!=-1){ + origString=replaceStr(origString," "," <text:s/>"); + } + if (origString.indexOf(new String(tab))!=-1){ + origString=replaceStr(origString,new String(tab),"<text:tab-stop/>"); + } + + return origString; + + } + + public static String replaceStr(String origString, String origChar, String replaceChar){ + String tmp=""; + int index=origString.indexOf(origChar); + if(index !=-1){ + while (index !=-1){ + String first =origString.substring(0,index); + first=first.concat(replaceChar); + tmp=tmp.concat(first); + origString=origString.substring(index+1,origString.length()); + index=origString.indexOf(origChar); + if(index==-1) { + tmp=tmp.concat(origString); + } + + } + + } + return tmp; + } + + + private static String replace(String test){ + int i=0; + String result=""; + if (test.indexOf(" ",i)!=-1){ + while (test.indexOf(" ",i)!=-1){ + result=result.concat(test.substring(0,test.indexOf(" ",i))); + result=result.concat(" <text:s/>"); + i=test.indexOf(" ",i)+2; + } + return result; + } + else{ + return test; + } + } + +} diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/sofftodocbookheadings_article.xsl b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/sofftodocbookheadings_article.xsl new file mode 100644 index 000000000000..a3dd877706fb --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/sofftodocbookheadings_article.xsl @@ -0,0 +1,852 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: sofftodocbookheadings_article.xsl,v $ + + $Revision: 1.6 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<xsl:stylesheet version="1.0" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:office="http://openoffice.org/2000/office" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="http://openoffice.org/2000/meta" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" xmlns:config="http://openoffice.org/2001/config" office:class="text" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="office meta table number dc fo xlink chart math script xsl draw svg dr3d form config text style"> + + <xsl:key name='headchildren' match="text:p | text:alphabetical-index | table:table | text:span | text:ordered-list | office:annotation | text:unordered-list | text:footnote | text:a | text:list-item | draw:plugin | draw:text-box | text:footnote-body | text:section" + use="generate-id((..|preceding-sibling::text:h[@text:level='1']|preceding-sibling::text:h[@text:level='2']|preceding-sibling::text:h[@text:level='3']|preceding-sibling::text:h[@text:level='4']|preceding-sibling::text:h[@text:level='5'])[last()])"/> + + <xsl:key name="children" match="text:h[@text:level='2']" + use="generate-id(preceding-sibling::text:h[@text:level='1'][1])"/> + + <xsl:key name="children" match="text:h[@text:level='3']" + use="generate-id(preceding-sibling::text:h[@text:level='2' or @text:level='1'][1])"/> + + <xsl:key name="children" match="text:h[@text:level='4']" + use="generate-id(preceding-sibling::text:h[@text:level='3' or @text:level='2' or @text:level='1'][1])"/> + + <xsl:key name="children" match="text:h[@text:level='5']" + use="generate-id(preceding-sibling::text:h[@text:level='4' or @text:level='3' or @text:level='2' or @text:level='1'][1])"/> + + <xsl:key name="secondary_children" match="text:p[@text:style-name = 'Index 2']" + use="generate-id(preceding-sibling::text:p[@text:style-name = 'Index 1'][1])"/> + +<!-- --> + <xsl:template match="/office:document"> + <xsl:text disable-output-escaping="yes"><!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ + </xsl:text> + <xsl:for-each select="descendant::text:variable-decl"> + <xsl:variable name="name"><xsl:value-of select="@text:name"/></xsl:variable> + <xsl:if test="contains(@text:name,'entitydecl')"> + <xsl:text disable-output-escaping="yes"><!ENTITY </xsl:text><xsl:value-of select="substring-after(@text:name,'entitydecl_')"/><xsl:text> "</xsl:text><xsl:value-of select="/descendant::text:variable-set[@text:name= $name][1]"/><xsl:text disable-output-escaping="yes">"></xsl:text> + </xsl:if> + </xsl:for-each> + + <xsl:text disable-output-escaping="yes">]></xsl:text> + <article> + <xsl:attribute name="lang"> + <xsl:value-of select="/office:document/office:meta/dc:language"/> + </xsl:attribute> + <xsl:apply-templates/> + </article> + </xsl:template> + + + <xsl:template match="text:section"> + <xsl:choose> + <xsl:when test="@text:name='ArticleInfo'"> + <articleinfo> + <xsl:apply-templates/> + </articleinfo> + </xsl:when> + <xsl:when test="@text:name='Abstract'"> + <abstract> + <xsl:apply-templates/> + </abstract> + </xsl:when> + <xsl:when test="@text:name='Appendix'"> + <appendix> + <xsl:apply-templates/> + </appendix> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="sectvar"><xsl:text>sect</xsl:text><xsl:value-of select="count(ancestor::text:section)+1"/></xsl:variable> + <xsl:variable name="idvar"><xsl:text> id="</xsl:text><xsl:value-of select="@text:name"/><xsl:text>"</xsl:text></xsl:variable> + <xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="$sectvar"/><xsl:value-of select="$idvar"/><xsl:text disable-output-escaping="yes">></xsl:text> + <xsl:apply-templates/> + <xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="$sectvar"/><xsl:text disable-output-escaping="yes">></xsl:text> + </xsl:otherwise> +</xsl:choose> + + </xsl:template> + + <xsl:template match="text:h[@text:level='1']"> + <xsl:choose> + <xsl:when test=".='Abstract'"> + <abstract> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="key('children', generate-id())"/> + </abstract> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="make-section"> + <xsl:with-param name="current" select="@text:level"/> + <xsl:with-param name="prev" select="1"/> + </xsl:call-template> + <!--<sect1> + <title> + <xsl:apply-templates/> + </title> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="key('children', generate-id())"/> + </sect1>--> + + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:h[@text:level='2'] | text:h[@text:level='3']| text:h[@text:level='4'] | text:h[@text:level='5']"> + <xsl:variable name="level" select="@text:level"/> + <xsl:call-template name="make-section"> + <xsl:with-param name="current" select="$level"/> + <xsl:with-param name="prev" select="preceding-sibling::text:h[@text:level < $level][1]/@text:level "/> + </xsl:call-template> + </xsl:template> + + + <xsl:template name="make-section"> + <xsl:param name="current"/> + <xsl:param name="prev"/> + <xsl:choose> + <xsl:when test="$current > $prev+1"> + <xsl:variable name="sect.element"> + <xsl:text disable-output-escaping="yes">sect</xsl:text> + <xsl:value-of select="$prev +1"/> + </xsl:variable> + <!--<xsl:text disable-output-escaping="yes"><sect</xsl:text><xsl:value-of select="$prev +1"/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + <xsl:element name="{$sect.element}"> + <xsl:call-template name="id.attribute"/> + <title/> + <xsl:call-template name="make-section"> + <xsl:with-param name="current" select="$current"/> + <xsl:with-param name="prev" select="$prev +1"/> + </xsl:call-template> + <!--<xsl:text disable-output-escaping="yes"></sect</xsl:text><xsl:value-of select="$prev +1 "/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="sect.element"> + <xsl:text disable-output-escaping="yes">sect</xsl:text> + <xsl:value-of select="$current"/> + </xsl:variable> + <!--<xsl:text disable-output-escaping="yes"><sect</xsl:text><xsl:value-of select="$current"/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + <xsl:element name="{$sect.element}"> + <xsl:call-template name="id.attribute"/> + <title> + <xsl:apply-templates/> + </title> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="key('children', generate-id())"/> + <!--<xsl:text disable-output-escaping="yes"></sect</xsl:text><xsl:value-of select="$current"/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template match="text:variable-set|text:variable-get"> + <xsl:choose> + <xsl:when test="contains(@text:name,'entitydecl')"> + <xsl:text disable-output-escaping="yes">&</xsl:text><xsl:value-of select="substring-after(@text:name,'entitydecl_')"/><xsl:text disable-output-escaping="yes">;</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='XMLComment']"> + <xsl:comment> + <xsl:value-of select="."/> + </xsl:comment> + </xsl:template> + + <xsl:template match="text:section[@text:name = 'ArticleInfo']/text:p[not(@text:style-name='XMLComment')]"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="text:p"> + <!--text:span text:style-name="XrefLabel" --> + <!--<xsl:if test="not( child::text:span[@text:style-name = 'XrefLabel'] )"> --> + + <xsl:element name="para"> + <xsl:if test="child::text:reference-mark-start"> + <xsl:value-of select="."/> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + <!-- </xsl:if> --> + + </xsl:template> + + + <xsl:template match="office:meta"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="text:ordered-list"> + <orderedlist> + <xsl:apply-templates/> + </orderedlist> + </xsl:template> + + <xsl:template match="meta:editing-cycles"/> + + <xsl:template match="meta:user-defined"/> + + <xsl:template match="meta:editing-duration"/> + + <xsl:template match="dc:language"/> + + <xsl:template match="dc:date"> + <!--<pubdate> + <xsl:value-of select="substring-before(.,'T')"/> + </pubdate>--> + </xsl:template> + + <xsl:template match="meta:creation-date"/> + + <xsl:template match="office:body"> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="text:h[@text:level='1']"/> + <!--<xsl:apply-templates/>--> + </xsl:template> + + <xsl:template match="office:styles"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="office:script"/> + + <xsl:template match="office:settings"/> + + <xsl:template match="office:font-decls"/> + + <xsl:template match="text:bookmark-start"> + <xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="substring-before(@text:name,'_')"/><xsl:text disable-output-escaping="yes">></xsl:text><xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="text:bookmark-end"> + <xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="substring-before(@text:name,'_')"/><xsl:text disable-output-escaping="yes">></xsl:text><xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Document Title']"> + <xsl:element name="title"> + <xsl:apply-templates /> + </xsl:element> + </xsl:template> + +<xsl:template match="text:p[@text:style-name='Document SubTitle']"> +</xsl:template> + + <xsl:template match="text:p[@text:style-name='Document SubTitle']"/> + + <xsl:template match="text:p[@text:style-name='Section Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + <xsl:template match="text:p[@text:style-name='Appendix Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='VarList Item']"> + <xsl:if test="not(preceding-sibling::text:p[@text:style-name='VarList Item'])"> + <xsl:text disable-output-escaping="yes"><listitem></xsl:text> + </xsl:if> + <para> + <xsl:apply-templates/> + </para> + <xsl:if test="not(following-sibling::text:p[@text:style-name='VarList Item'])"> + <xsl:text disable-output-escaping="yes"></listitem></xsl:text> + </xsl:if> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='VarList Term']"> + <term> + <xsl:apply-templates/> + </term> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Section1 Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Section2 Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Section3 Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:footnote-citation"/> + + + <xsl:template match="text:p[@text:style-name='Mediaobject']"> + <mediaobject> + <xsl:apply-templates/> + </mediaobject> + </xsl:template> + + + <xsl:template match="office:annotation/text:p"> + <note> + <remark> + <xsl:apply-templates/> + </remark> + </note> + </xsl:template> + <!--<xsl:template match="meta:initial-creator"> + <author> + <xsl:apply-templates /> + </author> + </xsl:template>--> + + <xsl:template match="table:table"> + <xsl:choose> + <xsl:when test="following-sibling::text:p[@text:style-name='Table']"> + <table frame="all"> + <xsl:attribute name="id"> + <xsl:value-of select="@table:name"/> + </xsl:attribute> + <title> + <xsl:value-of select="following-sibling::text:p[@text:style-name='Table']"/> + </title> + <xsl:call-template name="generictable"/> + </table> + </xsl:when> + <xsl:otherwise> + <informaltable frame="all"> + <xsl:call-template name="generictable"/> + </informaltable> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template name="generictable"> + <xsl:variable name="cells" select="count(descendant::table:table-cell)"/> + <xsl:variable name="rows"> + <xsl:value-of select="count(descendant::table:table-row) "/> + </xsl:variable> + <xsl:variable name="cols"> + <xsl:value-of select="$cells div $rows"/> + </xsl:variable> + <xsl:variable name="numcols"> + <xsl:choose> + <xsl:when test="child::table:table-column/@table:number-columns-repeated"> + <xsl:value-of select="number(table:table-column/@table:number-columns-repeated+1)"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$cols"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:element name="tgroup"> + <xsl:attribute name="cols"> + <xsl:value-of select="$numcols"/> + </xsl:attribute> + <xsl:call-template name="colspec"> + <xsl:with-param name="left" select="1"/> + </xsl:call-template> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template name="colspec"> + <xsl:param name="left"/> + <xsl:if test="number($left < ( table:table-column/@table:number-columns-repeated +2) )"> + <xsl:element name="colspec"> + <xsl:attribute name="colnum"> + <xsl:value-of select="$left"/> + </xsl:attribute> + <xsl:attribute name="colname">c + <xsl:value-of select="$left"/> + </xsl:attribute> + </xsl:element> + <xsl:call-template name="colspec"> + <xsl:with-param name="left" select="$left+1"/> + </xsl:call-template> + </xsl:if> + </xsl:template> + + + <xsl:template match="table:table-column"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="table:table-header-rows"> + <thead> + <xsl:apply-templates/> + </thead> + </xsl:template> + + + <xsl:template match="table:table-header-rows/table:table-row"> + <row> + <xsl:apply-templates/> + </row> + </xsl:template> + + + <xsl:template match="table:table/table:table-row"> + <xsl:if test="not(preceding-sibling::table:table-row)"> + <xsl:text disable-output-escaping="yes"><tbody></xsl:text> + </xsl:if> + <row> + <xsl:apply-templates/> + </row> + <xsl:if test="not(following-sibling::table:table-row)"> + <xsl:text disable-output-escaping="yes"></tbody></xsl:text> + </xsl:if> + </xsl:template> + + + <xsl:template match="table:table-cell"> + <xsl:element name="entry"> + <xsl:if test="@table:number-columns-spanned >'1'"> + <xsl:attribute name="namest"> + <xsl:value-of select="concat('c',count(preceding-sibling::table:table-cell[not(@table:number-columns-spanned)]) +sum(preceding-sibling::table:table-cell/@table:number-columns-spanned)+1)"/> + </xsl:attribute> + <xsl:attribute name="nameend"> + <xsl:value-of select="concat('c',count(preceding-sibling::table:table-cell[not(@table:number-columns-spanned)]) +sum(preceding-sibling::table:table-cell/@table:number-columns-spanned)+ @table:number-columns-spanned)"/> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:p"> + <xsl:choose> + <xsl:when test="@text:style-name='Table'"/> + <xsl:otherwise> + <xsl:if test="not( child::text:span[@text:style-name = 'XrefLabel'] )"> + <para> + <xsl:call-template name="id.attribute"/> + <xsl:apply-templates/> + </para> + </xsl:if> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:unordered-list"> + <xsl:choose> + <xsl:when test="@text:style-name='Var List'"> + <variablelist> + <xsl:apply-templates/> + </variablelist> + </xsl:when> + <xsl:when test="@text:style-name='UnOrdered List'"> + <variablelist> + <xsl:apply-templates/> + </variablelist> + </xsl:when> + <xsl:otherwise> + <itemizedlist> + <title/> + <xsl:apply-templates/> + </itemizedlist> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:list-item"> + <xsl:if test="parent::text:unordered-list/@text:style-name='Var List'"> + <varlistentry> + <xsl:for-each select="text:p[@text:style-name='VarList Term']"> + <xsl:apply-templates select="."/> + </xsl:for-each> + </varlistentry> + </xsl:if> + <xsl:if test="not(parent::text:unordered-list/@text:style-name='Var List')"> + <listitem> + <xsl:apply-templates/> + </listitem> + </xsl:if> + </xsl:template> + + + <xsl:template match="dc:title"/> + + + <xsl:template match="dc:description"> + <abstract> + <para> + <xsl:apply-templates/> + </para> + </abstract> + </xsl:template> + + + <xsl:template match="dc:subject"/> + + <xsl:template match="meta:generator"/> + + <xsl:template match="draw:plugin"> + <xsl:element name="audioobject"> + <xsl:attribute name="fileref"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:attribute name="width"/> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:footnote"> + <footnote> + <xsl:apply-templates/> + </footnote> + </xsl:template> + + + <xsl:template match="text:footnote-body"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="draw:text-box"/> + + <xsl:template match="draw:image"> + <xsl:choose> + <xsl:when test="parent::text:p[@text:style-name='Mediaobject']"> + <xsl:element name="imageobject"> + <xsl:element name="imagedata"> + <xsl:attribute name="fileref"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="caption"> + <xsl:value-of select="."/> + </xsl:element> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:element name="inlinegraphic"> + <xsl:attribute name="fileref"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:attribute name="width"/> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:span"> + <xsl:choose> + <xsl:when test="./@text:style-name='GuiMenu'"> + <xsl:element name="guimenu"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="./@text:style-name='GuiSubMenu'"> + <xsl:element name="guisubmenu"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiMenuItem'"> + <xsl:element name="guimenuitem"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiButton'"> + <xsl:element name="guibutton"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiButton'"> + <xsl:element name="guibutton"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiLabel'"> + <xsl:element name="guilabel"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='Emphasis'"> + <xsl:element name="emphasis"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> +<!-- Change Made By Kevin Fowlks (fowlks@msu.edu) June 4th, 2003 --> + <xsl:when test="@text:style-name='Emphasis Bold'"> + <xsl:element name="emphasis"> + <xsl:attribute name = "role" > + <xsl:text>bold</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> +<!-- Change Made By Kevin Fowlks (fowlks@msu.edu) June 16th, 2003 --> + <xsl:when test="@text:style-name='Citation'"> + <xsl:element name="quote"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='FileName'"> + <xsl:element name="filename"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='Application'"> + <xsl:element name="application"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='Command'"> + <command> + <xsl:apply-templates/> + </command> + </xsl:when> + <xsl:when test="@text:style-name='SubScript'"> + <subscript> + <xsl:apply-templates/> + </subscript> + </xsl:when> + <xsl:when test="@text:style-name='SuperScript'"> + <superscript> + <xsl:apply-templates/> + </superscript> + </xsl:when> + <xsl:when test="@text:style-name='SystemItem'"> + <systemitem> + <xsl:apply-templates/> + </systemitem> + </xsl:when> + <xsl:when test="@text:style-name='ComputerOutput'"> + <computeroutput> + <xsl:apply-templates/> + </computeroutput> + </xsl:when> + <xsl:when test="@text:style-name='Highlight'"> + <highlight> + <xsl:apply-templates/> + </highlight> + </xsl:when> + <xsl:when test="@text:style-name='KeyCap'"> + <keycap> + <xsl:apply-templates/> + </keycap> + </xsl:when> + <xsl:when test="@text:style-name='KeySym'"> + <xsl:element name="keysym"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='KeyCombo'"> + <keycombo> + <xsl:apply-templates/> + </keycombo> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:a"> + <xsl:choose> + <xsl:when test="contains(@xlink:href,'://')"> + <xsl:element name="ulink"> + <xsl:attribute name="url"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="not(contains(@xlink:href,'#'))"> + <xsl:element name="olink"> + <xsl:attribute name="targetdocent"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="linkvar" select="substring-after(@xlink:href,'#')"/> + <xsl:element name="link"> + <xsl:attribute name="linkend"> + <xsl:value-of select="substring-before($linkvar,'%')"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:line-break"> + <xsl:text disable-output-escaping="yes"/> + </xsl:template> + + + <xsl:template match="text:tab-stop"> + <xsl:text disable-output-escaping="yes"/> + </xsl:template> + <!-- @endterm not retained due to problems with OOo method of displaying text in the reference-ref --> + + <xsl:template match="text:reference-ref"> + <xsl:element name="xref"> + <xsl:attribute name="linkend"> + <xsl:value-of select="@text:ref-name"/> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template name="id.attribute"> + <xsl:if test="child::text:reference-mark-start"> + <xsl:attribute name="id"> + <xsl:value-of select="child::text:reference-mark-start/@text:name"/> + </xsl:attribute> + </xsl:if> + <!-- Constraints imposed by OOo method of displaying reference-ref text means that xreflabel and endterm are lost --> + <!--<xsl:if test="child::text:p/text:span[@text:style-name = 'XrefLabel']"> + <xsl:attribute name="xreflabel"> + <xsl:value-of select="text:p/text:span"/> + </xsl:attribute> + </xsl:if> --> + + </xsl:template> + <!-- + <text:h text:level="1">Part One Title + <text:reference-mark-start text:name="part"/> + <text:p text:style-name="Text body"> + <text:span text:style-name="XrefLabel">xreflabel_part</text:span> + </text:p> + <text:reference-mark-end text:name="part"/> + </text:h> +--> + <!--<xsl:template match="text:p/text:span[@text:style-name = 'XrefLabel']"/>--> + + <xsl:template match="text:reference-mark-start"/> + + <xsl:template match="text:reference-mark-end"/> + + <xsl:template match="comment"> + <xsl:comment> + <xsl:value-of select="."/> + </xsl:comment> + </xsl:template> + + + <xsl:template match="text:alphabetical-index-mark-start"> + <xsl:element name="indexterm"> + <xsl:attribute name="class"> + <xsl:text disable-output-escaping="yes">startofrange</xsl:text> + </xsl:attribute> + <xsl:attribute name="id"> + <xsl:value-of select="@text:id"/> + </xsl:attribute> + <!--<xsl:if test="@text:key1">--> + + <xsl:element name="primary"> + <xsl:value-of select="@text:key1"/> + </xsl:element> + <!--</xsl:if>--> + + <xsl:if test="@text:key2"> + <xsl:element name="secondary"> + <xsl:value-of select="@text:key2"/> + </xsl:element> + </xsl:if> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:alphabetical-index-mark-end"> + <xsl:element name="indexterm"> + <xsl:attribute name="startref"> + <xsl:value-of select="@text:id"/> + </xsl:attribute> + <xsl:attribute name="class"> + <xsl:text disable-output-escaping="yes">endofrange</xsl:text> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:alphabetical-index"> + <xsl:element name="index"> + <xsl:element name="title"> + <xsl:value-of select="text:index-body/text:index-title/text:p"/> + </xsl:element> + <xsl:apply-templates select="text:index-body"/> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:index-body"> + <xsl:for-each select="text:p[@text:style-name = 'Index 1']"> + <xsl:element name="indexentry"> + <xsl:element name="primaryie"> + <xsl:value-of select="."/> + </xsl:element> + <xsl:if test="key('secondary_children', generate-id())"> + <xsl:element name="secondaryie"> + <xsl:value-of select="key('secondary_children', generate-id())"/> + </xsl:element> + </xsl:if> + </xsl:element> + </xsl:for-each> + </xsl:template> + +</xsl:stylesheet> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/sofftodocbookheadings_chapter.xsl b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/sofftodocbookheadings_chapter.xsl new file mode 100644 index 000000000000..5b2cb54347d0 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/docbook/sofftodocbookheadings_chapter.xsl @@ -0,0 +1,862 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: sofftodocbookheadings_chapter.xsl,v $ + + $Revision: 1.6 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> + +<xsl:stylesheet version="1.0" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:office="http://openoffice.org/2000/office" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="http://openoffice.org/2000/meta" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" xmlns:config="http://openoffice.org/2001/config" office:class="text" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="office meta table number dc fo xlink chart math script xsl draw svg dr3d form config text style"> + + <xsl:key name='headchildren' match="text:p | text:alphabetical-index | table:table | text:span | text:ordered-list | office:annotation | text:unordered-list | text:footnote | text:a | text:list-item | draw:plugin | draw:text-box | text:footnote-body | text:section" + use="generate-id((..|preceding-sibling::text:h[@text:level='1']|preceding-sibling::text:h[@text:level='2']|preceding-sibling::text:h[@text:level='3']|preceding-sibling::text:h[@text:level='4']|preceding-sibling::text:h[@text:level='5'])[last()])"/> + + <xsl:key name="children" match="text:h[@text:level='2']" + use="generate-id(preceding-sibling::text:h[@text:level='1'][1])"/> + + <xsl:key name="children" match="text:h[@text:level='3']" + use="generate-id(preceding-sibling::text:h[@text:level='2' or @text:level='1'][1])"/> + + <xsl:key name="children" match="text:h[@text:level='4']" + use="generate-id(preceding-sibling::text:h[@text:level='3' or @text:level='2' or @text:level='1'][1])"/> + + <xsl:key name="children" match="text:h[@text:level='5']" + use="generate-id(preceding-sibling::text:h[@text:level='4' or @text:level='3' or @text:level='2' or @text:level='1'][1])"/> + + <xsl:key name="secondary_children" match="text:p[@text:style-name = 'Index 2']" + use="generate-id(preceding-sibling::text:p[@text:style-name = 'Index 1'][1])"/> + +<!-- --> + <xsl:template match="/office:document"> + <xsl:text disable-output-escaping="yes"><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ + </xsl:text> + <xsl:for-each select="descendant::text:variable-decl"> + <xsl:variable name="name"><xsl:value-of select="@text:name"/></xsl:variable> + <xsl:if test="contains(@text:name,'entitydecl')"> + <xsl:text disable-output-escaping="yes"><!ENTITY </xsl:text><xsl:value-of select="substring-after(@text:name,'entitydecl_')"/><xsl:text> "</xsl:text><xsl:value-of select="/descendant::text:variable-set[@text:name= $name][1]"/><xsl:text disable-output-escaping="yes">"></xsl:text> + </xsl:if> + </xsl:for-each> + + <xsl:text disable-output-escaping="yes">]></xsl:text> + <chapter> + <xsl:attribute name="lang"> + <xsl:value-of select="/office:document/office:meta/dc:language"/> + </xsl:attribute> + <xsl:apply-templates/> + </chapter> + </xsl:template> + + + <xsl:template match="text:section"> + <xsl:choose> + <xsl:when test="@text:name='ChapterInfo'"> + <chapterinfo> + <xsl:apply-templates/> + </chapterinfo> + </xsl:when> + <xsl:when test="@text:name='Abstract'"> + <abstract> + <xsl:apply-templates/> + </abstract> + </xsl:when> + <xsl:when test="@text:name='Appendix'"> + <appendix> + <xsl:apply-templates/> + </appendix> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="sectvar"><xsl:text>sect</xsl:text><xsl:value-of select="count(ancestor::text:section)+1"/></xsl:variable> + <xsl:variable name="idvar"><xsl:text> id="</xsl:text><xsl:value-of select="@text:name"/><xsl:text>"</xsl:text></xsl:variable> + <xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="$sectvar"/><xsl:value-of select="$idvar"/><xsl:text disable-output-escaping="yes">></xsl:text> + <xsl:apply-templates/> + <xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="$sectvar"/><xsl:text disable-output-escaping="yes">></xsl:text> + </xsl:otherwise> +</xsl:choose> + + </xsl:template> + + <xsl:template match="text:h[@text:level='1']"> + <xsl:choose> + <xsl:when test=".='Abstract'"> + <abstract> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="key('children', generate-id())"/> + </abstract> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="make-section"> + <xsl:with-param name="current" select="@text:level"/> + <xsl:with-param name="prev" select="1"/> + </xsl:call-template> + <!--<sect1> + <title> + <xsl:apply-templates/> + </title> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="key('children', generate-id())"/> + </sect1>--> + + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:h[@text:level='2'] | text:h[@text:level='3']| text:h[@text:level='4'] | text:h[@text:level='5']"> + <xsl:variable name="level" select="@text:level"/> + <xsl:call-template name="make-section"> + <xsl:with-param name="current" select="$level"/> + <xsl:with-param name="prev" select="preceding-sibling::text:h[@text:level < $level][1]/@text:level "/> + </xsl:call-template> + </xsl:template> + + + <xsl:template name="make-section"> + <xsl:param name="current"/> + <xsl:param name="prev"/> + <xsl:choose> + <xsl:when test="$current > $prev+1"> + <xsl:variable name="sect.element"> + <xsl:text disable-output-escaping="yes">sect</xsl:text> + <xsl:value-of select="$prev +1"/> + </xsl:variable> + <!--<xsl:text disable-output-escaping="yes"><sect</xsl:text><xsl:value-of select="$prev +1"/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + <xsl:element name="{$sect.element}"> + <xsl:call-template name="id.attribute"/> + <title/> + <xsl:call-template name="make-section"> + <xsl:with-param name="current" select="$current"/> + <xsl:with-param name="prev" select="$prev +1"/> + </xsl:call-template> + <!--<xsl:text disable-output-escaping="yes"></sect</xsl:text><xsl:value-of select="$prev +1 "/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="sect.element"> + <xsl:text disable-output-escaping="yes">sect</xsl:text> + <xsl:value-of select="$current"/> + </xsl:variable> + <!--<xsl:text disable-output-escaping="yes"><sect</xsl:text><xsl:value-of select="$current"/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + <xsl:element name="{$sect.element}"> + <xsl:call-template name="id.attribute"/> + <title> + <xsl:apply-templates/> + </title> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="key('children', generate-id())"/> + <!--<xsl:text disable-output-escaping="yes"></sect</xsl:text><xsl:value-of select="$current"/><xsl:text disable-output-escaping="yes">></xsl:text>--> + + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template match="text:variable-set"> + <xsl:choose> + <xsl:when test="contains(@text:name,'entitydecl')"> + <xsl:text disable-output-escaping="yes">&</xsl:text><xsl:value-of select="substring-after(@text:name,'entitydecl_')"/><xsl:text disable-output-escaping="yes">;</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:template> + + <xsl:template match="text:variable-get"> + <xsl:choose> + <xsl:when test="contains(@text:name,'entitydecl')"> + <xsl:text disable-output-escaping="yes">&</xsl:text><xsl:value-of select="substring-after(@text:name,'entitydecl_')"/><xsl:text disable-output-escaping="yes">;</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:template> + + + + + <xsl:template match="text:p[@text:style-name='XMLComment']"> + <xsl:comment> + <xsl:value-of select="."/> + </xsl:comment> + </xsl:template> + + <xsl:template match="text:section[@text:name = 'ChapterInfo']/text:p[not(@text:style-name='XMLComment')]"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="text:p"> + <!--text:span text:style-name="XrefLabel" --> + <!--<xsl:if test="not( child::text:span[@text:style-name = 'XrefLabel'] )"> --> + + <xsl:element name="para"> + <xsl:if test="child::text:reference-mark-start"> + <xsl:value-of select="."/> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + <!-- </xsl:if> --> + + </xsl:template> + + + <xsl:template match="office:meta"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="text:ordered-list"> + <orderedlist> + <xsl:apply-templates/> + </orderedlist> + </xsl:template> + + <xsl:template match="meta:editing-cycles"/> + + <xsl:template match="meta:user-defined"/> + + <xsl:template match="meta:editing-duration"/> + + <xsl:template match="dc:language"/> + + <xsl:template match="dc:date"> + <!--<pubdate> + <xsl:value-of select="substring-before(.,'T')"/> + </pubdate>--> + </xsl:template> + + <xsl:template match="meta:creation-date"/> + + <xsl:template match="office:body"> + <xsl:apply-templates select="key('headchildren', generate-id())"/> + <xsl:apply-templates select="text:h[@text:level='1']"/> + <!--<xsl:apply-templates/>--> + </xsl:template> + + <xsl:template match="office:styles"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="office:script"/> + + <xsl:template match="office:settings"/> + + <xsl:template match="office:font-decls"/> + + <xsl:template match="text:bookmark-start"> + <xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="substring-before(@text:name,'_')"/><xsl:text disable-output-escaping="yes">></xsl:text><xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="text:bookmark-end"> + <xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="substring-before(@text:name,'_')"/><xsl:text disable-output-escaping="yes">></xsl:text><xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Document Title']"> + <xsl:element name="title"> + <xsl:apply-templates /> + </xsl:element> + </xsl:template> + +<xsl:template match="text:p[@text:style-name='Document SubTitle']"> +</xsl:template> + + <xsl:template match="text:p[@text:style-name='Document SubTitle']"/> + + <xsl:template match="text:p[@text:style-name='Section Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + <xsl:template match="text:p[@text:style-name='Appendix Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='VarList Item']"> + <xsl:if test="not(preceding-sibling::text:p[@text:style-name='VarList Item'])"> + <xsl:text disable-output-escaping="yes"><listitem></xsl:text> + </xsl:if> + <para> + <xsl:apply-templates/> + </para> + <xsl:if test="not(following-sibling::text:p[@text:style-name='VarList Item'])"> + <xsl:text disable-output-escaping="yes"></listitem></xsl:text> + </xsl:if> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='VarList Term']"> + <term> + <xsl:apply-templates/> + </term> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Section1 Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Section2 Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:p[@text:style-name='Section3 Title']"> + <title> + <xsl:apply-templates/> + </title> + </xsl:template> + + + <xsl:template match="text:footnote-citation"/> + + + <xsl:template match="text:p[@text:style-name='Mediaobject']"> + <mediaobject> + <xsl:apply-templates/> + </mediaobject> + </xsl:template> + + + <xsl:template match="office:annotation/text:p"> + <note> + <remark> + <xsl:apply-templates/> + </remark> + </note> + </xsl:template> + <!--<xsl:template match="meta:initial-creator"> + <author> + <xsl:apply-templates /> + </author> + </xsl:template>--> + + <xsl:template match="table:table"> + <xsl:choose> + <xsl:when test="following-sibling::text:p[@text:style-name='Table']"> + <table frame="all"> + <xsl:attribute name="id"> + <xsl:value-of select="@table:name"/> + </xsl:attribute> + <title> + <xsl:value-of select="following-sibling::text:p[@text:style-name='Table']"/> + </title> + <xsl:call-template name="generictable"/> + </table> + </xsl:when> + <xsl:otherwise> + <informaltable frame="all"> + <xsl:call-template name="generictable"/> + </informaltable> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template name="generictable"> + <xsl:variable name="cells" select="count(descendant::table:table-cell)"/> + <xsl:variable name="rows"> + <xsl:value-of select="count(descendant::table:table-row) "/> + </xsl:variable> + <xsl:variable name="cols"> + <xsl:value-of select="$cells div $rows"/> + </xsl:variable> + <xsl:variable name="numcols"> + <xsl:choose> + <xsl:when test="child::table:table-column/@table:number-columns-repeated"> + <xsl:value-of select="number(table:table-column/@table:number-columns-repeated+1)"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$cols"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:element name="tgroup"> + <xsl:attribute name="cols"> + <xsl:value-of select="$numcols"/> + </xsl:attribute> + <xsl:call-template name="colspec"> + <xsl:with-param name="left" select="1"/> + </xsl:call-template> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template name="colspec"> + <xsl:param name="left"/> + <xsl:if test="number($left < ( table:table-column/@table:number-columns-repeated +2) )"> + <xsl:element name="colspec"> + <xsl:attribute name="colnum"> + <xsl:value-of select="$left"/> + </xsl:attribute> + <xsl:attribute name="colname">c + <xsl:value-of select="$left"/> + </xsl:attribute> + </xsl:element> + <xsl:call-template name="colspec"> + <xsl:with-param name="left" select="$left+1"/> + </xsl:call-template> + </xsl:if> + </xsl:template> + + + <xsl:template match="table:table-column"> + <xsl:apply-templates/> + </xsl:template> + + + <xsl:template match="table:table-header-rows"> + <thead> + <xsl:apply-templates/> + </thead> + </xsl:template> + + + <xsl:template match="table:table-header-rows/table:table-row"> + <row> + <xsl:apply-templates/> + </row> + </xsl:template> + + + <xsl:template match="table:table/table:table-row"> + <xsl:if test="not(preceding-sibling::table:table-row)"> + <xsl:text disable-output-escaping="yes"><tbody></xsl:text> + </xsl:if> + <row> + <xsl:apply-templates/> + </row> + <xsl:if test="not(following-sibling::table:table-row)"> + <xsl:text disable-output-escaping="yes"></tbody></xsl:text> + </xsl:if> + </xsl:template> + + + <xsl:template match="table:table-cell"> + <xsl:element name="entry"> + <xsl:if test="@table:number-columns-spanned >'1'"> + <xsl:attribute name="namest"> + <xsl:value-of select="concat('c',count(preceding-sibling::table:table-cell[not(@table:number-columns-spanned)]) +sum(preceding-sibling::table:table-cell/@table:number-columns-spanned)+1)"/> + </xsl:attribute> + <xsl:attribute name="nameend"> + <xsl:value-of select="concat('c',count(preceding-sibling::table:table-cell[not(@table:number-columns-spanned)]) +sum(preceding-sibling::table:table-cell/@table:number-columns-spanned)+ @table:number-columns-spanned)"/> + </xsl:attribute> + </xsl:if> + <xsl:apply-templates/> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:p"> + <xsl:choose> + <xsl:when test="@text:style-name='Table'"/> + <xsl:otherwise> + <xsl:if test="not( child::text:span[@text:style-name = 'XrefLabel'] )"> + <para> + <xsl:call-template name="id.attribute"/> + <xsl:apply-templates/> + </para> + </xsl:if> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:unordered-list"> + <xsl:choose> + <xsl:when test="@text:style-name='Var List'"> + <variablelist> + <xsl:apply-templates/> + </variablelist> + </xsl:when> + <xsl:when test="@text:style-name='UnOrdered List'"> + <variablelist> + <xsl:apply-templates/> + </variablelist> + </xsl:when> + <xsl:otherwise> + <itemizedlist> + <title/> + <xsl:apply-templates/> + </itemizedlist> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:list-item"> + <xsl:if test="parent::text:unordered-list/@text:style-name='Var List'"> + <varlistentry> + <xsl:for-each select="text:p[@text:style-name='VarList Term']"> + <xsl:apply-templates select="."/> + </xsl:for-each> + </varlistentry> + </xsl:if> + <xsl:if test="not(parent::text:unordered-list/@text:style-name='Var List')"> + <listitem> + <xsl:apply-templates/> + </listitem> + </xsl:if> + </xsl:template> + + + <xsl:template match="dc:title"/> + + + <xsl:template match="dc:description"> + <abstract> + <para> + <xsl:apply-templates/> + </para> + </abstract> + </xsl:template> + + + <xsl:template match="dc:subject"/> + + <xsl:template match="meta:generator"/> + + <xsl:template match="draw:plugin"> + <xsl:element name="audioobject"> + <xsl:attribute name="fileref"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:attribute name="width"/> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:footnote"> + <footnote> + <xsl:apply-templates/> + </footnote> + </xsl:template> + + + <xsl:template match="text:footnote-body"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="draw:text-box"/> + + <xsl:template match="draw:image"> + <xsl:choose> + <xsl:when test="parent::text:p[@text:style-name='Mediaobject']"> + <xsl:element name="imageobject"> + <xsl:element name="imagedata"> + <xsl:attribute name="fileref"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + </xsl:element> + <xsl:element name="caption"> + <xsl:value-of select="."/> + </xsl:element> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:element name="inlinegraphic"> + <xsl:attribute name="fileref"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:attribute name="width"/> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:span"> + <xsl:choose> + <xsl:when test="./@text:style-name='GuiMenu'"> + <xsl:element name="guimenu"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="./@text:style-name='GuiSubMenu'"> + <xsl:element name="guisubmenu"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiMenuItem'"> + <xsl:element name="guimenuitem"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiButton'"> + <xsl:element name="guibutton"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiButton'"> + <xsl:element name="guibutton"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='GuiLabel'"> + <xsl:element name="guilabel"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='Emphasis'"> + <xsl:element name="emphasis"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> +<!-- Change Made By Kevin Fowlks (fowlks@msu.edu) June 4th, 2003 --> + <xsl:when test="@text:style-name='Emphasis Bold'"> + <xsl:element name="emphasis"> + <xsl:attribute name = "role" > + <xsl:text >bold</xsl:text> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> +<!-- Change Made By Kevin Fowlks (fowlks@msu.edu) June 16th, 2003 --> + <xsl:when test="@text:style-name='Citation'"> + <xsl:element name="quote"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='FileName'"> + <xsl:element name="filename"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='Application'"> + <xsl:element name="application"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='Command'"> + <command> + <xsl:apply-templates/> + </command> + </xsl:when> + <xsl:when test="@text:style-name='SubScript'"> + <subscript> + <xsl:apply-templates/> + </subscript> + </xsl:when> + <xsl:when test="@text:style-name='SuperScript'"> + <superscript> + <xsl:apply-templates/> + </superscript> + </xsl:when> + <xsl:when test="@text:style-name='SystemItem'"> + <systemitem> + <xsl:apply-templates/> + </systemitem> + </xsl:when> + <xsl:when test="@text:style-name='ComputerOutput'"> + <computeroutput> + <xsl:apply-templates/> + </computeroutput> + </xsl:when> + <xsl:when test="@text:style-name='Highlight'"> + <highlight> + <xsl:apply-templates/> + </highlight> + </xsl:when> + <xsl:when test="@text:style-name='KeyCap'"> + <keycap> + <xsl:apply-templates/> + </keycap> + </xsl:when> + <xsl:when test="@text:style-name='KeySym'"> + <xsl:element name="keysym"> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="@text:style-name='KeyCombo'"> + <keycombo> + <xsl:apply-templates/> + </keycombo> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:a"> + <xsl:choose> + <xsl:when test="contains(@xlink:href,'://')"> + <xsl:element name="ulink"> + <xsl:attribute name="url"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:when test="not(contains(@xlink:href,'#'))"> + <xsl:element name="olink"> + <xsl:attribute name="targetdocent"> + <xsl:value-of select="@xlink:href"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="linkvar" select="substring-after(@xlink:href,'#')"/> + <xsl:element name="link"> + <xsl:attribute name="linkend"> + <xsl:value-of select="substring-before($linkvar,'%')"/> + </xsl:attribute> + <xsl:apply-templates/> + </xsl:element> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + + <xsl:template match="text:line-break"> + <xsl:text disable-output-escaping="yes"/> + </xsl:template> + + + <xsl:template match="text:tab-stop"> + <xsl:text disable-output-escaping="yes"/> + </xsl:template> + <!-- @endterm not retained due to problems with OOo method of displaying text in the reference-ref --> + + <xsl:template match="text:reference-ref"> + <xsl:element name="xref"> + <xsl:attribute name="linkend"> + <xsl:value-of select="@text:ref-name"/> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template name="id.attribute"> + <xsl:if test="child::text:reference-mark-start"> + <xsl:attribute name="id"> + <xsl:value-of select="child::text:reference-mark-start/@text:name"/> + </xsl:attribute> + </xsl:if> + <!-- Constraints imposed by OOo method of displaying reference-ref text means that xreflabel and endterm are lost --> + <!--<xsl:if test="child::text:p/text:span[@text:style-name = 'XrefLabel']"> + <xsl:attribute name="xreflabel"> + <xsl:value-of select="text:p/text:span"/> + </xsl:attribute> + </xsl:if> --> + + </xsl:template> + <!-- + <text:h text:level="1">Part One Title + <text:reference-mark-start text:name="part"/> + <text:p text:style-name="Text body"> + <text:span text:style-name="XrefLabel">xreflabel_part</text:span> + </text:p> + <text:reference-mark-end text:name="part"/> + </text:h> +--> + <!--<xsl:template match="text:p/text:span[@text:style-name = 'XrefLabel']"/>--> + + <xsl:template match="text:reference-mark-start"/> + + <xsl:template match="text:reference-mark-end"/> + + <xsl:template match="comment"> + <xsl:comment> + <xsl:value-of select="."/> + </xsl:comment> + </xsl:template> + + + <xsl:template match="text:alphabetical-index-mark-start"> + <xsl:element name="indexterm"> + <xsl:attribute name="class"> + <xsl:text disable-output-escaping="yes">startofrange</xsl:text> + </xsl:attribute> + <xsl:attribute name="id"> + <xsl:value-of select="@text:id"/> + </xsl:attribute> + <!--<xsl:if test="@text:key1">--> + + <xsl:element name="primary"> + <xsl:value-of select="@text:key1"/> + </xsl:element> + <!--</xsl:if>--> + + <xsl:if test="@text:key2"> + <xsl:element name="secondary"> + <xsl:value-of select="@text:key2"/> + </xsl:element> + </xsl:if> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:alphabetical-index-mark-end"> + <xsl:element name="indexterm"> + <xsl:attribute name="startref"> + <xsl:value-of select="@text:id"/> + </xsl:attribute> + <xsl:attribute name="class"> + <xsl:text disable-output-escaping="yes">endofrange</xsl:text> + </xsl:attribute> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:alphabetical-index"> + <xsl:element name="index"> + <xsl:element name="title"> + <xsl:value-of select="text:index-body/text:index-title/text:p"/> + </xsl:element> + <xsl:apply-templates select="text:index-body"/> + </xsl:element> + </xsl:template> + + + <xsl:template match="text:index-body"> + <xsl:for-each select="text:p[@text:style-name = 'Index 1']"> + <xsl:element name="indexentry"> + <xsl:element name="primaryie"> + <xsl:value-of select="."/> + </xsl:element> + <xsl:if test="key('secondary_children', generate-id())"> + <xsl:element name="secondaryie"> + <xsl:value-of select="key('secondary_children', generate-id())"/> + </xsl:element> + </xsl:if> + </xsl:element> + </xsl:for-each> + </xsl:template> + +</xsl:stylesheet> + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/htmltosoff.xsl b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/htmltosoff.xsl new file mode 100644 index 000000000000..3181681af6e9 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/htmltosoff.xsl @@ -0,0 +1,178 @@ +<?xml version='1.0' encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: htmltosoff.xsl,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:office="http://openoffice.org/2000/office" + xmlns:style="http://openoffice.org/2000/style" + xmlns:text="http://openoffice.org/2000/text" + xmlns:table="http://openoffice.org/2000/table" + xmlns:draw="http://openoffice.org/2000/drawing" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:number="http://openoffice.org/2000/datastyle" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:chart="http://openoffice.org/2000/chart" + xmlns:dr3d="http://openoffice.org/2000/dr3d" + xmlns:math="http://www.w3.org/1998/Math/MathML" + xmlns:form="http://openoffice.org/2000/form" + xmlns:script="http://openoffice.org/2000/script" + > +<xsl:output method="xml" /> + + +<xsl:template match="/"> + <xsl:apply-templates /> +</xsl:template> + +<xsl:template match="html"> + + <office:document-content xmlns:office="http://openoffice.org/2000/office" + xmlns:style="http://openoffice.org/2000/style" + xmlns:text="http://openoffice.org/2000/text" + xmlns:table="http://openoffice.org/2000/table" + xmlns:draw="http://openoffice.org/2000/drawing" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:number="http://openoffice.org/2000/datastyle" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:chart="http://openoffice.org/2000/chart" + xmlns:dr3d="http://openoffice.org/2000/dr3d" + xmlns:math="http://www.w3.org/1998/Math/MathML" + xmlns:form="http://openoffice.org/2000/form" + xmlns:script="http://openoffice.org/2000/script" + office:class="text" office:version="1.0"> + +<office:script/> + <office:font-decls> + <style:font-decl style:name="Letter Gothic" fo:font-family="'Letter Gothic'" style:font-family-generic="modern" style:font-pitch="fixed"/> + <style:font-decl style:name="Arial Unicode MS" fo:font-family="'Arial Unicode MS'" style:font-pitch="variable"/> + <style:font-decl style:name="HG Mincho Light J" fo:font-family="'HG Mincho Light J'" style:font-pitch="variable"/> + <style:font-decl style:name="CG Times" fo:font-family="'CG Times'" style:font-family-generic="roman" style:font-pitch="variable"/> + <style:font-decl style:name="Thorndale" fo:font-family="Thorndale" style:font-family-generic="roman" style:font-pitch="variable"/> + <style:font-decl style:name="Antique Olive" fo:font-family="'Antique Olive'" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-decl style:name="Arial Black" fo:font-family="'Arial Black'" style:font-family-generic="swiss" style:font-pitch="variable"/> + </office:font-decls> + <office:automatic-styles> + <style:style style:name="Table1" style:family="table"> + <style:properties style:width="16.999cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:properties style:column-width="3.399cm" style:rel-column-width="13107*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border-left="0.002cm solid #000000" fo:border-right="none" fo:border-top="0.002cm solid #000000" fo:border-bottom="0.002cm solid #000000"/> + </style:style> + <style:style style:name="Table1.E1" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border="0.002cm solid #000000"/> + </style:style> + <style:style style:name="Table1.A2" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border-left="0.002cm solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.002cm solid #000000"/> + </style:style> + <style:style style:name="Table1.E2" style:family="table-cell"> + <style:properties fo:padding="0.097cm" fo:border-left="0.002cm solid #000000" fo:border-right="0.002cm solid #000000" fo:border-top="none" fo:border-bottom="0.002cm solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table Contents"> + <style:properties style:font-name="Arial Black" fo:font-size="20pt"/> + </style:style> + </office:automatic-styles> + + + + + + <office:body> + <text:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + </text:sequence-decls> + + <xsl:apply-templates/> + </office:body> + </office:document-content> + +</xsl:template> + +<xsl:template match="body"> + <xsl:apply-templates /> +</xsl:template> + + + +<xsl:template match="p"> + <xsl:for-each select="."> + <text:p text:style-name="P1"> + <!--<xsl:value-of select="."/>--> + <xsl:apply-templates /> + </text:p> + </xsl:for-each> +</xsl:template> + +<xsl:template match="br"> + <xsl:if test="ancestor::p"> + <xsl:text disable-output-escaping="yes"></text:p> <text:p text:style-name="P1"></xsl:text> + </xsl:if> +</xsl:template> + +<xsl:template match="table"> + <xsl:for-each select="."> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A" table:number-columns-repeated="5"/> + <xsl:apply-templates/> + </table:table> + </xsl:for-each> +</xsl:template> + +<xsl:template match="tr"> + <xsl:for-each select="."> + <table:table-row> + <xsl:apply-templates/> + </table:table-row> + </xsl:for-each> +</xsl:template> + +<xsl:template match="td"> + <xsl:for-each select="."> + <table:table-cell table:style-name="Table1.A1" table:value-type="string"> + <text:p text:style-name="P1"> + <xsl:value-of select="."/> + </text:p> + </table:table-cell> + </xsl:for-each> +</xsl:template> + + + +</xsl:stylesheet> diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/makefile.mk b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/makefile.mk new file mode 100644 index 000000000000..3af2e42c695c --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/makefile.mk @@ -0,0 +1,36 @@ +#*************************************************************************** +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#*************************************************************************** + +TARGET=xmrg_jooxcx_xslt +PRJ=../../../../../../.. + +.INCLUDE : ant.mk +ALLTAR: ANTBUILD diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/package.html b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/package.html new file mode 100644 index 000000000000..88930e761329 --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/package.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: package.html,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<HTML> +<HEAD> + <TITLE>org.openoffice.xmerge.converter.xml.xslt package</TITLE> +</HEAD> +<BODY> +<P>Provides the tools for doing the conversion of StarWriter XML to +and from supported formats, through the use of an XSLT +transformation.</P> +<P>It follows the {@link org.openoffice.xmerge} +framework for the conversion process.</P> +<P>This converter does not currently support merge.</P> +<P><FONT FACE="Times New Roman, serif"><FONT SIZE=5><B>XSLT +Transformation</B></FONT></FONT></P> +<p>The converter makes use +of one or more XSLT style sheets, which are used in the +DocumentSerializer and DocumentDeserializer, to perform the actual +translations. The location of these stylesheets is extracted from the {@link org.openoffice.xmerge.util.registry.ConverterInfo ConverterInfo} data structure, and are specified using the optional converter-xslt-serialize and converter-xsltdeserialize tags in a plugins converter.xml file. Please refer to the SDK document for more information about how to implement a Plugin Configuration XML File for a specific plugin. +A sample OpenOffice to Html stylesheet and Html to +Openffice stylesheet, has been provided as a sample implementation. +The converter also makes use of an XsltPlugin.properties file, which may be edited by the user to provide MIME-TYPE to file extension mappings. This file is used by the {@link org.openoffice.xmerge.converter.xml.xslt.PluginFactoryImpl getDeviceFileExtension} method. +</p> + +<H2>TODO list</H2> + +<p><ol> +<li>Expand XSLT style sheets to support more office/html + capabilities</li> +<li>Add support for certain character codes, such as &nbsp + which currently causes the transformer to break.</li> +<li>Change the DocumentDeserializer transformer, so that the DOMResult is serialized using the xalan serializer and create an SxwDocument from the result</li> +</ol></p> + +@see org.openoffice.xmerge.util.registry + +</BODY> +</HTML> + + diff --git a/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/sofftohtml.xsl b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/sofftohtml.xsl new file mode 100644 index 000000000000..c51d998f548e --- /dev/null +++ b/xmerge/java/org/openoffice/xmerge/converter/xml/xslt/sofftohtml.xsl @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: sofftohtml.xsl,v $ + + $Revision: 1.5 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:style="http://openoffice.org/2000/style" xmlns:table="http://openoffice.org/2000/table" xmlns:text="http://openoffice.org/2000/text" xmlns:office="http://openoffice.org/2000/office" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="ISO-8859-1"/> <!--doctype-system=[<!ENTITY acirc "">] --> <xsl:strip-space elements="tokens"/> <xsl:template match="office:document"> <html> <xsl:apply-templates /> </html> </xsl:template> <xsl:template match="office:document-content"> <html> <xsl:apply-templates /> </html> </xsl:template> <xsl:template match="office:automatic-styles"> <style type="text/css"> p.Table-Heading{font-weight :bold;} <xsl:apply-templates /> </style> </xsl:template> <xsl:template match="office:styles"> </xsl:template> <xsl:template match="office:meta"> </xsl:template> <xsl:template match="office:settings"> </xsl:template> <xsl:template match="style:style"> <xsl:if test="@style:family ='paragraph'"> p.<xsl:value-of select="@style:name"/>{ <xsl:apply-templates />} </xsl:if> <xsl:if test="@style:family ='paragraph'"> p.<xsl:value-of select="@style:name"/>{ <xsl:if test="@style:parent-style-name='Table Heading'"> font-weight :bold;font-style:italic; </xsl:if> <xsl:apply-templates />} </xsl:if> <xsl:if test="@style:family ='table-cell'"> td.<xsl:value-of select="@style:name"/>{ <xsl:if test="@style:parent-style-name='Table Heading'"> font-weight :bold;font-style:italic; </xsl:if> <xsl:apply-templates />} </xsl:if> </xsl:template> <xsl:template match="style:properties"> <!--<xsl:param name="style" select="@fo:font-weight"/>--> <xsl:if test="@fo:font-weight"> font-weight :<xsl:value-of select="@fo:font-weight"/>; </xsl:if> <xsl:if test="@fo:font-style"> font-style :<xsl:value-of select="@fo:font-style"/>; </xsl:if> <xsl:if test="@style:font-name"> font-family :<xsl:value-of select="@style:font-name"/>; </xsl:if> <xsl:if test="@fo:font-size"> font-size : <xsl:value-of select="@fo:font-size"/>; </xsl:if> <xsl:if test="@style:text-underline='single'"> text-decoration :underline; </xsl:if> <xsl:if test="@style:text-crossing-out='single-line'"> text-decoration:line-through; </xsl:if> <xsl:if test="@fo:text-align='start'"> text-align :left </xsl:if> <xsl:if test="@fo:text-align='center'"> text-align :center </xsl:if> <xsl:if test="@fo:text-align='end'"> text-align :right </xsl:if> <!--<xsl:value-of select="$style"/>--> </xsl:template> <xsl:template match="office:body"> <xsl:apply-templates /> </xsl:template> <xsl:template match="table:table"> <table border="1" cellpadding="2" width="100%"> <xsl:apply-templates /> </table> </xsl:template> <xsl:template match="table:table-header-rows"> <th> <xsl:apply-templates /> </th> </xsl:template> <xsl:template match="table:table-row"> <tr> <xsl:apply-templates /> </tr> </xsl:template> <xsl:template match="table:table-cell"> <xsl:text disable-output-escaping="yes"><td class="</xsl:text> <xsl:value-of select="@table:style-name"/> <xsl:text disable-output-escaping="yes">"></xsl:text> <!--<xsl:value-of select="."/>--> <xsl:apply-templates /> <xsl:text disable-output-escaping="yes"></td></xsl:text> <!--<td width="20%"> <xsl:apply-templates /> </td>--> </xsl:template> <xsl:template match="text:p"> <xsl:if test="ancestor-or-self::table:table-cell"> <xsl:if test=".=''"> <br/> </xsl:if> </xsl:if> <xsl:text disable-output-escaping="yes"><p class="</xsl:text> <xsl:choose> <xsl:when test="@text:style-name ='Table Heading'"> Table-Heading </xsl:when> <xsl:otherwise> <xsl:value-of select="@text:style-name"/> </xsl:otherwise> </xsl:choose> <xsl:text disable-output-escaping="yes">"></xsl:text> <xsl:apply-templates/> <xsl:text disable-output-escaping="yes"></p></xsl:text> <!--<xsl:value-of select="."/>--> <!--<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>--> <!--<br/>--> </xsl:template> </xsl:stylesheet> |