summaryrefslogtreecommitdiff
path: root/xmerge/source/xmerge/java/org/openoffice/xmerge/util
diff options
context:
space:
mode:
Diffstat (limited to 'xmerge/source/xmerge/java/org/openoffice/xmerge/util')
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/ActiveSyncDriver.java144
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java446
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.java339
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.properties39
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/EndianConverter.java178
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/IntArrayList.java147
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/OfficeUtil.java135
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/Resources.java99
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/TwipsConverter.java99
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/XmlUtil.java189
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/package.html39
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfo.java436
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoMgr.java526
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoReader.java279
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/RegistryException.java47
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/build.xml135
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/package.html82
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/resources.properties69
18 files changed, 3428 insertions, 0 deletions
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ActiveSyncDriver.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ActiveSyncDriver.java
new file mode 100644
index 000000000000..fb7941a15ae0
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ActiveSyncDriver.java
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.util.StringTokenizer;
+
+import org.openoffice.xmerge.Convert;
+import org.openoffice.xmerge.Document;
+import org.openoffice.xmerge.ConvertData;
+import org.openoffice.xmerge.ConverterFactory;
+import org.openoffice.xmerge.util.registry.ConverterInfoMgr;
+import org.openoffice.xmerge.util.registry.ConverterInfoReader;
+
+public class ActiveSyncDriver {
+ public static void main(String[] args) {
+ if (args.length != 4) {
+ return;
+ }
+
+ ActiveSyncDriver asd = new ActiveSyncDriver();
+
+ try {
+ // At the moment can't really signal back to the calling DLL
+ asd.Convert(args[0], args[1], args[2], args[3]);
+ }
+ catch (Exception e) {
+ return;
+ }
+ }
+
+
+ private boolean Convert(String srcMime, String dstMime, String srcFile, String dstFile) throws Exception {
+ /*
+ * The classpath passed in by XMergeSync.dll should contain all of the
+ * jar files, but at the least it will contain xmerge.jar, so strip off
+ * the xmerge.jar portion and use the remainder to provide a root for
+ * the Pocket Word and Pocket Excel plugins.
+ */
+ String ooClassDir = null;
+ String strClassPath = System.getProperty("java.class.path");
+
+ StringTokenizer st = new StringTokenizer(strClassPath, ";");
+
+ // There should be at least one element, but just in case
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+
+ if (s.endsWith("xmerge.jar")) {
+ ooClassDir = s.substring(0, s.indexOf("xmerge.jar"));
+ }
+ }
+
+ if (ooClassDir == null) {
+ return true;
+ }
+
+
+ /*
+ * The XMergeSync.dll should will have checked for the presence of the
+ * jars at the same location already.
+ *
+ * Because they can be installed separately, though, the MIME types need
+ * to be check to see which one to load.
+ */
+ File pluginJar = null;
+ if (srcMime.equals("staroffice/sxw") || srcMime.equals("application/x-pocket-word"))
+ {
+ pluginJar = new File(ooClassDir + "pocketWord.jar");
+ }
+ else if (srcMime.equals("staroffice/sxc") || srcMime.equals("application/x-pocket-excel"))
+ {
+ pluginJar = new File(ooClassDir + "pexcel.jar");
+ }
+
+ ConverterInfoReader cirPlugin = new ConverterInfoReader(pluginJar.toURL().toString(), false);
+
+ ConverterInfoMgr.addPlugIn(cirPlugin.getConverterInfoEnumeration());
+
+ ConverterFactory cf = new ConverterFactory();
+ Convert conv = cf.getConverter(srcMime, dstMime);
+
+ if (conv == null) {
+ return false;
+ }
+
+ // Everything is registered so do the conversion
+ FileInputStream fis = new FileInputStream(srcFile);
+ FileOutputStream fos = new FileOutputStream(dstFile);
+
+ conv.addInputStream(srcFile, fis);
+
+ ConvertData dataOut;
+ try {
+ dataOut = conv.convert();
+ }
+ catch (Exception e) {
+ return false;
+ }
+
+ if (dataOut == null) {
+ return false;
+ }
+
+ // Get the document and write it out.
+ Document doc = (Document)dataOut.getDocumentEnumeration().nextElement();
+ if (doc == null) {
+ return false;
+ }
+
+ doc.write(fos);
+ fos.flush();
+ fos.close();
+
+ return true;
+ }
+}
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java
new file mode 100644
index 000000000000..30675c0889d5
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+
+import java.awt.Color;
+
+/**
+ * Utility class mapping RGB colour specifications to the colour indices used
+ * in the Pocket PC. The original converter was written for use with Pocket
+ * Word it was later put into the utils so Pocket excel could use this code
+ * also. For this reason the defualt values are those used by Pocket Word but
+ * a colour table can be passed in through the constructor to map the 16
+ * values to a colour table.
+ *
+ * These colour indices are based on the Windows VGA 16 colour palette, which
+ * later was used as the basis for the named colours in the HTML 3.2
+ * specification.
+ *
+ * In Pocket Word's case, the match to the VGA 16 palette is not exact as it
+ * swaps Grey and Silver, with Silver being the darker colour (i.e. having the
+ * lower RGB value).
+ */
+
+public class ColourConverter {
+
+ /** Colour table index for Black */
+ private static final short BLACK = 0;
+
+ /** Colour table index for Silver */
+ private static final short SILVER = 1;
+
+ /** Colour table index for Grey */
+ private static final short GREY = 2;
+
+ /** Colour table index for White */
+ private static final short WHITE = 3;
+
+ /** Colour table index for Red */
+ private static final short RED = 4;
+
+ /** Colour table index for Lime */
+ private static final short LIME = 5;
+
+ /** Colour table index for Blue */
+ private static final short BLUE = 6;
+
+ /** Colour table index for Aqua */
+ private static final short AQUA = 7;
+
+ /** Colour table index for Fuchsia */
+ private static final short FUCHSIA = 8;
+
+ /** Colour table index for Yellow */
+ private static final short YELLOW = 9;
+
+ /** Colour table index for Maroon */
+ private static final short MAROON = 10;
+
+ /** Colour table index for Green */
+ private static final short GREEN = 11;
+
+ /** Colour table index for Navy */
+ private static final short NAVY = 12;
+
+ /** Colour table index for Teal */
+ private static final short TEAL = 13;
+
+ /** Colour table index for Purple */
+ private static final short PURPLE = 14;
+
+ /** Colour table index for Olive */
+ public static final short OLIVE = 15;
+
+ private short tableLookup[] = null;
+
+ /**
+ * Default constructor used in the case where a lookup table is not
+ * required
+ */
+ public ColourConverter() {
+
+ }
+
+ /**
+ * Constructor that passes in the colour lookup table. This is required in
+ * cases where the 16 colour values are something other than there default
+ * values (e.g. in the case of pocket Excel)
+ *
+ * @param lookup a 16 bit array mapping the 16 colours to their values
+ */
+ public ColourConverter(short lookup[]) {
+
+ tableLookup = lookup;
+ }
+
+ /**
+ * Uses the colour table it it exists to translate default values to
+ * values in the colorTable
+ */
+ private short colourLookup(short colour) {
+
+ if(tableLookup!=null) {
+ return tableLookup[colour];
+ } else {
+ return colour;
+ }
+ }
+
+ /**
+ * Uses the colour table it it exists to translate default values to
+ * values in the colorTable
+ */
+ private short indexLookup(short index) {
+
+ short result = 0;
+
+ if(tableLookup!=null) {
+ for(short i = 0;i < tableLookup.length;i++) {
+ if(tableLookup[i]==index)
+ result = i;
+ }
+ } else {
+ result = index;
+ }
+
+ return result;
+ }
+ /**
+ * This method maps a Pocket Word colour index value to an RGB value as
+ * used by OpenOffice.
+ *
+ * @param colour The index into Pocket Word's colour table.
+ *
+ * @return A Color object representing the RGB value of the Pocket Word
+ * colour.
+ */
+ public Color convertToRGB (short colour) {
+
+ short index = indexLookup(colour);
+
+ int r = 0;
+ int g = 0;
+ int b = 0;
+
+ switch (index) {
+ case SILVER:
+ r = g = b = 128;
+ break;
+
+ case GREY:
+ r = g = b = 192;
+ break;
+
+ case WHITE:
+ r = g = b = 255;
+ break;
+
+ case RED:
+ r = 255;
+ break;
+
+ case LIME:
+ g = 255;
+ break;
+
+ case BLUE:
+ b = 255;
+ break;
+
+ case AQUA:
+ g = b = 255;
+ break;
+
+ case FUCHSIA:
+ r = b = 255;
+ break;
+
+ case YELLOW:
+ r = g = 255;
+ break;
+
+ case MAROON:
+ r = 128;
+ break;
+
+ case GREEN:
+ g = 128;
+ break;
+
+ case NAVY:
+ b = 128;
+ break;
+
+ case TEAL:
+ b = g = 128;
+ break;
+
+ case PURPLE:
+ r = b = 128;
+ break;
+
+ case OLIVE:
+ r = g = 128;
+ break;
+
+ case BLACK:
+ default:
+ r = g = b = 0;
+ break;
+ }
+
+ return new Color(r, g, b);
+ }
+
+
+ /**
+ * This method approximates an RGB value (as used by Writer) to one of the
+ * 16 available colours
+ *
+ * Most of the supported colours have their components set to either 0, 128
+ * or 255. The exception is 'Grey' which is 0xC0C0C0.
+ *
+ * @param colour Color object representing the RGB value of the colour.
+ *
+ * @return Index into the Pocket Word colour table which represents the
+ * closest match to the specified colour.
+ */
+ public short convertFromRGB (Color colour) {
+ int matchedRGB = 0;
+ short indexColour = 0;
+ int reducedMap[] = new int[] { 0, 0, 128 };
+
+ int red = colour.getRed();
+ int green = colour.getGreen();
+ int blue = colour.getBlue();
+
+ // We need to convert the pale colors to their base color rather than
+ // white so we modify the rgb values if the colour is sufficently
+ // white
+ if(red>0xC0 && green>0xC0 && blue>0xC0) {
+
+ if(red!=0xFF)
+ red = getClosest(red, reducedMap);
+ if(green!=0xFF)
+ green = getClosest(green, reducedMap);
+ if(blue!=0xFF)
+ blue = getClosest(blue, reducedMap);
+ }
+
+ /*
+ * Need to derive an RGB value that has been rounded to match the ones
+ * Pocket Word knows about.
+ */
+ matchedRGB += getClosest(red) << 16;
+ matchedRGB += getClosest(green) << 8;
+ matchedRGB += getClosest(blue);
+
+ /*
+ * The colour map used by Pocket Word doesn't have any combinations of
+ * values beyond 0 and any other value. A value of 255 in any RGB
+ * code indicates a dominant colour. Other colours are only modifiers
+ * to the principal colour(s). Thus, for this conversion, modifiers
+ * can be dropped.
+ */
+ if ((matchedRGB & 0xFF0000) == 0xFF0000 || (matchedRGB & 0xFF00) == 0xFF00
+ || (matchedRGB & 0xFF) == 0xFF) {
+ if ((matchedRGB & 0xFF0000) == 0x800000) {
+ matchedRGB ^= 0x800000;
+ }
+ if ((matchedRGB & 0xFF00) == 0x8000) {
+ matchedRGB ^= 0x8000;
+ }
+ if ((matchedRGB & 0xFF) == 0x80) {
+ matchedRGB ^= 0x80;
+ }
+ }
+
+
+ /*
+ * And now for the actual matching ...
+ *
+ * Colours are based on the Windows VGA 16 palette. One difference
+ * though is that Pocket Word seems to switch the RGB codes for Grey
+ * and Silver. In Pocket Word Silver is the darker colour leaving Grey
+ * is closest to White.
+ *
+ * Shades of grey will be converted to either Silver or White, where
+ * Grey may be a more appropraite colour. This is handled specially
+ * only for Silver and White matches.
+ */
+ switch (matchedRGB) {
+ case 0x000000:
+ indexColour = BLACK;
+ break;
+
+ case 0x808080:
+ if (!isGrey(colour)) {
+ indexColour = SILVER;
+ }
+ else {
+ indexColour = GREY;
+ }
+ break;
+
+ case 0xFFFFFF:
+ if (!isGrey(colour)) {
+ indexColour = WHITE;
+ }
+ else {
+ indexColour = GREY;
+ }
+ break;
+
+ case 0xFF0000:
+ indexColour = RED;
+ break;
+
+ case 0x00FF00:
+ indexColour = LIME;
+ break;
+
+ case 0x0000FF:
+ indexColour = BLUE;
+ break;
+
+ case 0x00FFFF:
+ indexColour = AQUA;
+ break;
+
+ case 0xFF00FF:
+ indexColour = FUCHSIA;
+ break;
+
+ case 0xFFFF00:
+ indexColour = YELLOW;
+ break;
+
+ case 0x800000:
+ indexColour = MAROON;
+ break;
+
+ case 0x008000:
+ indexColour = GREEN;
+ break;
+
+ case 0x000080:
+ indexColour = NAVY;
+ break;
+
+ case 0x008080:
+ indexColour = TEAL;
+ break;
+
+ case 0x800080:
+ indexColour = PURPLE;
+ break;
+
+ case 0x808000:
+ indexColour = OLIVE;
+ break;
+
+ default: // Just in case!
+ indexColour = BLACK;
+ break;
+ }
+
+ return colourLookup(indexColour);
+ }
+
+
+ /*
+ * Default implementation, checks for the closest of value to 0, 128 or 255.
+ */
+ private int getClosest(int value) {
+ int points[] = new int[] { 0, 128, 255 };
+
+ return getClosest(value, points);
+ }
+
+
+ /*
+ * Utility method that returns the closest of the three points to the value
+ * supplied.
+ */
+ private int getClosest(int value, int[] points) {
+
+ if (value == points[0] || value == points[1] || value == points[2]) {
+ return value;
+ }
+
+ if (value < points[1]) {
+ int x = value - points[0];
+ return (Math.round((float)x / (points[1] - points[0])) == 1 ? points[1] : points[0]);
+ }
+ else {
+ int x = value - points[1];
+ return (Math.round((float)x / (points[2] - points[1])) >= 1 ? points[2] : points[1]);
+ }
+ }
+
+
+ /*
+ * Checks to see if the supplied colour can be considered to be grey.
+ */
+ private boolean isGrey(Color c) {
+ int matchedRGB = 0;
+ int points[] = new int[] { 128, 192, 255 };
+
+ matchedRGB += getClosest(c.getRed(), points) << 16;
+ matchedRGB += getClosest(c.getGreen(), points) << 8;
+ matchedRGB += getClosest(c.getBlue(), points);
+
+ if (matchedRGB == 0xC0C0C0) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.java
new file mode 100644
index 000000000000..7edef508507a
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.java
@@ -0,0 +1,339 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Calendar;
+import java.util.Properties;
+
+/**
+ * This class is used for logging debug messages.
+ * Currently, there are three types of logging: {@link #INFO},
+ * {@link #TRACE} & {@link #ERROR}. Use the Debug.properties
+ * file to set or unset each type. Also use Debug.properties
+ * to set the writer to either <code>System.out</code>,
+ * <code>System.err</code>, or to a file.
+ *
+ * @author Herbie Ong
+ */
+public final class Debug {
+
+ /** Informational messages. */
+ public final static int INFO = 0x0001;
+ /** Error messages. */
+ public final static int ERROR = 0x0002;
+ /** Trace messages. */
+ public final static int TRACE = 0x0004;
+
+ /** To set a flag. */
+ public final static boolean SET = true;
+ /** To unset a flag. */
+ public final static boolean UNSET = false;
+
+ private static int flags = 0;
+ private static PrintWriter writer = null;
+
+ static {
+
+ try {
+
+ Class c = new Debug().getClass();
+ InputStream is = c.getResourceAsStream("Debug.properties");
+ Properties props = new Properties();
+ props.load(is);
+
+ String info = props.getProperty("debug.info", "false");
+ info = info.toLowerCase();
+
+ if (info.equals("true")) {
+ setFlags(Debug.INFO, Debug.SET);
+ }
+
+ String trace = props.getProperty("debug.trace", "false");
+ trace = trace.toLowerCase();
+
+ if (trace.equals("true")) {
+ setFlags(Debug.TRACE, Debug.SET);
+ }
+
+ String error = props.getProperty("debug.error", "false");
+ error = error.toLowerCase();
+
+ if (error.equals("true")) {
+ setFlags(Debug.ERROR, Debug.SET);
+ }
+
+ String w = props.getProperty("debug.output", "System.out");
+ setOutput(w);
+
+ } catch (Throwable ex) {
+
+ ex.printStackTrace(System.err);
+ }
+ }
+
+
+ /**
+ * Private constructor so as not to allow any instances
+ * of this class. This serves as a singleton class.
+ */
+ private Debug() {
+ }
+
+
+ /**
+ * Set the output to the specified argument.
+ * This method is only used internally to prevent
+ * invalid string parameters.
+ *
+ * @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 <code>OutputStream</code> object.
+ *
+ * @param stream OutputStream object.
+ */
+ private static void setOutput(OutputStream stream) {
+
+ setOutput(new OutputStreamWriter(stream));
+ }
+
+
+ /**
+ * Set the <code>Writer</code> object to manage the output.
+ *
+ * @param w <code>Writer</code> object to write out.
+ */
+ private static void setOutput(Writer w) {
+
+ if (writer != null) {
+
+ writer.close();
+ }
+
+ writer = new PrintWriter(new BufferedWriter(w), true);
+ }
+
+
+ /**
+ * <p>
+ * This method sets the levels for debugging logs.
+ * Example calls:
+ * </p>
+ *
+ * <blockquote><pre><code>
+ * Debug.setFlags( Debug.INFO, Debug.SET )
+ * Debug.setFlags( Debug.TRACE, Debug.SET )
+ * Debug.setFlags( Debug.INFO | Debug.TRACE, Debug.SET )
+ * Debug.setFlags( Debug.ERROR, Debug.UNSET )
+ * </code></pre></blockquote>
+ *
+ * @param f Debug flag
+ * @param set Use Debug.SET to set, and Debug.UNSET to unset
+ * the given flag.
+ */
+ private static void setFlags(int f, boolean set) {
+
+ if (set) {
+ flags |= f;
+ } else {
+ flags &= ~f;
+ }
+ }
+
+
+ /**
+ * Prints out information regarding platform.
+ */
+ public static void logSystemInfo() {
+
+ if (writer != null) {
+
+ writer.println();
+ writer.println("Platform Information:");
+ writer.println("OS : " + System.getProperty("os.name"));
+ writer.println("Version : " + System.getProperty("os.version"));
+ writer.println("Platform : " + System.getProperty("os.arch"));
+ writer.println("JDK Version : " + System.getProperty("java.version"));
+ writer.println("JDK Vendor : " + System.getProperty("java.vendor"));
+ writer.println();
+ }
+ }
+
+
+ /**
+ * Prints out timestamp.
+ */
+ public static void logTime() {
+
+ if (writer != null) {
+
+ Date time = Calendar.getInstance().getTime();
+ DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
+ writer.println(dt.format(time));
+ }
+ }
+
+
+ /**
+ * Checks if flag is set.
+ *
+ * @return true if info logging is on, otherwise false
+ */
+ public static boolean isFlagSet(int f) {
+
+ return ((flags & f) != 0);
+ }
+
+
+ /**
+ * <p>Log message based on the flag type.</p>
+ *
+ * <p>Example 1:</p>
+ *
+ * <blockquote><pre><code>
+ * Debug.log(Debug.INFO, "info string here");
+ * </code></pre></blockquote>
+ *
+ * <p>This logs the message during runtime if
+ * <code>debug.info</code> in the properties file is
+ * set to true.</p>
+ *
+ * <p>Example 2:</p>
+ *
+ * <blockquote><pre><code>
+ * Debug.log(Debug.INFO | Debug.TRACE, "info string here");
+ * </code></pre></blockquote>
+ *
+ * <p>This logs the message during runtime if debug.info or debug.trace
+ * in the properties file is set to true.</p>
+ *
+ * @param flag Log type, one of the Debug constants
+ * {@link #INFO}, {@link #TRACE}, {@link #ERROR}
+ * or a combination of which or'ed together.
+ * @param msg The message.
+ */
+ public static void log(int flag, String msg) {
+
+ if (isFlagSet(flag)) {
+
+ if (writer != null) {
+
+ writer.println(msg);
+ }
+ }
+ }
+
+
+ /**
+ * Log message based on flag type plus print out stack trace
+ * of the exception passed in. Refer to the other log method
+ * for description.
+ *
+ * @param flag Log type, one of the Debug constants
+ * {@link #INFO}, {@link #TRACE}, {@link #ERROR}
+ * or a combination of which or'ed together.
+ * @param msg The message.
+ * @param e Throwable object.
+ */
+ public static void log(int flag, String msg, Throwable e) {
+
+ if (isFlagSet(flag)) {
+
+ if (writer != null) {
+
+ writer.println(msg);
+ if (e != null)
+ e.printStackTrace(writer);
+ }
+ }
+ }
+
+
+ /**
+ * Converts the given bytes to a <code>String</code> of
+ * Hex digits.
+ *
+ * @param bytes <code>byte</code> array.
+ *
+ * @return Hex representation in a <code>String</code>.
+ */
+ public static String byteArrayToHexString(byte bytes[]) {
+
+ StringBuffer buff = new StringBuffer();
+
+ for (int i = 0; i < bytes.length; i++) {
+
+ int ch = ((int) bytes[i] & 0xff);
+ String str = Integer.toHexString(ch);
+ if (str.length() < 2)
+ buff.append('0');
+ buff.append(str);
+ buff.append(' ');
+ }
+
+ return buff.toString();
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.properties b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.properties
new file mode 100644
index 000000000000..925392b86cdd
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Debug.properties
@@ -0,0 +1,39 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# 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.
+#
+#*************************************************************************
+# x-no-translate
+
+
+#
+# debug logging information and settings.
+#
+
+debug.info=false
+debug.trace=false
+debug.error=false
+debug.output=System.err
+
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/EndianConverter.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/EndianConverter.java
new file mode 100644
index 000000000000..c41a428dd0c2
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/EndianConverter.java
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+
+/**
+ * <p>Helper class providing static methods to convert data to/from
+ * Network Byte Order (Big Endian).</p>
+ *
+ * <p>With the introduction of <code>java.nio.ByteOrder</code> and
+ * <code>java.nio.ByteBuffer</code> in Java 1.4, it may no longer be
+ * necessary to use this class in the future.</p>
+ *
+ * @author Mark Murnane
+ * @version 1.1
+ */
+public class EndianConverter {
+
+ /**
+ * <p>Convert a <code>short</code> to a Little Endian representation.</p>
+ *
+ * @param value The <code>short</code> to be converted.
+ *
+ * @return Two element <code>byte</code> array containing the converted
+ * value.
+ */
+ public static byte[] writeShort (short value) {
+ byte[] leShort = new byte[2];
+
+ leShort[0] = (byte) value;
+ leShort[1] = (byte) (value >>> 8);
+
+ return leShort;
+ }
+
+
+ /**
+ * <p>Convert an integer to a Little Endian representation.</p>
+ *
+ * @param value The <code>int</code> to be converted.
+ *
+ * @return Four element <code>byte</code> array containing the converted
+ * value.
+ */
+ public static byte[] writeInt (int value) {
+ byte[] leInt = new byte[4];
+
+ leInt[0] = (byte) value;
+ leInt[1] = (byte) (value >>> 8);
+ leInt[2] = (byte) (value >>> 16);
+ leInt[3] = (byte) (value >>> 24);
+
+ return leInt;
+ }
+
+ /**
+ * <p>Converts a <code>double</code> to a Little Endian representation
+ * of a float in IEEE-754 format.
+ *
+ * <p>An array with more than eight elements can be used, but only the first
+ * eight elements will be read.</p>
+ *
+ * @param value <code>double</code> containing the value to be converted
+ *
+ * @return <code>byte</code> array containing the LE representation of a IEEE-754 float
+ */
+ public static byte[] writeDouble(double value) {
+
+ long myDouble = Double.doubleToLongBits(value);
+ byte[] leDouble = new byte[8];
+
+ leDouble[0] = (byte) (myDouble >>> 0);
+ leDouble[1] = (byte) (myDouble >>> 8);
+ leDouble[2] = (byte) (myDouble >>> 16);
+ leDouble[3] = (byte) (myDouble >>> 24);
+ leDouble[4] = (byte) (myDouble >>> 32);
+ leDouble[5] = (byte) (myDouble >>> 40);
+ leDouble[6] = (byte) (myDouble >>> 48);
+ leDouble[7] = (byte) (myDouble >>> 56);
+
+ return leDouble;
+ }
+
+ /**
+ * <p>Convert a Little Endian representation of a short to a Java
+ * <code>short</code> (Network Byte Order).</p>
+ *
+ * <p>An array with more than two elements can be used, but only the first
+ * two elements will be read.</p>
+ *
+ * @param value <code>byte</code> array containing the LE representation
+ * of the value.
+ *
+ * @return <code>short</code> containing the converted value.
+ */
+ public static short readShort (byte[] value) {
+ int high, low;
+
+ high = value[1] & 0xFF;
+ low = value[0] & 0xFF;
+
+ return (short)(high << 8 | low);
+ }
+
+
+ /**
+ * <p>Convert a Little Endian representation of an integer to a Java
+ * <code>int</code> (Network Byte Order).</p>
+ *
+ * <p>An array with more than four elements can be used, but only the first
+ * four elements will be read.</p>
+ *
+ * @param value <code>byte</code> array containing the LE representation
+ * of the value.
+ *
+ * @return <code>int</code> containing the converted value.
+ */
+ public static int readInt(byte[] value) {
+ int number = 0;
+
+ for (int i = 0; i < 4; i++) {
+ number |= (value[i] & 0xFF) << ( i * 8);
+ }
+
+ return number;
+ }
+
+ /**
+ * <p>Convert a Little Endian representation of a float in IEEE-754 Little
+ * Endian to a Java <code>double</code> (Network Byte Order).</p>
+ *
+ * <p>An array with more than eight elements can be used, but only the first
+ * eight elements will be read.</p>
+ *
+ * @param value <code>byte</code> array containing the LE representation
+ * of a IEEE-754 float.
+ *
+ * @return <code>double</code> containing the converted value.
+ */
+ public static double readDouble(byte[] value) {
+
+ long lvalue = ( ((long)(value[7]) << 56) +
+ ((long)(value[6]&0xFF) << 48) +
+ ((long)(value[5]&0xFF) << 40) +
+ ((long)(value[4]&0xFF) << 32) +
+ ((long)(value[3]&0xFF) << 24) +
+ ((long)(value[2]&0xFF) << 16) +
+ ((long)(value[1]&0xFF) << 8) +
+ (long)(value[0]&0xFF));
+
+ return Double.longBitsToDouble(lvalue);
+ }
+}
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/IntArrayList.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/IntArrayList.java
new file mode 100644
index 000000000000..a317fa2997e1
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/IntArrayList.java
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+import java.util.ArrayList;
+import java.lang.Integer;
+
+/**
+ * This is a convenience class used to create an
+ * <code>ArrayList</code> of integers.
+ */
+public class IntArrayList {
+
+ /** The list to hold our integers. */
+ private ArrayList list;
+
+ /**
+ * Constructor.
+ * Creates the list with 0 length.
+ */
+ public IntArrayList() {
+ list = new ArrayList();
+ }
+
+
+ /**
+ * Constructor.
+ *
+ * @param initialCapacity Initial capacity of the list.
+ */
+ public IntArrayList(int initialCapacity) {
+ list = new ArrayList(initialCapacity);
+ }
+
+
+ /**
+ * This method ensures that the list is large enough for
+ * <code>minCapacity</code> elements.
+ *
+ * @param minCapacity The minimum capacity of the list.
+ */
+ public void ensureCapacity(int minCapacity) {
+
+ list.ensureCapacity(minCapacity);
+ }
+
+
+ /**
+ * This method ensures that the list is large enough for
+ * <code>minCapacity</code> elements. It also fills in the
+ * new slots in the list with the integer value input as
+ * <code>fillValue</code>.
+ *
+ * @param minCapacity The minimum capacity of the list.
+ * @param fillValue This method adds in a integer for each
+ * slot that was added to ensure that the
+ * list meets the minimum capacity.
+ * <code>fillValue</code> is the value
+ * used as the initial value of these
+ * added elements.
+ */
+ public void ensureCapacityAndFill(int minCapacity, int fillValue) {
+
+ list.ensureCapacity(minCapacity);
+
+ int needToAdd = minCapacity - list.size();
+ if (needToAdd > 0) {
+ for (int i = 0; i < needToAdd; i++) {
+ list.add(new Integer(fillValue));
+ }
+ }
+ }
+
+
+ /**
+ * This method sets an element of the list to the input
+ * integer value.
+ *
+ * @param index The index in the list of the element
+ * we wish to set.
+ * @param value The integer value that we assign to the
+ * selected element of the list.
+ */
+ public void set(int index, int value) {
+ list.set(index, new Integer(value));
+ }
+
+
+ /**
+ * This method appends an element to the list.
+ *
+ * @param value The integer value that we assign to the
+ * element that we are appending to the list.
+ */
+ public void add(int value) {
+ list.add(new Integer(value));
+ }
+
+
+ /**
+ * This method gets the integer value stored in element index.
+ *
+ * @param index The index in the list of the element
+ * we wish to get the value from.
+ *
+ * @return The value of the data stored in element index.
+ */
+ public int get(int index) {
+ return ((Integer)list.get(index)).intValue();
+ }
+
+
+ /**
+ * This method gets the size of the list.
+ *
+ * @return The size of the list.
+ */
+ public int size() {
+ return list.size();
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/OfficeUtil.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/OfficeUtil.java
new file mode 100644
index 000000000000..64a37037c406
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/OfficeUtil.java
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import org.openoffice.xmerge.converter.xml.OfficeConstants;
+
+import java.util.Vector;
+
+
+/**
+ * Class providing utility methods for OpenOffice plugins.
+ *
+ * @author Mark Murnane
+ * @version 1.1
+ */
+public class OfficeUtil implements OfficeConstants {
+
+ /**
+ * <p>Method to replace whitespace character within text with appropriate
+ * OpenOffice tags.</p>
+ *
+ * @param text The text to parse for whitespace.
+ *
+ * @return <code>Node</code> array containing OpenOffice XML nodes
+ * representing the text.
+ */
+ public static Node[] parseText(String text, Document parentDoc) {
+ Vector nodeVec = new Vector();
+
+ /*
+ * Break up the text from the 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);
+ }
+ 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
+ } 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);
+ }
+ }
+
+ /*
+ * 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);
+ }
+
+ // 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;
+ }
+} \ No newline at end of file
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Resources.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Resources.java
new file mode 100644
index 000000000000..44db518b3389
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/Resources.java
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+import java.util.ResourceBundle;
+
+/**
+ * <p>Provides a singleton resource class for converter messages.</p>
+ *
+ * <p>By default, this class will search for a
+ * <code>ResourceBundle</code> class file or properties file based
+ * on the default locale.</p>
+ *
+ * <p>A properties file resources.properties will be provided.</p>
+ *
+ * <p>Note that if the resource bundle object is not loaded, the
+ * construction of the singleton object will throw a
+ * <code>MissingResourceException</code>, which is a
+ * <code>RuntimeException</code>, thus I opted to not explicitly
+ * declare it. If it does throw <code>MissingResourceException</code>,
+ * it may be due to a packaging problem.</p>
+ *
+ * @author Herbie Ong
+ */
+public final class Resources
+{
+ private ResourceBundle rb = null;
+
+ private static Resources instance = null;
+
+
+ /**
+ * This method returns the singleton instance
+ * of this class.
+ *
+ * @return The singleton <code>Resources</code>
+ * instance.
+ */
+ public synchronized static Resources getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new Resources();
+ }
+
+ return instance;
+ }
+
+
+ /**
+ * Default constructor is only accessible within this class.
+ * Load the resource bundle that contains the resource
+ * <code>String</code> values.
+ */
+ private Resources()
+ {
+ rb = ResourceBundle.getBundle("org.openoffice.xmerge.util.resources");
+ }
+
+
+ /**
+ * This method returns the corresponding <code>String</code> given
+ * the key.
+ *
+ * @param key Key string for getting the message
+ * <code>String</code>.
+ * @return Message <code>String</code> corresponding to the key.
+ */
+ public String getString(String key)
+ {
+ return rb.getString(key);
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/TwipsConverter.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/TwipsConverter.java
new file mode 100644
index 000000000000..fe3931a5aadf
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/TwipsConverter.java
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+
+/**
+ * <p>Helper class providing static methods to convert data to/from
+ * twips</p>
+ *
+ * @author Martin Maher
+ */
+public class TwipsConverter {
+
+ /**
+ * <p>Convert from twips to cm's</p>
+ *
+ * @param value The <code>short</code> to be converted.
+ *
+ * @return float containing the converted
+ */
+ public static float twips2cm(int value) {
+
+ float inches = (float) value/1440;
+ float cm = (float) inches*(float)2.54;
+
+ return cm;
+ }
+
+
+
+ /**
+ * <p>Convert from cm's to twips</p>
+ *
+ * @param value <code>byte</code> array containing the LE representation
+ * of the value.
+ *
+ * @return int containing the converted value.
+ */
+ public static int cm2twips(float value) {
+
+ int twips = (int) ((value/2.54)*1440);
+
+ return twips;
+ }
+
+ /**
+ * <p>Convert from twips to cm's</p>
+ *
+ * @param value The <code>short</code> to be converted.
+ *
+ * @return float containing the converted
+ */
+ public static float twips2inches(int value) {
+
+ return (float) value/1440;
+ }
+
+
+
+ /**
+ * <p>Convert from cm's to twips</p>
+ *
+ * @param value <code>byte</code> array containing the LE representation
+ * of the value.
+ *
+ * @return int containing the converted value.
+ */
+ public static int inches2twips(float value) {
+
+ return (int) (value*1440);
+ }
+
+
+}
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/XmlUtil.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/XmlUtil.java
new file mode 100644
index 000000000000..9b3ec402b2e8
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/XmlUtil.java
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * Class containing static util methods for handling XML trees.
+ *
+ * @author smak
+ */
+public final class XmlUtil {
+
+
+ /**
+ * Perform a deep clone of certain <code>Node</code> which
+ * will base on the document <code>Node</code> of the old
+ * <code>Node</code>.
+ *
+ * @param oldNode The <code>Document</code> of this
+ * <code>Node</code> is used to clone
+ * the <code>Node</code>
+ * @param newNode The <code>Node</code> to clone.
+ *
+ * @return The cloned <code>Node</code>.
+ */
+ public static Node deepClone(Node oldNode, Node newNode) {
+ Document docNode = oldNode.getOwnerDocument();
+
+ // clone the starting node
+ Node clonedNode = cloneNode(docNode, newNode);
+
+ // then clone the sub-tree recursively
+ cloneTree(docNode, clonedNode, newNode);
+
+ return clonedNode;
+ }
+
+
+ /**
+ * Clone the sub-tree under certain given <code>Node</code>
+ *
+ * @param docNode The <code>Document</code> used to clone
+ * the <code>Node</code>.
+ * @param oldNode The <code>Node</code> to clone.
+ * @param newNode The destination <code>Node</code>.
+ */
+ private static void cloneTree(Document docNode, Node oldNode, Node newNode) {
+
+ NodeList nodeList = newNode.getChildNodes();
+ int nodeListLen = nodeList.getLength();
+
+ for (int i = 0; i < nodeListLen; i++) {
+ Node newClonedChild = cloneNode(docNode, nodeList.item(i));
+ if (newClonedChild != null) {
+ oldNode.appendChild(newClonedChild);
+ cloneTree(docNode, newClonedChild, nodeList.item(i));
+ }
+ }
+ }
+
+
+ /**
+ * Clone a <code>Node</code> (either text or element).
+ *
+ * @param docNode The <code>Document</code> used to
+ * clone the <code>Node</code>.
+ * @param newNode The <code>Node</code> to clone.
+ *
+ * @return The cloned <code>Node</code>.
+ */
+ private static Node cloneNode(Document docNode, Node newNode) {
+
+ Node clonedNode = null;
+
+ // only support text node and element node (will copy the attributes)
+ switch (newNode.getNodeType()) {
+ case Node.TEXT_NODE:
+ String textStr = newNode.getNodeValue();
+ clonedNode = docNode.createTextNode(textStr);
+ break;
+ case Node.ELEMENT_NODE:
+ Element oldElem = (Element)newNode;
+ String tagName = newNode.getNodeName();
+ Element newElem = (docNode.createElement(tagName));
+
+ // copy the attributes
+ NamedNodeMap attrs = oldElem.getAttributes();
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ newElem.setAttribute(attrs.item(i).getNodeName(),
+ attrs.item(i).getNodeValue());
+ }
+ clonedNode = newElem;
+ break;
+ }
+ return clonedNode;
+ }
+
+
+ /**
+ * Returns the name and type of an XML DOM <code>Node</code>.
+ *
+ * @param node <code>Node</code> to query.
+ *
+ * @return Name and type of XML DOM <code>Node</code>.
+ */
+ public static String getNodeInfo(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;
+ }
+
+ StringBuffer buffer = new StringBuffer("name=\"");
+ buffer.append(node.getNodeName());
+ buffer.append("\" type=\"");
+ buffer.append(str);
+ buffer.append("\"");
+
+ return buffer.toString();
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/package.html b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/package.html
new file mode 100644
index 000000000000..1caffdbe41d4
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/package.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+ #*************************************************************************
+ #
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ Copyright 2000, 2010 Oracle and/or its affiliates.
+
+ OpenOffice.org - a multi-platform office productivity suite
+
+ 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>Provides general purpose utilities.</p>
+
+</body>
+</html>
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfo.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfo.java
new file mode 100644
index 000000000000..359bcbfeb222
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfo.java
@@ -0,0 +1,436 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util.registry;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.lang.reflect.Constructor;
+import org.openoffice.xmerge.PluginFactory;
+import org.openoffice.xmerge.DocumentSerializerFactory;
+import org.openoffice.xmerge.DocumentDeserializerFactory;
+import org.openoffice.xmerge.DocumentMergerFactory;
+
+/**
+ * Class for storing the information about a converter plugin.
+ *
+ * @author Brian Cameron
+ */
+public class ConverterInfo {
+
+ /**
+ * Keep track of the valid Office mime types
+ */
+ private static String[] validOfficeTypes;
+ public static String SxwType = "staroffice/sxw";
+ public static String SxcType = "staroffice/sxc";
+
+
+ static {
+ // This needs to be updated to reflect all valid office types.
+ //
+ validOfficeTypes = new String[2];
+ validOfficeTypes[0] = SxwType;
+ validOfficeTypes[1] = SxcType;
+ }
+
+ private String piJarName;
+ private String piOfficeMime;
+ private Vector piDeviceMime;
+ private String piDisplayName;
+ private String piDescription;
+ private String piVersion;
+ private String piVendor;
+ private String piClassImpl;
+ private String piXsltSerial;
+ private String piXsltDeserial;
+ private boolean piCanSerialize = false;
+ private boolean piCanDeserialize = false;
+ private boolean piCanMerge = false;
+ private ClassLoader piClassLoader = null;
+ private PluginFactory piPluginFactory;
+
+
+ /**
+ * The constructor builds a ConverterInfo structure.
+ *
+ * @param jarName The URL of the jarfile.
+ * @param officeMime The office mime-type.
+ * @param deviceMime The device mime-type.
+ * @param displayName The display name.
+ * @param description The description.
+ * @param version The version.
+ * @param vendor The vendor name.
+ * @param impl The implementation class name of
+ * PluginFactory.
+ * @param xsltSerial The url of the serializer xsl stylesheet
+ * @param xsltDeserial The url of the deserializer xsl stylesheet
+ *
+ * @throws RegistryException If <code>ci</code> cannot
+ * be loaded.
+ */
+ public ConverterInfo(String jarName, String officeMime,
+ Vector deviceMime, String displayName, String description,
+ String version, String vendor, String impl,String xsltSerial,
+ String xsltDeserial)
+ throws RegistryException {
+
+ if (isValidOfficeType(officeMime.trim()) == false) {
+ RegistryException re = new RegistryException(
+ "Invalid office type");
+ throw re;
+ }
+
+ piJarName = jarName.trim();
+ piOfficeMime = officeMime.trim();
+ piDeviceMime = deviceMime;
+ piDisplayName = displayName.trim();
+ piDescription = description.trim();
+ piVersion = version.trim();
+ piVendor = vendor.trim();
+ piXsltSerial = xsltSerial.trim();
+ piXsltDeserial= xsltDeserial.trim();
+ piClassImpl = impl.trim();
+ piClassLoader = this.getClass().getClassLoader();
+
+ // Get instance of the PluginFactory.
+ //
+ try {
+ URL jarURL = new URL(jarName);
+ URLClassLoader loader = new URLClassLoader(new URL[] { jarURL },
+ piClassLoader);
+ Class clas = loader.loadClass(piClassImpl);
+ Class[] argumentTypes = { org.openoffice.xmerge.util.registry.ConverterInfo.class };
+ Constructor construct = clas.getConstructor(argumentTypes);
+
+ Object[] arguments = { this };
+ piPluginFactory = ( PluginFactory ) construct.newInstance(arguments);
+
+ // See which interfaces the plug-in PluginFactory supports.
+ //
+ Class[] cl = piPluginFactory.getClass().getInterfaces();
+ for (int i=0; i < cl.length; i++) {
+
+ if (cl[i].getName().equals("org.openoffice.xmerge.DocumentSerializerFactory")) {
+ piCanSerialize = true;
+ }
+ if (cl[i].getName().equals("org.openoffice.xmerge.DocumentDeserializerFactory")) {
+ piCanDeserialize = true;
+ }
+ if (cl[i].getName().equals("org.openoffice.xmerge.DocumentMergerFactory")) {
+ piCanMerge = true;
+ }
+ }
+
+ } catch (Exception e) {
+ RegistryException re = new RegistryException(
+ "Class implementation of the plug-in cannot be loaded.");
+ throw re;
+ }
+ }
+
+ /**
+ * The constructor builds a ConverterInfo structure.
+ *
+ * @param jarName The URL of the jarfile.
+ * @param officeMime The office mime-type.
+ * @param deviceMime The device mime-type.
+ * @param displayName The display name.
+ * @param description The description.
+ * @param version The version.
+ * @param vendor The vendor name.
+ * @param impl The implementation class name of
+ * PluginFactory.
+ *
+ * @throws RegistryException If <code>ci</code> cannot
+ * be loaded.
+ */
+
+
+ public ConverterInfo(String jarName, String officeMime,
+ Vector deviceMime, String displayName, String description,
+ String version, String vendor, String impl)
+ throws RegistryException {
+
+ if (isValidOfficeType(officeMime.trim()) == false) {
+ RegistryException re = new RegistryException(
+ "Invalid office type");
+ throw re;
+ }
+
+ piJarName = jarName.trim();
+ piOfficeMime = officeMime.trim();
+ piDeviceMime = deviceMime;
+ piDisplayName = displayName.trim();
+ piDescription = description.trim();
+ piVersion = version.trim();
+ piVendor = vendor.trim();
+ piClassImpl = impl.trim();
+ piClassLoader = this.getClass().getClassLoader();
+
+ // Get instance of the PluginFactory.
+ //
+ try {
+ URL jarURL = new URL(jarName);
+ URLClassLoader loader = new URLClassLoader(new URL[] { jarURL },
+ piClassLoader);
+ Class clas = loader.loadClass(piClassImpl);
+ Class[] argumentTypes = { org.openoffice.xmerge.util.registry.ConverterInfo.class };
+ Constructor construct = clas.getConstructor(argumentTypes);
+
+ Object[] arguments = { this };
+ piPluginFactory = ( PluginFactory ) construct.newInstance(arguments);
+
+ // See which interfaces the plug-in PluginFactory supports.
+ //
+ Class[] cl = piPluginFactory.getClass().getInterfaces();
+ for (int i=0; i < cl.length; i++) {
+
+ if (cl[i].getName().equals("org.openoffice.xmerge.DocumentSerializerFactory")) {
+ piCanSerialize = true;
+ }
+ if (cl[i].getName().equals("org.openoffice.xmerge.DocumentDeserializerFactory")) {
+ piCanDeserialize = true;
+ }
+ if (cl[i].getName().equals("org.openoffice.xmerge.DocumentMergerFactory")) {
+ piCanMerge = true;
+ }
+ }
+
+ } catch (Exception e) {
+ RegistryException re = new RegistryException(
+ "Class implementation of the plug-in cannot be loaded.");
+ throw re;
+ }
+ }
+
+
+
+
+ /**
+ * Create a default constructor so we can use isValidOfficeType
+ * without having to actually have a valid ConverterInfo.
+ */
+ private ConverterInfo() {
+ }
+
+
+ /**
+ * Returns an instance of the DocumentDeserializerFactory interface.
+ *
+ * @return instance of the DocumentDeserializer for this ConverterInfo.
+ */
+ public DocumentSerializerFactory getDocSerializerFactory() {
+ return (DocumentSerializerFactory)piPluginFactory;
+ }
+
+
+ /**
+ * Returns an instance of the DocumentSerializerFactory interface.
+ *
+ * @return instance of the DocumentSerializer for this ConverterInfo.
+ */
+ public DocumentDeserializerFactory getDocDeserializerFactory() {
+ return (DocumentDeserializerFactory)piPluginFactory;
+ }
+
+
+ /**
+ * Returns an instance of the DocumentMergerFactory interface.
+ *
+ * @return instance of the DocumentMergerFactory for this ConverterInfo.
+ */
+ public DocumentMergerFactory getDocMergerFactory() {
+ return (DocumentMergerFactory)piPluginFactory;
+ }
+
+
+ /**
+ * Returns the jar file name.
+ *
+ * @return The jar file name, null if none exists.
+ */
+ public String getJarName() {
+ return piJarName;
+ }
+
+
+ /**
+ * Returns the office mime-type.
+ *
+ * @return The office mime-type, null if none exists.
+ */
+ public String getOfficeMime() {
+ return piOfficeMime;
+ }
+
+
+ /**
+ * Returns an <code>Enumeration</code> of <code>String</code>
+ * objects indicating the device mime-type.
+ *
+ * @return An <code>Enumeration</code> of <code>String</code>
+ * objects indicating the device mime-type.
+ */
+ public Enumeration getDeviceMime() {
+ return(piDeviceMime.elements());
+ }
+
+
+ /**
+ * Returns the display name.
+ *
+ * @return The display name, null if none exists.
+ */
+ public String getDisplayName() {
+ return piDisplayName;
+ }
+
+
+ /**
+ * Returns the description.
+ *
+ * @return The description, null if none exists.
+ */
+ public String getDescription() {
+ return piDescription;
+ }
+
+
+ /**
+ * Returns the version.
+ *
+ * @return The version, null if none exists.
+ */
+ public String getVersion() {
+ return piVersion;
+ }
+
+
+ /**
+ * Returns the vendor name.
+ *
+ * @return The vendor name, null if none exists.
+ */
+ public String getVendor() {
+ return piVendor;
+ }
+
+
+ /**
+ * Returns the implementation class name of PluginFactory.
+ *
+ * @return The implementation class name of PluginFactory,
+ * null if none exists.
+ */
+ public String getClassImpl() {
+ return piClassImpl;
+ }
+
+
+ /**
+ * Returns the PluginFactory instance for this plug-in.
+ *
+ * @return The PluginFactory instance for this plug-in.
+ */
+ public PluginFactory getPluginFactory() {
+ return piPluginFactory;
+ }
+
+
+ /**
+ * Returns true if this plug-in has a serializier, false otherwise.
+ *
+ * @return true if this plug-in has a serializier, false otherwise.
+ */
+ public boolean canSerialize() {
+ return piCanSerialize;
+ }
+
+
+ /**
+ * Returns true if this plug-in has a deserializier, false otherwise.
+ *
+ * @return true if this plug-in has a deserializier, false otherwise.
+ */
+ public boolean canDeserialize() {
+ return piCanDeserialize;
+ }
+
+
+ /**
+ * Returns true if this plug-in has a merger, false otherwise.
+ *
+ * @return true if this plug-in has a merger, false otherwise.
+ */
+ public boolean canMerge() {
+ return piCanMerge;
+ }
+
+
+ /**
+ * Returns true if the officeMime is a valid Office mime type.
+ *
+ * @return true if the officeMime is a valid Office mime type.
+ */
+ public static boolean isValidOfficeType(String officeMime) {
+
+ boolean rc = false;
+ for (int i=0; i < validOfficeTypes.length; i++) {
+ if (officeMime.equals(validOfficeTypes[i])) {
+ rc = true;
+ }
+ }
+
+ return rc;
+ }
+
+ /**
+ * Returns a <code>String</code> containing the Xslt stylesheet url that
+ * is to be used by the Xslt Plugin Serializer.
+ *
+ * @return <code>String</code>
+ */
+
+ public String getXsltSerial() {
+ return piXsltSerial;
+ }
+
+ /**
+ * Returns a <code>String</code> containing the xslt stylesheet url that
+ * is to be used by the Xslt Plugin Deserializer.
+ *
+ * @return <code>String</code>
+ */
+
+ public String getXsltDeserial() {
+ return piXsltDeserial;
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoMgr.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoMgr.java
new file mode 100644
index 000000000000..b94a7085724c
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoMgr.java
@@ -0,0 +1,526 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util.registry;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Manages the converter plug-ins that are currently active.
+ * This class allows plug-ins to be added or removed dynamically.
+ * This class is a singleton (static) class, so that only one
+ * manager can exist at a time. It is final, so it may not be
+ * subclassed.
+ *
+ * @author Brian Cameron
+ */
+public final class ConverterInfoMgr {
+
+ private static Vector converterInfoList;
+
+ /**
+ * Constructor
+ */
+ static {
+ converterInfoList = new Vector();
+ }
+
+ /**
+ * Adds a converter plug-in to the registry. The
+ * <code>ConverterInfo</code> must have a unique DisplayName
+ * and must have non-null values for DisplayName, ClassImpl,
+ * OfficeMime, and DeviceMime.
+ *
+ * @param ci A <code>ConverterInfo</code> object describing a plug-in.
+ *
+ * @throws RegistryException If the <code>ConverterInfo</code>
+ * is not valid.
+ */
+ public static void addPlugIn(ConverterInfo ci) throws RegistryException {
+
+ ConverterInfo converterInfo;
+
+ // Validate
+ //
+ if (ci.getDisplayName() == null) {
+ RegistryException re = new RegistryException(
+ "Converter must have valid name.");
+ throw re;
+ }
+ if (ci.getClassImpl() == null) {
+ RegistryException re = new RegistryException(
+ "Converter must have valid class implementation specified.");
+ throw re;
+ }
+ if (ci.getOfficeMime() == null) {
+ RegistryException re = new RegistryException(
+ "Converter must have valid office mime specified.");
+ throw re;
+ }
+ if (! ci.getDeviceMime().hasMoreElements()) {
+ RegistryException re = new RegistryException(
+ "Converter must have valid device mime specified.");
+ throw re;
+ }
+
+ // Verify there is no converter with the same Display Name in
+ // the registry.
+ //
+ Enumeration ciEnum = converterInfoList.elements();
+ while (ciEnum.hasMoreElements()) {
+ converterInfo = (ConverterInfo)ciEnum.nextElement();
+ if (ci.getDisplayName().equals(converterInfo.getDisplayName())) {
+ RegistryException re = new RegistryException(
+ "Converter with specified display name already exists.");
+ throw re;
+ }
+ }
+
+ // Since this is a adding to a static Vector, make sure this
+ // add method call is synchronized.
+ //
+ synchronized (converterInfoList) {
+ converterInfoList.add(ci);
+ }
+ }
+
+ /**
+ * Adds a list of converter plug-ins to the registry.
+ * Each <code>ConverterInfo</code> in the list must have
+ * a unique DisplayName and must have non-null values for DisplayName,
+ * ClassImpl, OfficeMime, and DeviceMime.
+ *
+ * @param jarEnum An <code>Enumeration</code> of <code>ConverterInfo</code>
+ * objects describing one or more plug-in(s).
+ *
+ * @throws RegistryException If a <code>ConverterInfo</code> in the
+ * <code>Vector</code> is not valid.
+ */
+ public static void addPlugIn(Enumeration jarEnum) throws RegistryException {
+
+ while (jarEnum.hasMoreElements()) {
+ ConverterInfo converterInfo = (ConverterInfo)jarEnum.nextElement();
+ addPlugIn(converterInfo);
+ }
+ }
+
+ /**
+ * Returns an <code>Enumeration</code> of registered
+ * <code>ConverterInfo</code> objects.
+ *
+ * @return An <code>Enumeration</code> containing the currently registered
+ * <code>ConverterInfo</code> objects, an empty
+ * <code>Vector</code> if none exist.
+ */
+ public static Enumeration getConverterInfoEnumeration() {
+ return (converterInfoList.elements());
+ }
+
+ /**
+ * Removes any <code>ConverterInfo</code> object from the registry
+ * that have the specified jar name value.
+ *
+ * @param jar The name of the jarfile.
+ *
+ * @return True if a <code>ConverterInfo</code> object was
+ * removed, false otherwise.
+ */
+ public static boolean removeByJar(String jar) {
+
+ ConverterInfo converterInfo;
+ boolean rc = false;
+
+ // FIX (HJ): Has to use an iterator, since we are removing items
+ /*Enumeration ciEnum = converterInfoList.elements();
+ while (ciEnum.hasMoreElements())
+ {
+ converterInfo = (ConverterInfo)ciEnum.nextElement();
+ if (jar.equals(converterInfo.getJarName())) {
+ converterInfoList.remove(converterInfo);
+ rc = true;
+ }
+ }*/
+
+ Iterator ciIter = converterInfoList.iterator();
+ while (ciIter.hasNext())
+ {
+ converterInfo = (ConverterInfo)ciIter.next();
+ if (jar.equals(converterInfo.getJarName())) {
+ ciIter.remove();
+ rc = true;
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Removes any <code>ConverterInfo</code> object from the registry
+ * that have the specified display name value.
+ *
+ * @param name The display name.
+ *
+ * @return True if a <code>ConverterInfo</code> object was
+ * removed, false otherwise.
+ */
+ public static boolean removeByName(String name) {
+
+ ConverterInfo converterInfo;
+ boolean rc = false;
+
+ Enumeration ciEnum = converterInfoList.elements();
+ while (ciEnum.hasMoreElements())
+ {
+ converterInfo = (ConverterInfo)ciEnum.nextElement();
+ if (name.equals(converterInfo.getDisplayName())) {
+ converterInfoList.remove(converterInfo);
+ rc = true;
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Returns the <code>ConverterInfo</code> object that supports
+ * the specified device/office mime type conversion. If there
+ * are multiple <code>ConverterInfo</code> objects registered
+ * that support this conversion, only the first is returned.
+ *
+ * @param deviceMime The device mime.
+ * @param officeMime The office mime.
+ *
+ * @return The first plug-in that supports the specified
+ * conversion.
+ */
+ public static ConverterInfo findConverterInfo(String deviceMime, String officeMime) {
+
+ ConverterInfo converterInfo;
+
+ if (deviceMime == null ||
+ ConverterInfo.isValidOfficeType(officeMime) == false) {
+ return null;
+ }
+
+ // Loop over elements comparing with deviceFromMime
+ //
+ Enumeration ciEnum = converterInfoList.elements();
+ while (ciEnum.hasMoreElements()) {
+
+ converterInfo = (ConverterInfo)ciEnum.nextElement();
+ String toDeviceInfo = (String)converterInfo.getOfficeMime();
+ Enumeration fromEnum = converterInfo.getDeviceMime();
+
+ // Loop over the deviceMime types.
+ //
+ while (fromEnum.hasMoreElements()) {
+ String fromDeviceInfo = (String)fromEnum.nextElement();
+ if (deviceMime.trim().equals(fromDeviceInfo) &&
+ officeMime.trim().equals(toDeviceInfo)) {
+ return (converterInfo);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an array of two <code>ConverterInfo</code> objects that
+ * can be chained to perform the specified mime type conversion.
+ * If there are multiple <code>ConverterInfo</code> objects that
+ * support this conversion, only the first is returned.
+ *
+ * @param deviceFromMime The device from mime.
+ * @param deviceToMime The device to mime.
+ *
+ * @return An array of two <code>ConverterInfo</code> objects
+ * that can be chained to perform the specified
+ * conversion.
+ */
+ public static ConverterInfo[] findConverterInfoChain(String deviceFromMime, String deviceToMime) {
+
+ if (deviceFromMime == null || deviceToMime == null) {
+ return null;
+ }
+
+ ConverterInfo[] converterInfo = new ConverterInfo[2];
+
+ // Loop over elements comparing with deviceFromMime
+ //
+ Enumeration cifEnum = converterInfoList.elements();
+ while (cifEnum.hasMoreElements()) {
+
+ converterInfo[0] = (ConverterInfo)cifEnum.nextElement();
+ String fromOfficeInfo = converterInfo[0].getOfficeMime();
+ Enumeration fromEnum = converterInfo[0].getDeviceMime();
+
+ // Loop over the deviceMime types looking for a deviceFromMime
+ // match.
+ //
+ while (fromEnum.hasMoreElements()) {
+ String fromDeviceInfo = (String)fromEnum.nextElement();
+
+ if (deviceFromMime.trim().equals(fromDeviceInfo)) {
+
+ // Found a a match for deviceFrom. Now loop over the
+ // elements comparing with deviceToMime
+ //
+ Enumeration citEnum = converterInfoList.elements();
+ while (citEnum.hasMoreElements()) {
+
+ converterInfo[1] = (ConverterInfo)citEnum.nextElement();
+ String toOfficeInfo = converterInfo[1].getOfficeMime();
+ Enumeration toEnum = converterInfo[1].getDeviceMime();
+
+ // Loop over deviceMime types looking for a
+ // deviceToMime match.
+ //
+ while (toEnum.hasMoreElements()) {
+ String toDeviceInfo = (String)toEnum.nextElement();
+ if (deviceToMime.trim().equals(toDeviceInfo) &&
+ fromOfficeInfo.equals(toOfficeInfo)) {
+
+ // Found a match
+ //
+ return (converterInfo);
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * main to let the user specify what plug-ins to register from
+ * jarfiles and to display the currently registered plug-ins.
+ *
+ * @param args Not used.
+ */
+ public static void main(String args[]) {
+
+ ConverterInfoReader cir = null;
+ boolean validate = false;
+ InputStreamReader isr = new InputStreamReader(System.in);
+ BufferedReader br = new BufferedReader(isr);
+ char c = ' ';
+
+ boolean exitFlag = false;
+ while (exitFlag == false) {
+
+ System.out.println("\nMenu:");
+ System.out.println("(L)oad plug-ins from a jar file");
+ System.out.println("(D)isplay name unload");
+ System.out.println("(J)ar name unload");
+ System.out.println("(F)ind ConverterInfo");
+ System.out.println("(C)ind ConverterInfo chain");
+ System.out.println("(V)iew plug-ins");
+ System.out.println("(T)oggle Validation");
+ System.out.println("(Q)uit\n");
+
+ try {
+ c = br.readLine().toUpperCase().trim().charAt(0);
+ } catch(Exception e) {
+ System.out.println("Invalid entry");
+ System.out.println("Error msg: " + e.getMessage());
+ continue;
+ }
+
+ System.out.println("");
+
+ // Quit
+ //
+ if (c == 'Q') {
+ exitFlag = true;
+
+ // Load by Jarfile
+ //
+ } else if (c == 'L') {
+
+ System.out.println("Enter path to jarfile: ");
+ try {
+ String jarname = br.readLine().trim();
+ cir = new ConverterInfoReader(jarname,validate);
+ } catch (RegistryException e) {
+ System.out.println("Cannot load plug-in ConverterFactory implementation.");
+ System.out.println("Error msg: " + e.getMessage());
+ } catch (Exception e) {
+ System.out.println("Error adding data to registry");
+ System.out.println("Error msg: " + e.getMessage());
+ }
+
+ if (cir != null) {
+ Enumeration jarInfoEnum = cir.getConverterInfoEnumeration();
+ try {
+ ConverterInfoMgr.addPlugIn(jarInfoEnum);
+ } catch (Exception e) {
+ System.out.println("Error adding data to registry");
+ System.out.println("Error msg: " + e.getMessage());
+ }
+ }
+
+ // Unload by Display Name or Jarfile
+ //
+ } else if (c == 'T') {
+ if (validate== true){
+ System.out.println("Validation switched off");
+ validate=false;
+ }else{
+ System.out.println("Validation switched on");
+ validate=true;
+ }
+ } else if (c == 'D' || c == 'J') {
+
+ if (c == 'D') {
+ System.out.println("Enter display name: ");
+ } else {
+ System.out.println("Enter path to jarfile: ");
+ }
+
+ try
+ {
+ String name = br.readLine().trim();
+ boolean rc = false;
+
+ if (c == 'D') {
+ rc = ConverterInfoMgr.removeByName(name);
+ } else {
+ rc = ConverterInfoMgr.removeByJar(name);
+ }
+
+ if (rc == true) {
+ System.out.println("Remove successful.");
+ } else {
+ System.out.println("Remove failed.");
+ }
+
+ } catch (Exception e) {
+ System.out.println("Error removing value from registry");
+ System.out.println("Error msg: " + e.getMessage());
+ }
+
+ // Find Office Mime
+ //
+ } else if (c == 'F' || c == 'C') {
+
+ String findMimeOne = null;
+ String findMimeTwo = null;
+
+ if (c == 'F') {
+ System.out.println("Enter device mime: ");
+ } else {
+ System.out.println("Enter device from mime: ");
+ }
+
+ try {
+ findMimeOne = br.readLine().trim();
+ } catch (Exception e) {
+ System.out.println("Error adding data to registry");
+ System.out.println("Error msg: " + e.getMessage());
+ }
+
+ if (c == 'F') {
+ System.out.println("Enter office mime: ");
+ } else {
+ System.out.println("Enter device to mime: ");
+ }
+
+ try {
+ findMimeTwo = br.readLine().trim();
+ } catch (Exception e) {
+ System.out.println("Error adding data to registry");
+ System.out.println("Error msg: " + e.getMessage());
+ }
+
+ if (c == 'F') {
+ ConverterInfo foundInfo = ConverterInfoMgr.findConverterInfo(findMimeOne, findMimeTwo);
+ if (foundInfo != null) {
+ System.out.println(" Found ConverterInfo");
+ System.out.println(" DisplayName : " + foundInfo.getDisplayName());
+ } else {
+ System.out.println(" Did not find ConverterInfo");
+ }
+ } else {
+ ConverterInfo[] foundInfo = ConverterInfoMgr.findConverterInfoChain(findMimeOne,
+ findMimeTwo);
+ if (foundInfo[0] != null && foundInfo[1] != null ) {
+ System.out.println(" Found ConverterInfo Chain");
+ System.out.println(" DisplayName : " + foundInfo[0].getDisplayName());
+ System.out.println(" DisplayName : " + foundInfo[1].getDisplayName());
+ } else {
+ System.out.println(" Did not find ConverterInfo");
+ }
+ }
+
+ // View
+ //
+ } else if (c == 'V') {
+
+ Enumeration ciEnum = ConverterInfoMgr.getConverterInfoEnumeration();
+
+ int ciCnt = 0;
+ while (ciEnum.hasMoreElements())
+ {
+ System.out.println("");
+ System.out.println(" Displaying converter number " + ciCnt);
+ ConverterInfo converterInfo = (ConverterInfo)ciEnum.nextElement();
+ System.out.println(" DisplayName : " + converterInfo.getDisplayName());
+ System.out.println(" JarFile : " + converterInfo.getJarName());
+ System.out.println(" Description : " + converterInfo.getDescription());
+ System.out.println(" Version : " + converterInfo.getVersion());
+ System.out.println(" OfficeMime : " + converterInfo.getOfficeMime());
+ Enumeration fromEnum = converterInfo.getDeviceMime();
+ int feCnt = 1;
+ while (fromEnum.hasMoreElements())
+ {
+ System.out.println(" DeviceMime : (#" + feCnt + ") : " +
+ (String)fromEnum.nextElement());
+ feCnt++;
+ }
+ if (feCnt == 1) {
+ System.out.println(" DeviceMime : None specified");
+ }
+
+ System.out.println(" Vendor : " + converterInfo.getVendor());
+ System.out.println(" ClassImpl : " + converterInfo.getClassImpl());
+ System.out.println(" XsltSerial : " + converterInfo.getXsltSerial());
+ System.out.println(" XsltDeserial : " + converterInfo.getXsltDeserial());
+ System.out.println(" Serialize : " + converterInfo.canSerialize());
+ System.out.println(" Deserialize : " + converterInfo.canDeserialize());
+ System.out.println(" Merge : " + converterInfo.canMerge());
+ ciCnt++;
+ }
+
+ if (ciCnt == 0) {
+ System.out.println("No converters registered");
+ }
+ } else {
+ System.out.println("Invalid input");
+ }
+ }
+ }
+}
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoReader.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoReader.java
new file mode 100644
index 000000000000..238fd59f9608
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/ConverterInfoReader.java
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util.registry;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.parsers.*;
+import java.net.URL;
+import java.net.JarURLConnection;
+
+/**
+ * The <code>ConverterInfoReader</code> pulls a META-INF/converter.xml
+ * file out of a jar file and parses it, providing access to this
+ * information in a <code>Vector</code> of <code>ConverterInfo</code>
+ * objects.
+ *
+ * @author Brian Cameron
+ */
+public class ConverterInfoReader {
+
+ private final static String TAG_CONVERTER = "converter";
+ private final static String ATTRIB_OFFICE_TYPE = "type";
+ private final static String ATTRIB_VERSION = "version";
+ private final static String TAG_NAME = "converter-display-name";
+ private final static String TAG_DESC = "converter-description";
+ private final static String TAG_VENDOR = "converter-vendor";
+ private final static String TAG_CLASS_IMPL = "converter-class-impl";
+ private final static String TAG_TARGET = "converter-target";
+ private final static String ATTRIB_DEVICE_TYPE = "type";
+ private final static String TAG_XSLT_DESERIAL = "converter-xslt-deserialize";
+ private final static String TAG_XSLT_SERIAL = "converter-xslt-serialize";
+ private String jarfilename;
+ private Document document;
+ private Vector converterInfoList;
+
+
+ /**
+ * Constructor. A jar file is passed in. The jar file is
+ * parsed and the <code>Vector</code> of <code>ConverterInfo</code>
+ * objects is built.
+ *
+ * @param jar The URL of the jar file to process.
+ * @param shouldvalidate Boolean to enable or disable xml validation.
+ *
+ * @throws IOException If the jar file cannot
+ * be read or if the
+ * META-INF/converter.xml
+ * can not be read in the
+ * jar file.
+ * @throws ParserConfigurationException If the DocumentBuilder
+ * can not be built.
+ * @throws org.xml.sax.SAXException If the converter.xml
+ * file can not be parsed.
+ * @throws RegistryException If the ConverterFactory
+ * implementation of a
+ * plug-in cannot be loaded.
+ */
+ public ConverterInfoReader(String jar,boolean shouldvalidate) throws IOException,
+ ParserConfigurationException, org.xml.sax.SAXException,
+ RegistryException {
+
+ InputStream istream;
+ InputSource isource;
+ DocumentBuilderFactory builderFactory;
+ DocumentBuilder builder;
+ JarURLConnection jarConnection;
+ JarEntry jarentry;
+ JarFile jarfile;
+ URL url;
+
+ converterInfoList = new Vector();
+ jarfilename = jar;
+
+ // Get Jar via URL
+ //
+ url = new URL("jar:" + jar + "!/META-INF/converter.xml");
+ jarConnection = (JarURLConnection)url.openConnection();
+ jarentry = jarConnection.getJarEntry();
+ jarfile = jarConnection.getJarFile();
+
+ // Build the InputSource
+ //
+ istream = jarfile.getInputStream(jarentry);
+ isource = new InputSource(istream);
+
+ // Get the DOM builder and build the document.
+ //
+ builderFactory = DocumentBuilderFactory.newInstance();
+
+ //DTD validation
+ if (shouldvalidate){
+ System.out.println("Validating xml...");
+ builderFactory.setValidating(true);
+ }
+ //
+ builder = builderFactory.newDocumentBuilder();
+ document = builder.parse(isource);
+
+ // Parse the document.
+ //
+ parseDocument();
+ }
+
+
+ /**
+ * Loops over the <i>converter</i> <code>Node</code> in the converter.xml
+ * file and processes them.
+ *
+ * @throws RegistryException If the plug-in associated with a
+ * specific <i>converter</i> <code>Node</code>
+ * cannot be loaded.
+ */
+ private void parseDocument() throws RegistryException {
+
+ Node converterNode;
+ NodeList converterNodes = document.getElementsByTagName(TAG_CONVERTER);
+
+ for (int i=0; i < converterNodes.getLength(); i++) {
+ converterNode = converterNodes.item(i);
+ if (converterNode.getNodeType() == Node.ELEMENT_NODE) {
+ parseConverterNode((Element)converterNode);
+ }
+ }
+ }
+
+
+ /**
+ * Parses a <i>converter</i> node, pulling the information out of
+ * the <code>Node</code> and placing it in a <code>ConverterInfo</code>
+ * object, and adds that object to a <code>Vector</code> of
+ * <code>ConverterInfo</code> objects.
+ *
+ * @param e The <code>Element</code> corresponding to the
+ * <i>converter</i> XML tag.
+ *
+ *
+ * @throws RegistryException If the plug-in cannot be loaded.
+ */
+ private void parseConverterNode(Element e) throws RegistryException {
+
+ Element detailElement;
+ Node detailNode;
+ String elementTagName;
+ String officeMime = null;
+ Vector deviceMime = new Vector();
+ String name = null;
+ String desc = null;
+ String version = null;
+ String vendor = null;
+ String classImpl = null;
+ String xsltSerial = null;
+ String xsltDeserial= null;
+ String temp;
+
+ temp = e.getAttribute(ATTRIB_OFFICE_TYPE);
+ if (temp.length() != 0) {
+ officeMime = temp;
+ }
+
+ temp = e.getAttribute(ATTRIB_VERSION);
+ if (temp.length() != 0) {
+ version = temp;
+ }
+
+ NodeList detailNodes = e.getChildNodes();
+ for (int i=0; i < detailNodes.getLength(); i++) {
+
+ detailNode = detailNodes.item(i);
+ if (detailNode.getNodeType() == Node.ELEMENT_NODE) {
+
+ detailElement = (Element)detailNode;
+ elementTagName = detailElement.getTagName();
+
+ if (TAG_NAME.equalsIgnoreCase(elementTagName)) {
+ name = getTextValue(detailElement);
+ } else if (TAG_DESC.equalsIgnoreCase(elementTagName)) {
+ desc = getTextValue(detailElement);
+ } else if (TAG_VENDOR.equalsIgnoreCase(elementTagName)) {
+ vendor = getTextValue(detailElement);
+ } else if (TAG_XSLT_SERIAL.equalsIgnoreCase(elementTagName)) {
+ xsltSerial = getTextValue(detailElement);
+ } else if (TAG_XSLT_DESERIAL.equalsIgnoreCase(elementTagName)) {
+ xsltDeserial = getTextValue(detailElement);
+ } else if (TAG_CLASS_IMPL.equalsIgnoreCase(elementTagName)) {
+ classImpl = getTextValue(detailElement);
+ } else if (TAG_TARGET.equalsIgnoreCase(elementTagName)) {
+
+ temp = detailElement.getAttribute(ATTRIB_DEVICE_TYPE);
+ if (temp.length() != 0) {
+ deviceMime.add(temp);
+ }
+ }
+ }
+ }
+ ConverterInfo converterInfo;
+ if ((xsltSerial==null) || (xsltDeserial==null)){
+ converterInfo = new ConverterInfo(jarfilename,
+ officeMime, deviceMime, name,
+ desc, version, vendor,classImpl);
+ }
+ else{
+ converterInfo = new ConverterInfo(jarfilename,
+ officeMime, deviceMime, name,
+ desc, version, vendor,classImpl,
+ xsltSerial,xsltDeserial);
+ }
+ /*ConverterInfo converterInfo = new ConverterInfo(jarfilename,
+ officeMime, deviceMime, name, desc, version, vendor,
+ classImpl);*/
+ converterInfoList.add(converterInfo);
+ }
+
+
+ /**
+ * Helper function to get the text value of an
+ * <code>Element</code>.
+ *
+ * @param e The <code>Element</code> to process.
+ *
+ * @return The text value of the <code>Element</code>.
+ */
+ private String getTextValue(Element e) {
+
+ NodeList tempNodes = e.getChildNodes();
+ String text = null;
+ Node tempNode;
+
+ for (int j=0; j < tempNodes.getLength(); j++) {
+ tempNode = tempNodes.item(j);
+ if (tempNode.getNodeType() == Node.TEXT_NODE) {
+ text = tempNode.getNodeValue().trim();
+ break;
+ }
+ }
+
+ return text;
+ }
+
+
+ /**
+ * Returns an <code>Enumeration</code> of <code>ConverterInfo</code>
+ * objects.
+ *
+ * @return An <code>Enumeration</code> of <code>ConverterInfo</code>
+ * objects.
+ */
+ public Enumeration getConverterInfoEnumeration() {
+ return (converterInfoList.elements());
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/RegistryException.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/RegistryException.java
new file mode 100644
index 000000000000..ea370d386c1c
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/RegistryException.java
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.util.registry;
+
+/**
+ * This <code>Exception</code> is thrown by converter registry
+ * algorithms.
+ */
+public class RegistryException extends Exception {
+
+
+ /**
+ * Exception thrown by merge algorithms.
+ *
+ * @param message Message to be included in the
+ * <code>Exception</code>.
+ */
+ public RegistryException(String message) {
+ super(message);
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/build.xml b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/build.xml
new file mode 100644
index 000000000000..525546d2f7fc
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/build.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ #*************************************************************************
+ #
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ Copyright 2000, 2010 Oracle and/or its affiliates.
+
+ OpenOffice.org - a multi-platform office productivity suite
+
+ 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_jooxu_registry" 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_jooxu_registry"/>
+
+ <!-- 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/util/registry"/>
+
+ <!-- define how to handle CLASSPATH environment -->
+ <property name="build.sysclasspath" value="ignore"/>
+
+ <property environment="env"/>
+ <property name="env.XML_APIS_JAR" value="${solar.jar}/xml-apis.jar"/>
+ <property name="env.XERCES_JAR" value="${solar.jar}/xercesImpl.jar"/>
+
+ <!-- classpath settings for javac tasks -->
+ <path id="classpath">
+ <pathelement location="${build.class}"/>
+ <pathelement location="${env.XML_APIS_JAR}"/>
+ <pathelement location="${env.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}/ConverterInfo.java"/>
+ <include name="${package}/ConverterInfoMgr.java"/>
+ <include name="${package}/ConverterInfoReader.java"/>
+ <include name="${package}/RegistryException.java"/>
+ <include name="${package}/UnoBridgeConverterInfo.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/source/xmerge/java/org/openoffice/xmerge/util/registry/package.html b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/package.html
new file mode 100644
index 000000000000..b6af6262cc5c
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/registry/package.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+ #*************************************************************************
+ #
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ Copyright 2000, 2010 Oracle and/or its affiliates.
+
+ OpenOffice.org - a multi-platform office productivity suite
+
+ 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.registry package</title>
+</head>
+
+<body bgcolor="white">
+
+<p>Provides an interface for plug-in registration. Each plug-in must
+have a corresponding Plugin Configuration XML File which is named
+converter.xml. If the plug-in is stored in a jarfile, this
+converter.xml file is typically stored in the following location in
+the jarfile:</p>
+
+<blockquote>
+ META-INF/converter.xml
+</blockquote>
+
+<p>The Plugin Configuration XML File must validate against the
+converter.dtd file provided with this package. Since a jarfile
+can contain multiple plug-ins, this DTD supports specifying multiple
+plug-ins per jarfile. Please refer to the SDK document for more
+information about how to implement a Plugin Configuration XML File
+for a specific plugin.</p>
+
+<p>All information in the Plugin Configuratino XML File is bundled
+into one or more <code>ConverterInfo</code> object. The
+<code>ConverterInfoReader</code> object is used to build a
+<code>Vector</code> of <code>ConverterInfo</code> objects from a
+jarfile.</p>
+
+<p>The <code>ConverterInfoMgr</code> manages the registry of
+<code>ConverterInfo</code>. It is a singleton class, so that only one
+registry manager will ever exist. It is the client program's
+responsibility to register <code>ConverterInfo</code> objects that
+correspond to the plug-ins that are to be used.</p>
+
+<h2>TODO/IDEAS list</h2>
+
+<p><ol>
+<li>The <code>ConverterInfo</code> object could contain
+ <code>org.w3c.dom.Document</code> fragments that are accessed in a
+ generic fashion rather than get/set methods for each item in the DTD.
+ This would provide a more flexible approach, especially for adding
+ custom tags to a specific Plugin Configuration XML file (tags that
+ are only used by its associated plug-in).
+<li><code>ConverterInfo</code> should allow the merge/serialize/deserialize
+ logic to be included in separate plug-ins, if desired.</li>
+<li><code>ConverterInfoMgr</code> could use the Java Activation
+ Framework (JAF) to manage registration.</li>
+</ol></p>
+
+</body>
+</html>
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/resources.properties b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/resources.properties
new file mode 100644
index 000000000000..99e6ccae2645
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/resources.properties
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# 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.
+#
+#*************************************************************************
+# x-no-translate
+
+
+#
+# resources.properties
+#
+# resources for org.openoffice.xmerge.converter package.
+#
+NULL_MIME_EXCEPTION=Cannot specify null MIME types
+EMPTY_MIME_EXCEPTION=Cannot specify empty MIME types
+CANNOT_LOAD_CLASS=Unable to load class
+CANNOT_INST_CLASS=Unable to instantiate class
+NOT_AN_INSTANCE= is not an instance of
+CANNOT_FIND_REGISTERED=Cannot find registered class
+PARSE_ERROR=Parse Error
+LINE=Line
+COLUMN=Column
+PUBLIC_ID=PublicId
+SYSTEM_ID=SystemId
+INVALID_LOG_LEVEL=Invalid log level specified
+OPERATION_NOT_SUPPORTED=Operation not supported
+TEMPLATE_FILE_LOAD_ERROR=Error in loading template file -
+
+#
+# diff/merge algorithm erro messages
+#
+EMPTY_NODE_EXCEPTION=Current Node is empty
+NOT_LEAFNODE_EXCEPTION=Current Node is not a leaf node
+ROOTNODE_EXCEPTION=Cannot perform insert/append/remove on root node
+NOT_TEXTNODE_EXCEPTION=The target Node is not a TEXT_NODE, it is -
+NULL_NODE_EXCEPTION=The initial Xmldocument node is null
+CELL_NODE_EXCEPTION1=Cell node do not have only 1 child <text:p> nodes, will skip the merge of this node.Num of PARA child nodes:
+CELL_NODE_EXCEPTION2=Cell node have a non Element child nodes -
+CELL_NODE_EXCEPTION2=There is a child node under an expected empty cell node.
+NOT_ELEM_NODE_ERROR=The compared nodes are not a Element Node
+NOT_PARA_NODE_ERROR=The compared nodes are not a Paragraph or Heading node -
+NOT_NODE_ERROR=The compared nodes are not a Node
+#
+# SXW to/from DOC conversion error messages.
+#
+UNKNOWN_DOC_VERSION=Unknown DOC version.
+DOC_TEXT_LENGTH_EXCEEDED=DOC text length exceeds maximum value.
+DOC_TEXT_RECORD_SIZE_EXCEEDED=DOC text record exceeds size limit.