Localization improvements and removing some unused code

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@143 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2012-03-19 21:01:15 +00:00
parent de74e5ff6b
commit e3a808f820
39 changed files with 435 additions and 1442 deletions

View file

@ -37,26 +37,24 @@
************************************************************************/
// This version is adapted for writer2latex
// Version 1.2 (2010-03-15)
// Version 1.4 (2012-03-19)
package writer2latex.xmerge;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
//import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
//import java.io.ByteArrayInputStream;
//import java.io.IOException;
import java.io.OutputStreamWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
//import org.xml.sax.SAXParseException;
@ -221,133 +219,106 @@ public class DOMDocument
}
}
/**
* Write out content to the supplied <code>OutputStream</code>.
*
* (with pretty printing)
* @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);
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
osw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
write(getContentDOM().getDocumentElement(),0,osw);
osw.flush();
osw.close();
}
/**
* <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")) {
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"))
{
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")) {
// 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 if (domImpl.equals("gnu.xml.dom.DomDocument")) {
Class gnuSer = Class.forName("gnu.xml.dom.ls.DomLSSerializer");
// Get the serialize method
meth = gnuSer.getMethod("serialize",
new Class [] { Class.forName("org.w3c.dom.Node"),
Class.forName("java.io.OutputStream") } );
// Get an instance
Object serializer = gnuSer.newInstance();
// Now call serialize to write the document
meth.invoke(serializer, new Object [] { doc, baos } );
}
else {
// We dont have another parser
throw new IOException("No appropriate API (JAXP/Xerces) to serialize XML document: " + domImpl);
}
// Write nodes; we only need element, text and comment nodes
private void write(Node node, int nLevel, OutputStreamWriter osw) throws IOException {
short nType = node.getNodeType();
switch (nType) {
case Node.ELEMENT_NODE:
if (node.hasChildNodes()) {
// Block pretty print from this node?
NodeList list = node.getChildNodes();
int nLen = list.getLength();
boolean bBlockPrettyPrint = false;
if (nLevel>=0) {
for (int i = 0; i < nLen; i++) {
bBlockPrettyPrint |= list.item(i).getNodeType()==Node.TEXT_NODE;
}
}
// Print start tag
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<"+node.getNodeName());
writeAttributes(node,osw);
osw.write(">");
if (nLevel>=0 && !bBlockPrettyPrint) { osw.write("\n"); }
// Print children
for (int i = 0; i < nLen; i++) {
int nNextLevel;
if (bBlockPrettyPrint || nLevel<0) { nNextLevel=-1; }
else { nNextLevel=nLevel+1; }
write(list.item(i),nNextLevel,osw);
}
// Print end tag
if (nLevel>=0 && !bBlockPrettyPrint) { writeSpaces(nLevel,osw); }
osw.write("</"+node.getNodeName()+">");
if (nLevel>=0) { osw.write("\n"); }
}
else { // empty element
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<"+node.getNodeName());
writeAttributes(node,osw);
osw.write(" />");
if (nLevel>=0) { osw.write("\n"); }
}
break;
case Node.TEXT_NODE:
write(node.getNodeValue(),osw);
break;
case Node.COMMENT_NODE:
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<!-- ");
write(node.getNodeValue(),osw);
osw.write(" -->");
if (nLevel>=0) { osw.write("\n"); }
}
catch (ClassNotFoundException cnfe) {
throw new IOException(cnfe.toString());
}
private void writeAttributes(Node node, OutputStreamWriter osw) throws IOException {
NamedNodeMap attr = node.getAttributes();
int nLen = attr.getLength();
for (int i=0; i<nLen; i++) {
Node item = attr.item(i);
osw.write(" ");
write(item.getNodeName(),osw);
osw.write("=\"");
write(item.getNodeValue(),osw);
osw.write("\"");
}
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;
}
private void writeSpaces(int nCount, OutputStreamWriter osw) throws IOException {
for (int i=0; i<nCount; i++) { osw.write(" "); }
}
private void write(String s, OutputStreamWriter osw) throws IOException {
int nLen = s.length();
char c;
for (int i=0; i<nLen; i++) {
c = s.charAt(i);
switch (c) {
case ('<'): osw.write("&lt;"); break;
case ('>'): osw.write("&gt;"); break;
case ('&'): osw.write("&amp;"); break;
case ('"'): osw.write("&quot;"); break;
case ('\''): osw.write( "&apos;"); break;
default: osw.write(c);
}
}
}
/**
* Initializes a new DOM <code>Document</code> with the content
* containing minimum XML tags.

View file

@ -38,15 +38,10 @@
************************************************************************/
// This version is adapted for Writer2LaTeX
// Version 1.0 (2008-11-22)
// Version 1.4 (2012-03-19)
package writer2latex.xmerge;
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
@ -105,39 +100,10 @@ public class EmbeddedBinaryObject extends EmbeddedObject {
*
* @param data A <code>byte</code> array containing data for the object.
*/
public void setBinaryData(byte[] data) {
/*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);
}
}*/
}

View file

@ -37,15 +37,10 @@
************************************************************************/
// This version is adapted for Writer2LaTeX
// Version 1.4 (2012-03-19)
package writer2latex.xmerge;
import java.io.IOException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
public abstract class EmbeddedObject {
protected String objName;
protected String objType;
@ -110,20 +105,4 @@ public abstract class EmbeddedObject {
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;
}

View file

@ -37,7 +37,7 @@
************************************************************************/
// This version is adapted for Writer2LaTeX
// Version 1.0 (2008-11-23)
// Version 1.4 (2012-03-19)
package writer2latex.xmerge;
@ -49,9 +49,6 @@ 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;
@ -128,10 +125,10 @@ public class EmbeddedXMLObject extends EmbeddedObject {
*
* @param content DOM representation of the object's content.
*/
public void setContentDOM(Document content) {
/*public void setContentDOM(Document content) {
contentDOM = content;
hasChanged = true;
}
}*/
/**
@ -157,10 +154,10 @@ public class EmbeddedXMLObject extends EmbeddedObject {
*
* @param settings DOM representation of the object's settings.
*/
public void setSettingsDOM(Document settings) {
/*public void setSettingsDOM(Document settings) {
settingsDOM = settings;
hasChanged = true;
}
}*/
/**
@ -186,10 +183,10 @@ public class EmbeddedXMLObject extends EmbeddedObject {
*
* @param styles DOM representation of the object's styles.
*/
public void setStylesDOM(Document styles) {
/*public void setStylesDOM(Document styles) {
stylesDOM = styles;
hasChanged = true;
}
}*/
/**
@ -238,75 +235,5 @@ public class EmbeddedXMLObject extends EmbeddedObject {
}
/**
* 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);
}
}

View file

@ -1,160 +0,0 @@
/************************************************************************
*
* NewDOMDocument.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2006 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2006-10-01)
*
*/
package writer2latex.xmerge;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import writer2latex.xmerge.DOMDocument;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
/**
* An extension of <code>DOMDocument</code>
* that overrides the write method.
* (This method fails with the version of xerces shipped with jre 1.5)
*/
public class NewDOMDocument extends DOMDocument {
/** Constructor
*/
public NewDOMDocument(String sFileName, String sExtension) {
super(sFileName,sExtension);
}
/**
* Write out content to the supplied <code>OutputStream</code>.
* (with pretty printing)
* @param os XML <code>OutputStream</code>.
* @throws IOException If any I/O error occurs.
*/
public void write(OutputStream os) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
osw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
write(getContentDOM().getDocumentElement(),0,osw);
osw.flush();
osw.close();
}
// Write nodes; we only need element, text and comment nodes
private void write(Node node, int nLevel, OutputStreamWriter osw) throws IOException {
short nType = node.getNodeType();
switch (nType) {
case Node.ELEMENT_NODE:
if (node.hasChildNodes()) {
// Block pretty print from this node?
NodeList list = node.getChildNodes();
int nLen = list.getLength();
boolean bBlockPrettyPrint = false;
if (nLevel>=0) {
for (int i = 0; i < nLen; i++) {
bBlockPrettyPrint |= list.item(i).getNodeType()==Node.TEXT_NODE;
}
}
// Print start tag
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<"+node.getNodeName());
writeAttributes(node,osw);
osw.write(">");
if (nLevel>=0 && !bBlockPrettyPrint) { osw.write("\n"); }
// Print children
for (int i = 0; i < nLen; i++) {
int nNextLevel;
if (bBlockPrettyPrint || nLevel<0) { nNextLevel=-1; }
else { nNextLevel=nLevel+1; }
write(list.item(i),nNextLevel,osw);
}
// Print end tag
if (nLevel>=0 && !bBlockPrettyPrint) { writeSpaces(nLevel,osw); }
osw.write("</"+node.getNodeName()+">");
if (nLevel>=0) { osw.write("\n"); }
}
else { // empty element
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<"+node.getNodeName());
writeAttributes(node,osw);
osw.write(" />");
if (nLevel>=0) { osw.write("\n"); }
}
break;
case Node.TEXT_NODE:
write(node.getNodeValue(),osw);
break;
case Node.COMMENT_NODE:
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<!-- ");
write(node.getNodeValue(),osw);
osw.write(" -->");
if (nLevel>=0) { osw.write("\n"); }
}
}
private void writeAttributes(Node node, OutputStreamWriter osw) throws IOException {
NamedNodeMap attr = node.getAttributes();
int nLen = attr.getLength();
for (int i=0; i<nLen; i++) {
Node item = attr.item(i);
osw.write(" ");
write(item.getNodeName(),osw);
osw.write("=\"");
write(item.getNodeValue(),osw);
osw.write("\"");
}
}
private void writeSpaces(int nCount, OutputStreamWriter osw) throws IOException {
for (int i=0; i<nCount; i++) { osw.write(" "); }
}
private void write(String s, OutputStreamWriter osw) throws IOException {
int nLen = s.length();
char c;
for (int i=0; i<nLen; i++) {
c = s.charAt(i);
switch (c) {
case ('<'): osw.write("&lt;"); break;
case ('>'): osw.write("&gt;"); break;
case ('&'): osw.write("&amp;"); break;
case ('"'): osw.write("&quot;"); break;
case ('\''): osw.write( "&apos;"); break;
default: osw.write(c);
}
}
}
}

View file

@ -37,22 +37,17 @@
************************************************************************/
// This version is adapted for Writer2LaTeX
// Version 1.2 (2010-03-28)
// Version 1.4 (2012-03-19)
package writer2latex.xmerge;
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;
@ -64,26 +59,19 @@ 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 writer2latex.office.MIMETypes;
import writer2latex.util.Misc;
//import org.openoffice.xmerge.util.Resources;
//import org.openoffice.xmerge.util.Debug;
/**
* An implementation of <code>Document</code> for
* StarOffice documents.
* This class implements reading of ODF files
*/
public class OfficeDocument
implements writer2latex.xmerge.Document, OfficeConstants {
implements OfficeConstants {
/** Factory for <code>DocumentBuilder</code> objects. */
private static DocumentBuilderFactory factory =
@ -107,9 +95,6 @@ public class OfficeDocument
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
@ -224,46 +209,6 @@ public class OfficeDocument
}
/**
* 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.
@ -413,7 +358,7 @@ public class OfficeDocument
*
* @param embObj An instance of <code>EmbeddedObject</code>.
*/
public void addEmbeddedObject(EmbeddedObject embObj) {
/*public void addEmbeddedObject(EmbeddedObject embObj) {
if (embObj == null) {
return;
}
@ -423,7 +368,7 @@ public class OfficeDocument
}
embeddedObjects.put(embObj.getName(), embObj);
}
}*/
/**
@ -706,383 +651,6 @@ public class OfficeDocument
}
/**
* Method to return the MIME type of the document.
*
* @return String The document's MIME type.
*/
// not really used...
protected String getDocumentMimeType() { return ""; }
/**
* 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<EmbeddedObject> embObjs = getEmbeddedObjects();
while (embObjs.hasNext()) {
EmbeddedObject obj = 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();
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);
os.write(contentBytes);
}
catch(Exception exc){
System.err.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>
@ -1252,45 +820,5 @@ public class OfficeDocument
}
/**
* 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);
}
// TODO: We need these because we implement OutputFile (but in fact we shouldn't)
public String getMIMEType() {
return "";
}
public boolean isMasterDocument() {
return false;
}
}

View file

@ -37,28 +37,22 @@
************************************************************************/
// This version is adapted for Writer2LaTeX
// Version 1.0 (2008-11-22)
// Version 1.4 (2012-03-19)
package writer2latex.xmerge;
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
* OfficeDocument} to handle reading
* from a ZIP file, as well as storing ZIP entries.
*
* @author Herbie Ong
@ -113,9 +107,6 @@ class OfficeZip {
while ((ze = zis.getNextEntry()) != null) {
String name = ze.getName();
//System.out.println("Found "+name);
// Debug.log(Debug.TRACE, "reading entry: " + name);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -240,31 +231,6 @@ class OfficeZip {
}
/**
* 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 = 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
@ -289,171 +255,6 @@ class OfficeZip {
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 = 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<Entry> iterator = entryList.listIterator();
while (iterator.hasNext()) {
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.