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.File;
021: import java.io.FileNotFoundException;
022: import java.io.IOException;
023: import java.net.MalformedURLException;
024: import java.net.URL;
025: import java.util.List;
026:
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpServletResponse;
029:
030: import org.ofbiz.base.util.Debug;
031: import org.ofbiz.base.util.UtilMisc;
032: import org.ofbiz.base.util.UtilProperties;
033: import org.ofbiz.base.util.UtilValidate;
034:
035: import com.sun.star.beans.PropertyValue;
036: import com.sun.star.beans.XPropertySet;
037: import com.sun.star.bridge.XUnoUrlResolver;
038: import com.sun.star.container.XNameAccess;
039: import com.sun.star.frame.XComponentLoader;
040: import com.sun.star.frame.XStorable;
041: import com.sun.star.lang.XComponent;
042: import com.sun.star.lang.XMultiComponentFactory;
043: import com.sun.star.uno.UnoRuntime;
044: import com.sun.star.uno.XComponentContext;
045: import com.sun.star.uri.ExternalUriReferenceTranslator;
046:
047: /**
048: * OpenOfficeWorker Class
049: *
050: * Note that for this to work you must start OpenOffice with a command such as the following:
051: * <code>soffice -accept=socket,host=localhost,port=8100;urp;</code>
052: */
053: public class OpenOfficeWorker {
054:
055: public static final String module = OpenOfficeWorker.class
056: .getName();
057:
058: /**
059: * Use OpenOffice to convert documents between types
060: */
061: public static XMultiComponentFactory getRemoteServer(String host,
062: String port) throws IOException, Exception {
063:
064: if (UtilValidate.isEmpty(host))
065: host = UtilProperties.getPropertyValue("openoffice-uno",
066: "oo.host", "localhost");
067: if (UtilValidate.isEmpty(port))
068: port = UtilProperties.getPropertyValue("openoffice-uno",
069: "oo.port", "8100");
070:
071: XMultiComponentFactory xmulticomponentfactory = null;
072: XComponentContext xcomponentcontext = null;
073: Object objectUrlResolver = null;
074: XUnoUrlResolver xurlresolver = null;
075: Object objectInitial = null;
076: // Converting the document to the favoured type
077: try {
078: /* Bootstraps a component context with the jurt base components
079: registered. Component context to be granted to a component for running.
080: Arbitrary values can be retrieved from the context. */
081: xcomponentcontext = com.sun.star.comp.helper.Bootstrap
082: .createInitialComponentContext(null);
083:
084: /* Gets the service manager instance to be used (or null). This method has
085: been added for convenience, because the service manager is a often used
086: object. */
087: xmulticomponentfactory = xcomponentcontext
088: .getServiceManager();
089:
090: /* Creates an instance of the component UnoUrlResolver which
091: supports the services specified by the factory. */
092: objectUrlResolver = xmulticomponentfactory
093: .createInstanceWithContext(
094: "com.sun.star.bridge.UnoUrlResolver",
095: xcomponentcontext);
096:
097: // Create a new url resolver
098: xurlresolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
099: XUnoUrlResolver.class, objectUrlResolver);
100:
101: // Resolves an object that is specified as follow:
102: // uno:<connection description>;<protocol description>;<initial object name>
103: String url = "uno:socket,host=" + host + ",port=" + port
104: + ";urp;StarOffice.ServiceManager";
105: objectInitial = xurlresolver.resolve(url);
106:
107: // Create a service manager from the initial object
108: xmulticomponentfactory = (XMultiComponentFactory) UnoRuntime
109: .queryInterface(XMultiComponentFactory.class,
110: objectInitial);
111: } catch (Exception e) {
112: // TODO: None of this works. Need a programmable start solution.
113: //String ooxvfb = UtilProperties.getPropertyValue("openoffice-uno", "oo.start.xvfb");
114: //String ooexport = UtilProperties.getPropertyValue("openoffice-uno", "oo.start.export");
115: // String oosoffice = UtilProperties.getPropertyValue("openoffice-uno", "oo.start.soffice");
116: //Process procXvfb = Runtime.getRuntime().exec(ooxvfb);
117: //Process procExport = Runtime.getRuntime().exec(ooexport);
118: /*
119: Process procSoffice = Runtime.getRuntime().exec(oosoffice);
120: Thread.sleep(3000);
121: objectInitial = xurlresolver.resolve("uno:socket,host=" + host + ",port=" + port + ";urp;StarOffice.ServiceManager");
122: xmulticomponentfactory = (XMultiComponentFactory) UnoRuntime.queryInterface(XMultiComponentFactory.class, objectInitial);
123: Debug.logInfo("soffice started. " + procSoffice, module);
124: */
125: String errMsg = "Error connecting to OpenOffice with host ["
126: + host
127: + "] and port ["
128: + port
129: + "]: "
130: + e.toString();
131: Debug.logError(e, errMsg, module);
132: throw new IllegalArgumentException(errMsg);
133: }
134:
135: return xmulticomponentfactory;
136: }
137:
138: public static String listFilterNamesEvent(
139: HttpServletRequest request, HttpServletResponse response) {
140: XMultiComponentFactory factory = null;
141:
142: try {
143: factory = getRemoteServer("localhost", "8100");
144: List filterList = getFilterNames(factory);
145: request.setAttribute("filterList", filterList);
146: } catch (IOException e) {
147: request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
148: return "error";
149: } catch (Exception e) {
150: request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
151: return "error";
152: }
153: return "success";
154: }
155:
156: public static List getFilterNames(
157: XMultiComponentFactory xmulticomponentfactory)
158: throws Exception {
159: XPropertySet xPropertySet = (XPropertySet) UnoRuntime
160: .queryInterface(XPropertySet.class,
161: xmulticomponentfactory);
162: Object oDefaultContext = xPropertySet
163: .getPropertyValue("DefaultContext");
164: XComponentContext xComponentContext = (XComponentContext) UnoRuntime
165: .queryInterface(XComponentContext.class,
166: oDefaultContext);
167:
168: Object filterFactory = xmulticomponentfactory
169: .createInstanceWithContext(
170: "com.sun.star.document.FilterFactory",
171: xComponentContext);
172: XNameAccess xNameAccess = (XNameAccess) UnoRuntime
173: .queryInterface(XNameAccess.class, filterFactory);
174: String[] filterNames = xNameAccess.getElementNames();
175:
176: //String [] serviceNames = filterFactory.getAvailableServiceNames();
177: for (int i = 0; i < filterNames.length; i++) {
178: String s = filterNames[i];
179: Debug.logInfo(s, module);
180: /*
181: if (s.toLowerCase().indexOf("filter") >= 0) {
182: Debug.logInfo("FILTER: " + s, module);
183: }
184: if (s.toLowerCase().indexOf("desktop") >= 0) {
185: Debug.logInfo("DESKTOP: " + s, module);
186: }
187: */
188: }
189:
190: List filterNameList = UtilMisc.toListArray(filterNames);
191: return filterNameList;
192: }
193:
194: public static void convertOODocToFile(
195: XMultiComponentFactory xmulticomponentfactory,
196: String fileInPath, String fileOutPath, String outputMimeType)
197: throws FileNotFoundException, IOException,
198: MalformedURLException, Exception {
199: // Converting the document to the favoured type
200: // Query for the XPropertySet interface.
201: XPropertySet xpropertysetMultiComponentFactory = (XPropertySet) UnoRuntime
202: .queryInterface(XPropertySet.class,
203: xmulticomponentfactory);
204:
205: // Get the default context from the office server.
206: Object objectDefaultContext = xpropertysetMultiComponentFactory
207: .getPropertyValue("DefaultContext");
208:
209: // Query for the interface XComponentContext.
210: XComponentContext xcomponentcontext = (XComponentContext) UnoRuntime
211: .queryInterface(XComponentContext.class,
212: objectDefaultContext);
213:
214: /* A desktop environment contains tasks with one or more
215: frames in which components can be loaded. Desktop is the
216: environment for components which can instanciate within
217: frames. */
218:
219: Object desktopObj = xmulticomponentfactory
220: .createInstanceWithContext(
221: "com.sun.star.frame.Desktop", xcomponentcontext);
222: //XDesktop desktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktopObj);
223: XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime
224: .queryInterface(XComponentLoader.class, desktopObj);
225:
226: // Preparing properties for loading the document
227: PropertyValue propertyvalue[] = new PropertyValue[2];
228: // Setting the flag for hidding the open document
229: propertyvalue[0] = new PropertyValue();
230: propertyvalue[0].Name = "Hidden";
231: propertyvalue[0].Value = new Boolean(false);
232:
233: propertyvalue[1] = new PropertyValue();
234: propertyvalue[1].Name = "UpdateDocMode";
235: propertyvalue[1].Value = "1";
236:
237: // Loading the wanted document
238: String stringUrl = convertToUrl(fileInPath, xcomponentcontext);
239: Debug.logInfo("stringUrl:" + stringUrl, module);
240: Object objectDocumentToStore = xcomponentloader
241: .loadComponentFromURL(stringUrl, "_blank", 0,
242: propertyvalue);
243:
244: // Getting an object that will offer a simple way to store a document to a URL.
245: XStorable xstorable = (XStorable) UnoRuntime.queryInterface(
246: XStorable.class, objectDocumentToStore);
247:
248: // Preparing properties for converting the document
249: propertyvalue = new PropertyValue[3];
250: // Setting the flag for overwriting
251: propertyvalue[0] = new PropertyValue();
252: propertyvalue[0].Name = "Overwrite";
253: propertyvalue[0].Value = new Boolean(true);
254: // Setting the filter name
255: // Preparing properties for converting the document
256: String filterName = getFilterNameFromMimeType(outputMimeType);
257:
258: propertyvalue[1] = new PropertyValue();
259: propertyvalue[1].Name = "FilterName";
260: propertyvalue[1].Value = filterName;
261:
262: propertyvalue[2] = new PropertyValue();
263: propertyvalue[2].Name = "CompressionMode";
264: propertyvalue[2].Value = "1";
265:
266: // Storing and converting the document
267: //File newFile = new File(stringConvertedFile);
268: //newFile.createNewFile();
269:
270: String stringConvertedFile = convertToUrl(fileOutPath,
271: xcomponentcontext);
272: Debug.logInfo("stringConvertedFile: " + stringConvertedFile,
273: module);
274: xstorable.storeToURL(stringConvertedFile, propertyvalue);
275:
276: // Getting the method dispose() for closing the document
277: XComponent xcomponent = (XComponent) UnoRuntime.queryInterface(
278: XComponent.class, xstorable);
279:
280: // Closing the converted document
281: xcomponent.dispose();
282: return;
283: }
284:
285: public static OpenOfficeByteArrayOutputStream convertOODocByteStreamToByteStream(
286: XMultiComponentFactory xmulticomponentfactory,
287: OpenOfficeByteArrayInputStream is, String inputMimeType,
288: String outputMimeType) throws Exception {
289:
290: // Query for the XPropertySet interface.
291: XPropertySet xpropertysetMultiComponentFactory = (XPropertySet) UnoRuntime
292: .queryInterface(XPropertySet.class,
293: xmulticomponentfactory);
294:
295: // Get the default context from the office server.
296: Object objectDefaultContext = xpropertysetMultiComponentFactory
297: .getPropertyValue("DefaultContext");
298:
299: // Query for the interface XComponentContext.
300: XComponentContext xcomponentcontext = (XComponentContext) UnoRuntime
301: .queryInterface(XComponentContext.class,
302: objectDefaultContext);
303:
304: /* A desktop environment contains tasks with one or more
305: frames in which components can be loaded. Desktop is the
306: environment for components which can instanciate within
307: frames. */
308:
309: Object desktopObj = xmulticomponentfactory
310: .createInstanceWithContext(
311: "com.sun.star.frame.Desktop", xcomponentcontext);
312: //XDesktop desktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktopObj);
313: XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime
314: .queryInterface(XComponentLoader.class, desktopObj);
315:
316: // Preparing properties for loading the document
317: PropertyValue propertyvalue[] = new PropertyValue[2];
318: // Setting the flag for hidding the open document
319: propertyvalue[0] = new PropertyValue();
320: propertyvalue[0].Name = "Hidden";
321: propertyvalue[0].Value = Boolean.TRUE;
322: //
323: propertyvalue[1] = new PropertyValue();
324: propertyvalue[1].Name = "InputStream";
325: propertyvalue[1].Value = is;
326:
327: // Loading the wanted document
328: Object objectDocumentToStore = xcomponentloader
329: .loadComponentFromURL("private:stream", "_blank", 0,
330: propertyvalue);
331: if (objectDocumentToStore == null) {
332: Debug
333: .logError(
334: "Could not get objectDocumentToStore object from xcomponentloader.loadComponentFromURL",
335: module);
336: }
337:
338: // Getting an object that will offer a simple way to store a document to a URL.
339: XStorable xstorable = (XStorable) UnoRuntime.queryInterface(
340: XStorable.class, objectDocumentToStore);
341: if (xstorable == null) {
342: Debug
343: .logError(
344: "Could not get XStorable object from UnoRuntime.queryInterface",
345: module);
346: }
347:
348: // Preparing properties for converting the document
349: String filterName = getFilterNameFromMimeType(outputMimeType);
350: propertyvalue = new PropertyValue[4];
351:
352: propertyvalue[0] = new PropertyValue();
353: propertyvalue[0].Name = "OutputStream";
354: OpenOfficeByteArrayOutputStream os = new OpenOfficeByteArrayOutputStream();
355: propertyvalue[0].Value = os;
356: // Setting the filter name
357: propertyvalue[1] = new PropertyValue();
358: propertyvalue[1].Name = "FilterName";
359: propertyvalue[1].Value = filterName;
360: // Setting the flag for overwriting
361: propertyvalue[3] = new PropertyValue();
362: propertyvalue[3].Name = "Overwrite";
363: propertyvalue[3].Value = Boolean.TRUE;
364: // For PDFs
365: propertyvalue[2] = new PropertyValue();
366: propertyvalue[2].Name = "CompressionMode";
367: propertyvalue[2].Value = "1";
368:
369: xstorable.storeToURL("private:stream", propertyvalue);
370: //xstorable.storeToURL("file:///home/byersa/testdoc1_file.pdf", propertyvalue);
371:
372: // Getting the method dispose() for closing the document
373: XComponent xcomponent = (XComponent) UnoRuntime.queryInterface(
374: XComponent.class, xstorable);
375:
376: // Closing the converted document
377: xcomponent.dispose();
378:
379: return os;
380: }
381:
382: public static String getFilterNameFromMimeType(String mimeType) {
383: String filterName = "";
384: if (UtilValidate.isEmpty(mimeType)) {
385: filterName = "HTML";
386: } else if (mimeType.equalsIgnoreCase("application/pdf")) {
387: filterName = "writer_pdf_Export";
388: } else if (mimeType.equalsIgnoreCase("application/msword")) {
389: filterName = "MS Word 97";
390: } else if (mimeType.equalsIgnoreCase("text/html")) {
391: filterName = "HTML (StarWriter)";
392: } else {
393: filterName = "HTML";
394: }
395: return filterName;
396:
397: }
398:
399: public static String getExtensionFromMimeType(String mimeType) {
400: String extension = "";
401: if (UtilValidate.isEmpty(mimeType)) {
402: extension = "html";
403: } else if (mimeType.equalsIgnoreCase("application/pdf")) {
404: extension = "pdf";
405: } else if (mimeType.equalsIgnoreCase("application/msword")) {
406: extension = "doc";
407: } else if (mimeType.equalsIgnoreCase("text/html")) {
408: extension = "html";
409: } else {
410: extension = "html";
411: }
412: return extension;
413:
414: }
415:
416: public static String convertToUrl(String filePath,
417: XComponentContext xComponentContext)
418: throws MalformedURLException {
419:
420: String returnUrl = null;
421: File f = new File(filePath);
422: URL u = f.toURL();
423: returnUrl = ExternalUriReferenceTranslator.create(
424: xComponentContext).translateToInternal(
425: u.toExternalForm());
426:
427: return returnUrl;
428: }
429:
430: }
|