1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.documentlibrary.util;
16  
17  import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
18  import com.artofsolving.jodconverter.DocumentConverter;
19  import com.artofsolving.jodconverter.DocumentFormat;
20  import com.artofsolving.jodconverter.DocumentFormatRegistry;
21  import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
22  import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
23  import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
24  import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
25  
26  import com.liferay.portal.kernel.exception.SystemException;
27  import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
28  import com.liferay.portal.kernel.util.ArrayUtil;
29  import com.liferay.portal.kernel.util.FileUtil;
30  import com.liferay.portal.kernel.util.PropsKeys;
31  import com.liferay.portal.kernel.util.StringBundler;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.util.PrefsPropsUtil;
35  import com.liferay.portal.util.PropsValues;
36  import com.liferay.util.SystemProperties;
37  
38  import java.io.File;
39  import java.io.FileInputStream;
40  import java.io.IOException;
41  import java.io.InputStream;
42  
43  import java.util.ArrayList;
44  import java.util.HashMap;
45  import java.util.List;
46  import java.util.Map;
47  
48  /**
49   * <a href="DocumentConversionUtil.java.html"><b><i>View Source</i></b></a>
50   *
51   * @author Bruno Farache
52   */
53  public class DocumentConversionUtil {
54  
55      public static InputStream convert(
56              String id, InputStream is, String sourceExtension,
57              String targetExtension)
58          throws IOException, SystemException {
59  
60          return _instance._convert(id, is, sourceExtension, targetExtension);
61      }
62  
63      public static void disconnect() {
64          _instance._disconnect();
65      }
66  
67      public static String[] getConversions(String extension) {
68          return _instance._getConversions(extension);
69      }
70  
71      public static String getTempFileId(long id, String version) {
72          return String.valueOf(id).concat(StringPool.PERIOD).concat(version);
73      }
74  
75      private DocumentConversionUtil() {
76          _conversionsMap.put("svg", _DRAWING_CONVERSIONS);
77          _conversionsMap.put("swf", _DRAWING_CONVERSIONS);
78  
79          _conversionsMap.put("odp", _PRESENTATION_CONVERSIONS);
80          _conversionsMap.put("ppt", _PRESENTATION_CONVERSIONS);
81          _conversionsMap.put("pptx", _PRESENTATION_CONVERSIONS);
82          _conversionsMap.put("sxi", _PRESENTATION_CONVERSIONS);
83  
84          _conversionsMap.put("csv", _SPREADSHEET_CONVERSIONS);
85          _conversionsMap.put("ods", _SPREADSHEET_CONVERSIONS);
86          _conversionsMap.put("sxc", _SPREADSHEET_CONVERSIONS);
87          _conversionsMap.put("tsv", _SPREADSHEET_CONVERSIONS);
88          _conversionsMap.put("xls", _SPREADSHEET_CONVERSIONS);
89          _conversionsMap.put("xlsx", _SPREADSHEET_CONVERSIONS);
90  
91          _conversionsMap.put("doc", _TEXT_CONVERSIONS);
92          _conversionsMap.put("docx", _TEXT_CONVERSIONS);
93          _conversionsMap.put("htm", _TEXT_CONVERSIONS);
94          _conversionsMap.put("html", _TEXT_CONVERSIONS);
95          _conversionsMap.put("odt", _TEXT_CONVERSIONS);
96          _conversionsMap.put("rtf", _TEXT_CONVERSIONS);
97          _conversionsMap.put("sxw", _TEXT_CONVERSIONS);
98          _conversionsMap.put("txt", _TEXT_CONVERSIONS);
99          _conversionsMap.put("wpd", _TEXT_CONVERSIONS);
100     }
101 
102     private InputStream _convert(
103             String id, InputStream is, String sourceExtension,
104             String targetExtension)
105         throws IOException, SystemException {
106 
107         if (!PrefsPropsUtil.getBoolean(
108                 PropsKeys.OPENOFFICE_SERVER_ENABLED,
109                 PropsValues.OPENOFFICE_SERVER_ENABLED)) {
110 
111             return null;
112         }
113 
114         StringBundler sb = new StringBundler(5);
115 
116         sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
117         sb.append("/liferay/document_conversion/");
118         sb.append(id);
119         sb.append(StringPool.PERIOD);
120         sb.append(targetExtension);
121 
122         String fileName = sb.toString();
123 
124         File file = new File(fileName);
125 
126         if (!PropsValues.OPENOFFICE_CACHE_ENABLED || !file.exists()) {
127             DocumentFormatRegistry registry =
128                 new DefaultDocumentFormatRegistry();
129 
130             DocumentConverter converter = _getConverter(registry);
131 
132             if (sourceExtension.equals("htm")) {
133                 sourceExtension = "html";
134             }
135 
136             DocumentFormat inputFormat = registry.getFormatByFileExtension(
137                 sourceExtension);
138 
139             UnsyncByteArrayOutputStream ubaos =
140                 new UnsyncByteArrayOutputStream();
141 
142             DocumentFormat outputFormat = registry.getFormatByFileExtension(
143                 targetExtension);
144 
145             converter.convert(is, inputFormat, ubaos, outputFormat);
146 
147             FileUtil.write(file, ubaos.unsafeGetByteArray(), 0, ubaos.size());
148         }
149 
150         return new FileInputStream(file);
151     }
152 
153     private void _disconnect() {
154         if (_connection != null) {
155             _connection.disconnect();
156         }
157     }
158 
159     private String[] _getConversions(String extension) {
160         String[] conversions = _conversionsMap.get(extension);
161 
162         if (conversions == null) {
163             conversions = _DEFAULT_CONVERSIONS;
164         }
165         else {
166             if (ArrayUtil.contains(conversions, extension)) {
167                 List<String> list = new ArrayList<String>();
168 
169                 for (int i = 0; i < conversions.length; i++) {
170                     String conversion = conversions[i];
171 
172                     if (!conversion.equals(extension)) {
173                         list.add(conversion);
174                     }
175                 }
176 
177                 conversions = list.toArray(new String[list.size()]);
178             }
179         }
180 
181         return conversions;
182     }
183 
184     private DocumentConverter _getConverter(DocumentFormatRegistry registry)
185         throws SystemException {
186 
187         if ((_connection == null) || (_converter == null)) {
188             String host = PrefsPropsUtil.getString(
189                 PropsKeys.OPENOFFICE_SERVER_HOST);
190             int port = PrefsPropsUtil.getInteger(
191                 PropsKeys.OPENOFFICE_SERVER_PORT,
192                 PropsValues.OPENOFFICE_SERVER_PORT);
193 
194             if (_isRemoteOpenOfficeHost(host)) {
195                 _connection = new SocketOpenOfficeConnection(host, port);
196                 _converter = new StreamOpenOfficeDocumentConverter(_connection);
197             }
198             else {
199                 _connection = new SocketOpenOfficeConnection(port);
200                 _converter = new OpenOfficeDocumentConverter(_connection);
201             }
202         }
203 
204         return _converter;
205     }
206 
207     private boolean _isRemoteOpenOfficeHost(String host) {
208         if (Validator.isNotNull(host) && !host.equals(_LOCALHOST_IP) &&
209             !host.startsWith(_LOCALHOST)) {
210 
211             return true;
212         }
213         else {
214             return false;
215         }
216     }
217 
218     private static final String[] _DEFAULT_CONVERSIONS = new String[0];
219 
220     private static final String[] _DRAWING_CONVERSIONS = new String[] {"odg"};
221 
222     private static final String _LOCALHOST = "localhost";
223 
224     private static final String _LOCALHOST_IP = "127.0.0.1";
225 
226     private static final String[] _PRESENTATION_CONVERSIONS = new String[] {
227         "odp", "pdf", "ppt", "swf", "sxi"
228     };
229 
230     private static final String[] _SPREADSHEET_CONVERSIONS = new String[] {
231         "csv", "ods", "pdf", "sxc", "tsv", "xls"
232     };
233 
234     private static final String[] _TEXT_CONVERSIONS = new String[] {
235         "doc", "odt", "pdf", "rtf", "sxw", "txt"
236     };
237 
238     private static DocumentConversionUtil _instance =
239         new DocumentConversionUtil();
240 
241     private Map<String, String[]> _conversionsMap =
242         new HashMap<String, String[]>();
243     private OpenOfficeConnection _connection;
244     private DocumentConverter _converter;
245 
246 }