blob: e2430f428bc3d2d2385c5d117c94d7ab35564ec5 [file] [log] [blame]
/*******************************************************************************
* 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));
}
}
}