001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.content.openoffice;
019:
020: import java.io.ByteArrayOutputStream;
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.FileOutputStream;
024: import java.io.IOException;
025: import java.io.FileNotFoundException;
026: import java.util.Map;
027: import java.util.Random;
028: import java.sql.Timestamp;
029: import java.lang.Math;
030: import java.net.MalformedURLException;
031:
032: import org.ofbiz.base.util.Debug;
033: import org.ofbiz.base.util.UtilValidate;
034: import org.ofbiz.base.util.UtilDateTime;
035: import org.ofbiz.base.util.UtilProperties;
036: import org.ofbiz.entity.util.ByteWrapper;
037: import org.ofbiz.entity.GenericDelegator;
038: import org.ofbiz.service.DispatchContext;
039: import org.ofbiz.service.ServiceUtil;
040:
041: import com.sun.star.beans.PropertyValue;
042: import com.sun.star.beans.XPropertySet;
043: import com.sun.star.frame.XComponentLoader;
044: import com.sun.star.frame.XDesktop;
045: import com.sun.star.frame.XDispatchHelper;
046: import com.sun.star.frame.XDispatchProvider;
047: import com.sun.star.frame.XFrame;
048: import com.sun.star.frame.XStorable;
049: import com.sun.star.lang.XComponent;
050: import com.sun.star.lang.XMultiComponentFactory;
051: import com.sun.star.uno.UnoRuntime;
052: import com.sun.star.uno.XComponentContext;
053:
054: /**
055: * OpenOfficeServices Class
056: */
057: public class OpenOfficeServices {
058: public static final String module = OpenOfficeServices.class
059: .getName();
060:
061: /**
062: * Use OpenOffice to convert documents between types
063: * This service requires that the "content.temp.dir" directory be set in the content.properties file.
064: * This value should be operating system dependent with "\\" separators for Windows
065: * and "/" for Linux/Unix.
066: */
067: public static Map convertDocumentByteWrapper(DispatchContext dctx,
068: Map context) {
069:
070: Map results = ServiceUtil.returnSuccess();
071: GenericDelegator delegator = dctx.getDelegator();
072: XMultiComponentFactory xmulticomponentfactory = null;
073: //String uniqueSeqNum = delegator.getNextSeqId("OOTempDir");
074: Timestamp ts = UtilDateTime.nowTimestamp();
075: Random random = new Random(ts.getTime());
076: String uniqueSeqNum = Integer.toString(Math.abs(random
077: .nextInt()));
078: String fileInName = "OOIN_" + uniqueSeqNum;
079: String fileOutName = "OOOUT_" + uniqueSeqNum;
080: File fileIn = null;
081: File fileOut = null;
082:
083: ByteWrapper inByteWrapper = (ByteWrapper) context
084: .get("inByteWrapper");
085: String inputMimeType = (String) context.get("inputMimeType");
086: String outputMimeType = (String) context.get("outputMimeType");
087: String extName = OpenOfficeWorker
088: .getExtensionFromMimeType(outputMimeType);
089: fileOutName += "." + extName;
090:
091: // if these are empty don't worry, the OpenOfficeWorker down below will take care of it
092: String oooHost = (String) context.get("oooHost");
093: String oooPort = (String) context.get("oooPort");
094:
095: try {
096: xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(
097: oooHost, oooPort);
098: byte[] inByteArray = inByteWrapper.getBytes();
099:
100: // The following line work in linux, but not Windows or Mac environment. It is preferred because it does not use temporary files
101: //OpenOfficeByteArrayInputStream oobais = new OpenOfficeByteArrayInputStream(inByteArray);
102: //Debug.logInfo("Doing convertDocumentByteWrapper, inBytes size is [" + inByteArray.length + "]", module);
103: //OpenOfficeByteArrayOutputStream baos = OpenOfficeWorker.convertOODocByteStreamToByteStream(xmulticomponentfactory, oobais, inputMimeType, outputMimeType);
104:
105: String tempDir = UtilProperties.getPropertyValue("content",
106: "content.temp.dir");
107: fileIn = new File(tempDir + fileInName);
108: FileOutputStream fos = new FileOutputStream(fileIn);
109: fos.write(inByteArray);
110: fos.close();
111: Debug.logInfo("fileIn:" + tempDir + fileInName, module);
112: OpenOfficeWorker.convertOODocToFile(xmulticomponentfactory,
113: tempDir + fileInName, tempDir + fileOutName,
114: outputMimeType);
115: fileOut = new File(tempDir + fileOutName);
116: FileInputStream fis = new FileInputStream(fileOut);
117: int c;
118: ByteArrayOutputStream baos = new ByteArrayOutputStream();
119: while ((c = fis.read()) > -1) {
120: baos.write(c);
121: }
122: fis.close();
123:
124: results.put("outByteWrapper", new ByteWrapper(baos
125: .toByteArray()));
126: baos.close();
127:
128: } catch (MalformedURLException e) {
129: Debug.logError(e, module);
130: return ServiceUtil.returnError(e.toString());
131: } catch (FileNotFoundException e) {
132: Debug
133: .logError(e, "Error in OpenOffice operation: ",
134: module);
135: return ServiceUtil.returnError(e.toString());
136: } catch (IOException e) {
137: Debug
138: .logError(e, "Error in OpenOffice operation: ",
139: module);
140: return ServiceUtil.returnError(e.toString());
141: } catch (Exception e) {
142: Debug
143: .logError(e, "Error in OpenOffice operation: ",
144: module);
145: return ServiceUtil.returnError(e.toString());
146: } finally {
147: if (fileIn != null)
148: fileIn.delete();
149: if (fileOut != null)
150: fileOut.delete();
151: }
152: return results;
153: }
154:
155: /**
156: * Use OpenOffice to convert documents between types
157: */
158: public static Map convertDocument(DispatchContext dctx, Map context) {
159: XMultiComponentFactory xmulticomponentfactory = null;
160:
161: String stringUrl = "file:///" + context.get("filenameFrom");
162: String stringConvertedFile = "file:///"
163: + context.get("filenameTo");
164: String filterName = "file:///" + context.get("filterName");
165:
166: // if these are empty don't worry, the OpenOfficeWorker down below will take care of it
167: String oooHost = (String) context.get("oooHost");
168: String oooPort = (String) context.get("oooPort");
169:
170: try {
171: xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(
172: oooHost, oooPort);
173: OpenOfficeWorker.convertOODocToFile(xmulticomponentfactory,
174: stringUrl, stringConvertedFile, filterName);
175:
176: Map results = ServiceUtil.returnSuccess();
177: return results;
178: } catch (IOException e) {
179: Debug
180: .logError(e, "Error in OpenOffice operation: ",
181: module);
182: return ServiceUtil.returnError(e.toString());
183: } catch (Exception e) {
184: Debug
185: .logError(e, "Error in OpenOffice operation: ",
186: module);
187: return ServiceUtil.returnError(e.toString());
188: }
189: }
190:
191: /**
192: * Use OpenOffice to convert documents between types
193: */
194: public static Map convertDocumentFileToFile(DispatchContext dctx,
195: Map context) {
196: XMultiComponentFactory xmulticomponentfactory = null;
197:
198: String stringUrl = (String) context.get("filenameFrom");
199: String stringConvertedFile = (String) context.get("filenameTo");
200: String inputMimeType = (String) context.get("inputMimeType");
201: String outputMimeType = (String) context.get("outputMimeType");
202:
203: // if these are empty don't worry, the OpenOfficeWorker down below will take care of it
204: String oooHost = (String) context.get("oooHost");
205: String oooPort = (String) context.get("oooPort");
206:
207: try {
208: xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(
209: oooHost, oooPort);
210: File inputFile = new File(stringUrl);
211: long fileSize = inputFile.length();
212: FileInputStream fis = new FileInputStream(inputFile);
213: ByteArrayOutputStream baos = new ByteArrayOutputStream(
214: (int) fileSize);
215: int c;
216: while ((c = fis.read()) != -1) {
217: baos.write(c);
218: }
219: OpenOfficeByteArrayInputStream oobais = new OpenOfficeByteArrayInputStream(
220: baos.toByteArray());
221: OpenOfficeByteArrayOutputStream oobaos = OpenOfficeWorker
222: .convertOODocByteStreamToByteStream(
223: xmulticomponentfactory, oobais,
224: inputMimeType, outputMimeType);
225: FileOutputStream fos = new FileOutputStream(
226: stringConvertedFile);
227: fos.write(oobaos.toByteArray());
228: fos.close();
229: fis.close();
230: oobais.close();
231: oobaos.close();
232:
233: Map results = ServiceUtil.returnSuccess();
234: return results;
235: } catch (IOException e) {
236: Debug
237: .logError(e, "Error in OpenOffice operation: ",
238: module);
239: return ServiceUtil.returnError(e.toString());
240: } catch (Exception e) {
241: Debug
242: .logError(e, "Error in OpenOffice operation: ",
243: module);
244: return ServiceUtil.returnError(e.toString());
245: }
246: }
247:
248: /**
249: * Use OpenOffice to convert documents between types
250: */
251: public static Map convertDocumentStreamToStream(
252: DispatchContext dctx, Map context) {
253: XMultiComponentFactory xmulticomponentfactory = null;
254:
255: String stringUrl = "file:///" + context.get("filenameFrom");
256: String stringConvertedFile = "file:///"
257: + context.get("filenameTo");
258: String inputMimeType = (String) context.get("inputMimeType");
259: String outputMimeType = (String) context.get("outputMimeType");
260:
261: // if these are empty don't worry, the OpenOfficeWorker down below will take care of it
262: String oooHost = (String) context.get("oooHost");
263: String oooPort = (String) context.get("oooPort");
264:
265: try {
266: xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(
267: oooHost, oooPort);
268: File inputFile = new File(stringUrl);
269: long fileSize = inputFile.length();
270: FileInputStream fis = new FileInputStream(inputFile);
271: ByteArrayOutputStream baos = new ByteArrayOutputStream(
272: (int) fileSize);
273: int c;
274: while ((c = fis.read()) != -1) {
275: baos.write(c);
276: }
277: OpenOfficeByteArrayInputStream oobais = new OpenOfficeByteArrayInputStream(
278: baos.toByteArray());
279: OpenOfficeByteArrayOutputStream oobaos = OpenOfficeWorker
280: .convertOODocByteStreamToByteStream(
281: xmulticomponentfactory, oobais,
282: inputMimeType, outputMimeType);
283: FileOutputStream fos = new FileOutputStream(
284: stringConvertedFile);
285: fos.write(oobaos.toByteArray());
286: fos.close();
287: fis.close();
288: oobais.close();
289: oobaos.close();
290:
291: Map results = ServiceUtil.returnSuccess();
292: return results;
293: } catch (IOException e) {
294: Debug
295: .logError(e, "Error in OpenOffice operation: ",
296: module);
297: return ServiceUtil.returnError(e.toString());
298: } catch (Exception e) {
299: Debug
300: .logError(e, "Error in OpenOffice operation: ",
301: module);
302: return ServiceUtil.returnError(e.toString());
303: }
304: }
305:
306: /**
307: * Use OpenOffice to compare documents
308: */
309: public static Map compareDocuments(DispatchContext dctx, Map context) {
310: XMultiComponentFactory xmulticomponentfactory = null;
311:
312: String stringUrl = "file:///" + context.get("filenameFrom");
313: String stringOriginalFile = "file:///"
314: + context.get("filenameOriginal");
315: String stringOutFile = "file:///" + context.get("filenameOut");
316:
317: // if these are empty don't worry, the OpenOfficeWorker down below will take care of it
318: String oooHost = (String) context.get("oooHost");
319: String oooPort = (String) context.get("oooPort");
320:
321: try {
322: xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(
323: oooHost, oooPort);
324: } catch (IOException e) {
325: Debug
326: .logError(e, "Error in OpenOffice operation: ",
327: module);
328: return ServiceUtil.returnError(e.toString());
329: } catch (Exception e) {
330: Debug
331: .logError(e, "Error in OpenOffice operation: ",
332: module);
333: return ServiceUtil.returnError(e.toString());
334: }
335: //System.out.println("xmulticomponentfactory: " + xmulticomponentfactory);
336:
337: // Converting the document to the favoured type
338: try {
339: // Composing the URL
340:
341: // Query for the XPropertySet interface.
342: XPropertySet xpropertysetMultiComponentFactory = (XPropertySet) UnoRuntime
343: .queryInterface(XPropertySet.class,
344: xmulticomponentfactory);
345:
346: // Get the default context from the office server.
347: Object objectDefaultContext = xpropertysetMultiComponentFactory
348: .getPropertyValue("DefaultContext");
349:
350: // Query for the interface XComponentContext.
351: XComponentContext xcomponentcontext = (XComponentContext) UnoRuntime
352: .queryInterface(XComponentContext.class,
353: objectDefaultContext);
354:
355: /* A desktop environment contains tasks with one or more
356: frames in which components can be loaded. Desktop is the
357: environment for components which can instanciate within
358: frames. */
359:
360: Object desktopObj = xmulticomponentfactory
361: .createInstanceWithContext(
362: "com.sun.star.frame.Desktop",
363: xcomponentcontext);
364: XDesktop desktop = (XDesktop) UnoRuntime.queryInterface(
365: XDesktop.class, desktopObj);
366: XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime
367: .queryInterface(XComponentLoader.class, desktopObj);
368:
369: // Preparing properties for loading the document
370: PropertyValue propertyvalue[] = new PropertyValue[1];
371: // Setting the flag for hidding the open document
372: propertyvalue[0] = new PropertyValue();
373: propertyvalue[0].Name = "Hidden";
374: propertyvalue[0].Value = new Boolean(true);
375: //TODO: Hardcoding opening word documents -- this will need to change.
376: //propertyvalue[ 1 ] = new PropertyValue();
377: //propertyvalue[ 1 ].Name = "FilterName";
378: //propertyvalue[ 1 ].Value = "HTML (StarWriter)";
379:
380: // Loading the wanted document
381: Object objectDocumentToStore = xcomponentloader
382: .loadComponentFromURL(stringUrl, "_blank", 0,
383: propertyvalue);
384:
385: // Getting an object that will offer a simple way to store a document to a URL.
386: XStorable xstorable = (XStorable) UnoRuntime
387: .queryInterface(XStorable.class,
388: objectDocumentToStore);
389:
390: // Preparing properties for comparing the document
391: propertyvalue = new PropertyValue[1];
392: // Setting the flag for overwriting
393: propertyvalue[0] = new PropertyValue();
394: propertyvalue[0].Name = "URL";
395: propertyvalue[0].Value = stringOriginalFile;
396: // Setting the filter name
397: //propertyvalue[ 1 ] = new PropertyValue();
398: //propertyvalue[ 1 ].Name = "FilterName";
399: //propertyvalue[ 1 ].Value = context.get("convertFilterName");
400: XFrame frame = desktop.getCurrentFrame();
401: //XFrame frame = (XFrame) UnoRuntime.queryInterface(XFrame.class, desktop);
402: Object dispatchHelperObj = xmulticomponentfactory
403: .createInstanceWithContext(
404: "com.sun.star.frame.DispatchHelper",
405: xcomponentcontext);
406: XDispatchHelper dispatchHelper = (XDispatchHelper) UnoRuntime
407: .queryInterface(XDispatchHelper.class,
408: dispatchHelperObj);
409: XDispatchProvider dispatchProvider = (XDispatchProvider) UnoRuntime
410: .queryInterface(XDispatchProvider.class, frame);
411: dispatchHelper.executeDispatch(dispatchProvider,
412: ".uno:CompareDocuments", "", 0, propertyvalue);
413:
414: // Preparing properties for storing the document
415: propertyvalue = new PropertyValue[1];
416: // Setting the flag for overwriting
417: propertyvalue[0] = new PropertyValue();
418: propertyvalue[0].Name = "Overwrite";
419: propertyvalue[0].Value = new Boolean(true);
420: // Setting the filter name
421: //propertyvalue[ 1 ] = new PropertyValue();
422: //propertyvalue[ 1 ].Name = "FilterName";
423: //propertyvalue[ 1 ].Value = context.get("convertFilterName");
424:
425: Debug.logInfo("stringOutFile: " + stringOutFile, module);
426: // Storing and converting the document
427: xstorable.storeToURL(stringOutFile, propertyvalue);
428:
429: // Getting the method dispose() for closing the document
430: XComponent xcomponent = (XComponent) UnoRuntime
431: .queryInterface(XComponent.class, xstorable);
432:
433: // Closing the converted document
434: xcomponent.dispose();
435:
436: Map results = ServiceUtil.returnSuccess();
437: return results;
438: } catch (Exception e) {
439: Debug
440: .logError(e, "Error in OpenOffice operation: ",
441: module);
442: return ServiceUtil
443: .returnError("Error converting document: "
444: + e.toString());
445: }
446: }
447: }
|