| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| *******************************************************************************/ |
| package org.ofbiz.content.openoffice; |
| |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.FileNotFoundException; |
| import java.nio.ByteBuffer; |
| import java.util.Map; |
| import java.util.Random; |
| import java.sql.Timestamp; |
| import java.lang.Math; |
| import java.net.MalformedURLException; |
| |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.UtilValidate; |
| import org.ofbiz.base.util.UtilDateTime; |
| import org.ofbiz.base.util.UtilProperties; |
| import org.ofbiz.entity.Delegator; |
| import org.ofbiz.entity.util.EntityUtilProperties; |
| import org.ofbiz.service.DispatchContext; |
| import org.ofbiz.service.ServiceUtil; |
| |
| import com.sun.star.beans.PropertyValue; |
| import com.sun.star.beans.XPropertySet; |
| import com.sun.star.frame.XComponentLoader; |
| import com.sun.star.frame.XDesktop; |
| import com.sun.star.frame.XDispatchHelper; |
| import com.sun.star.frame.XDispatchProvider; |
| import com.sun.star.frame.XFrame; |
| import com.sun.star.frame.XStorable; |
| import com.sun.star.lang.XComponent; |
| import com.sun.star.lang.XMultiComponentFactory; |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.uno.XComponentContext; |
| |
| /** |
| * OpenOfficeServices Class |
| */ |
| public class OpenOfficeServices { |
| public static final String module = OpenOfficeServices.class.getName(); |
| |
| /** |
| * Use OpenOffice to convert documents between types |
| * This service requires that the "content.temp.dir" directory be set in the content.properties file. |
| * This value should be operating system dependent with "\\" separators for Windows |
| * and "/" for Linux/Unix. |
| */ |
| public static Map<String, Object> convertDocumentByteBuffer(DispatchContext dctx, Map<String, ? extends Object> context) { |
| |
| Map results = ServiceUtil.returnSuccess(); |
| Delegator delegator = dctx.getDelegator(); |
| XMultiComponentFactory xmulticomponentfactory = null; |
| //String uniqueSeqNum = delegator.getNextSeqId("OOTempDir"); |
| Timestamp ts = UtilDateTime.nowTimestamp(); |
| Random random = new Random(ts.getTime()); |
| String uniqueSeqNum = Integer.toString(Math.abs(random.nextInt())); |
| String fileInName = "OOIN_" + uniqueSeqNum; |
| String fileOutName = "OOOUT_" + uniqueSeqNum; |
| File fileIn = null; |
| File fileOut = null; |
| |
| ByteBuffer inByteBuffer = (ByteBuffer) context.get("inByteBuffer"); |
| String inputMimeType = (String) context.get("inputMimeType"); |
| String outputMimeType = (String) context.get("outputMimeType"); |
| String extName = OpenOfficeWorker.getExtensionFromMimeType(outputMimeType); |
| fileOutName += "." + extName; |
| |
| // if these are empty don't worry, the OpenOfficeWorker down below will take care of it |
| String oooHost = (String) context.get("oooHost"); |
| String oooPort = (String) context.get("oooPort"); |
| |
| try { |
| xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(oooHost, oooPort); |
| byte[] inByteArray = inByteBuffer.array(); |
| |
| // The following line work in linux, but not Windows or Mac environment. It is preferred because it does not use temporary files |
| //OpenOfficeByteArrayInputStream oobais = new OpenOfficeByteArrayInputStream(inByteArray); |
| //Debug.logInfo("Doing convertDocumentByteBuffer, inBytes size is [" + inByteArray.length + "]", module); |
| //OpenOfficeByteArrayOutputStream baos = OpenOfficeWorker.convertOODocByteStreamToByteStream(xmulticomponentfactory, oobais, inputMimeType, outputMimeType); |
| |
| |
| String tempDir = EntityUtilProperties.getPropertyValue("content", "content.temp.dir", delegator); |
| fileIn = new File(tempDir + fileInName); |
| FileOutputStream fos = new FileOutputStream(fileIn); |
| fos.write(inByteArray); |
| fos.close(); |
| Debug.logInfo("fileIn:" + tempDir + fileInName, module); |
| OpenOfficeWorker.convertOODocToFile(xmulticomponentfactory, tempDir + fileInName, tempDir + fileOutName, outputMimeType); |
| fileOut = new File(tempDir + fileOutName); |
| FileInputStream fis = new FileInputStream(fileOut); |
| int c; |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| while ((c=fis.read()) > -1) { |
| baos.write(c); |
| } |
| fis.close(); |
| |
| results.put("outByteBuffer", ByteBuffer.wrap(baos.toByteArray())); |
| baos.close(); |
| |
| } catch (MalformedURLException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (FileNotFoundException e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (IOException e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (Exception e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } finally { |
| if (fileIn != null) fileIn.delete(); |
| if (fileOut != null) fileOut.delete(); |
| } |
| return results; |
| } |
| |
| /** |
| * Use OpenOffice to convert documents between types |
| */ |
| public static Map<String, Object> convertDocument(DispatchContext dctx, Map<String, ? extends Object> context) { |
| XMultiComponentFactory xmulticomponentfactory = null; |
| |
| String stringUrl = "file:///" + context.get("filenameFrom"); |
| String stringConvertedFile = "file:///" + context.get("filenameTo"); |
| String filterName = "file:///" + context.get("filterName"); |
| |
| // if these are empty don't worry, the OpenOfficeWorker down below will take care of it |
| String oooHost = (String) context.get("oooHost"); |
| String oooPort = (String) context.get("oooPort"); |
| |
| try { |
| xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(oooHost, oooPort); |
| OpenOfficeWorker.convertOODocToFile(xmulticomponentfactory, stringUrl, stringConvertedFile, filterName); |
| |
| Map results = ServiceUtil.returnSuccess(); |
| return results; |
| } catch (IOException e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (Exception e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } |
| } |
| |
| /** |
| * Use OpenOffice to convert documents between types |
| */ |
| public static Map<String, Object> convertDocumentFileToFile(DispatchContext dctx, Map<String, ? extends Object> context) { |
| XMultiComponentFactory xmulticomponentfactory = null; |
| |
| String stringUrl = (String) context.get("filenameFrom"); |
| String stringConvertedFile = (String) context.get("filenameTo"); |
| String inputMimeType = (String) context.get("inputMimeType"); |
| String outputMimeType = (String) context.get("outputMimeType"); |
| |
| // if these are empty don't worry, the OpenOfficeWorker down below will take care of it |
| String oooHost = (String) context.get("oooHost"); |
| String oooPort = (String) context.get("oooPort"); |
| |
| try { |
| xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(oooHost, oooPort); |
| File inputFile = new File(stringUrl); |
| long fileSize = inputFile.length(); |
| FileInputStream fis = new FileInputStream(inputFile); |
| ByteArrayOutputStream baos = new ByteArrayOutputStream((int)fileSize); |
| int c; |
| while ((c = fis.read()) != -1) { |
| baos.write(c); |
| } |
| OpenOfficeByteArrayInputStream oobais = new OpenOfficeByteArrayInputStream(baos.toByteArray()); |
| OpenOfficeByteArrayOutputStream oobaos = OpenOfficeWorker.convertOODocByteStreamToByteStream(xmulticomponentfactory, oobais, inputMimeType, outputMimeType); |
| FileOutputStream fos = new FileOutputStream(stringConvertedFile); |
| fos.write(oobaos.toByteArray()); |
| fos.close(); |
| fis.close(); |
| oobais.close(); |
| oobaos.close(); |
| |
| Map results = ServiceUtil.returnSuccess(); |
| return results; |
| } catch (IOException e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (Exception e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } |
| } |
| |
| /** |
| * Use OpenOffice to convert documents between types |
| */ |
| public static Map<String, Object> convertDocumentStreamToStream(DispatchContext dctx, Map<String, ? extends Object> context) { |
| XMultiComponentFactory xmulticomponentfactory = null; |
| |
| String stringUrl = "file:///" + context.get("filenameFrom"); |
| String stringConvertedFile = "file:///" + context.get("filenameTo"); |
| String inputMimeType = (String) context.get("inputMimeType"); |
| String outputMimeType = (String) context.get("outputMimeType"); |
| |
| // if these are empty don't worry, the OpenOfficeWorker down below will take care of it |
| String oooHost = (String) context.get("oooHost"); |
| String oooPort = (String) context.get("oooPort"); |
| |
| try { |
| xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(oooHost, oooPort); |
| File inputFile = new File(stringUrl); |
| long fileSize = inputFile.length(); |
| FileInputStream fis = new FileInputStream(inputFile); |
| ByteArrayOutputStream baos = new ByteArrayOutputStream((int)fileSize); |
| int c; |
| while ((c = fis.read()) != -1) { |
| baos.write(c); |
| } |
| OpenOfficeByteArrayInputStream oobais = new OpenOfficeByteArrayInputStream(baos.toByteArray()); |
| OpenOfficeByteArrayOutputStream oobaos = OpenOfficeWorker.convertOODocByteStreamToByteStream(xmulticomponentfactory, oobais, inputMimeType, outputMimeType); |
| FileOutputStream fos = new FileOutputStream(stringConvertedFile); |
| fos.write(oobaos.toByteArray()); |
| fos.close(); |
| fis.close(); |
| oobais.close(); |
| oobaos.close(); |
| |
| Map results = ServiceUtil.returnSuccess(); |
| return results; |
| } catch (IOException e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (Exception e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } |
| } |
| |
| /** |
| * Use OpenOffice to compare documents |
| */ |
| public static Map<String, Object> compareDocuments(DispatchContext dctx, Map<String, ? extends Object> context) { |
| XMultiComponentFactory xmulticomponentfactory = null; |
| |
| String stringUrl = "file:///" + context.get("filenameFrom"); |
| String stringOriginalFile = "file:///" + context.get("filenameOriginal"); |
| String stringOutFile = "file:///" + context.get("filenameOut"); |
| |
| // if these are empty don't worry, the OpenOfficeWorker down below will take care of it |
| String oooHost = (String)context.get("oooHost"); |
| String oooPort = (String)context.get("oooPort"); |
| |
| try { |
| xmulticomponentfactory = OpenOfficeWorker.getRemoteServer(oooHost, oooPort); |
| } catch (IOException e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } catch (Exception e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(e.toString()); |
| } |
| //System.out.println("xmulticomponentfactory: " + xmulticomponentfactory); |
| |
| // Converting the document to the favoured type |
| try { |
| // Composing the URL |
| |
| |
| // Query for the XPropertySet interface. |
| XPropertySet xpropertysetMultiComponentFactory = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xmulticomponentfactory); |
| |
| // Get the default context from the office server. |
| Object objectDefaultContext = xpropertysetMultiComponentFactory.getPropertyValue("DefaultContext"); |
| |
| // Query for the interface XComponentContext. |
| XComponentContext xcomponentcontext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, objectDefaultContext); |
| |
| /* A desktop environment contains tasks with one or more |
| frames in which components can be loaded. Desktop is the |
| environment for components which can instanciate within |
| frames. */ |
| |
| Object desktopObj = xmulticomponentfactory.createInstanceWithContext("com.sun.star.frame.Desktop", xcomponentcontext); |
| XDesktop desktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktopObj); |
| XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktopObj); |
| |
| |
| // Preparing properties for loading the document |
| PropertyValue propertyvalue[] = new PropertyValue[ 1 ]; |
| // Setting the flag for hidding the open document |
| propertyvalue[ 0 ] = new PropertyValue(); |
| propertyvalue[ 0 ].Name = "Hidden"; |
| propertyvalue[ 0 ].Value = Boolean.valueOf(true); |
| //TODO: Hardcoding opening word documents -- this will need to change. |
| //propertyvalue[ 1 ] = new PropertyValue(); |
| //propertyvalue[ 1 ].Name = "FilterName"; |
| //propertyvalue[ 1 ].Value = "HTML (StarWriter)"; |
| |
| // Loading the wanted document |
| Object objectDocumentToStore = xcomponentloader.loadComponentFromURL(stringUrl, "_blank", 0, propertyvalue); |
| |
| // Getting an object that will offer a simple way to store a document to a URL. |
| XStorable xstorable = (XStorable) UnoRuntime.queryInterface(XStorable.class, objectDocumentToStore); |
| |
| // Preparing properties for comparing the document |
| propertyvalue = new PropertyValue[ 1 ]; |
| // Setting the flag for overwriting |
| propertyvalue[ 0 ] = new PropertyValue(); |
| propertyvalue[ 0 ].Name = "URL"; |
| propertyvalue[ 0 ].Value = stringOriginalFile; |
| // Setting the filter name |
| //propertyvalue[ 1 ] = new PropertyValue(); |
| //propertyvalue[ 1 ].Name = "FilterName"; |
| //propertyvalue[ 1 ].Value = context.get("convertFilterName"); |
| XFrame frame = desktop.getCurrentFrame(); |
| //XFrame frame = (XFrame) UnoRuntime.queryInterface(XFrame.class, desktop); |
| Object dispatchHelperObj = xmulticomponentfactory.createInstanceWithContext("com.sun.star.frame.DispatchHelper", xcomponentcontext); |
| XDispatchHelper dispatchHelper = (XDispatchHelper) UnoRuntime.queryInterface(XDispatchHelper.class, dispatchHelperObj); |
| XDispatchProvider dispatchProvider = (XDispatchProvider) UnoRuntime.queryInterface(XDispatchProvider.class, frame); |
| dispatchHelper.executeDispatch(dispatchProvider, ".uno:CompareDocuments", "", 0, propertyvalue); |
| |
| // Preparing properties for storing the document |
| propertyvalue = new PropertyValue[ 1 ]; |
| // Setting the flag for overwriting |
| propertyvalue[ 0 ] = new PropertyValue(); |
| propertyvalue[ 0 ].Name = "Overwrite"; |
| propertyvalue[ 0 ].Value = Boolean.valueOf(true); |
| // Setting the filter name |
| //propertyvalue[ 1 ] = new PropertyValue(); |
| //propertyvalue[ 1 ].Name = "FilterName"; |
| //propertyvalue[ 1 ].Value = context.get("convertFilterName"); |
| |
| Debug.logInfo("stringOutFile: "+stringOutFile, module); |
| // Storing and converting the document |
| xstorable.storeToURL(stringOutFile, propertyvalue); |
| |
| // Getting the method dispose() for closing the document |
| XComponent xcomponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, |
| xstorable); |
| |
| // Closing the converted document |
| xcomponent.dispose(); |
| |
| Map results = ServiceUtil.returnSuccess(); |
| return results; |
| } catch (Exception e) { |
| Debug.logError(e, "Error in OpenOffice operation: ", module); |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "ContentConvertingDocumentError", |
| UtilMisc.toMap("errorString", e.toString()), locale)); |
| } |
| } |
| } |