1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.documentlibrary.util;
24  
25  import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
26  import com.artofsolving.jodconverter.DocumentConverter;
27  import com.artofsolving.jodconverter.DocumentFormat;
28  import com.artofsolving.jodconverter.DocumentFormatRegistry;
29  import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
30  import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
31  import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
32  import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
33  
34  import com.liferay.portal.SystemException;
35  import com.liferay.portal.kernel.util.ArrayUtil;
36  import com.liferay.portal.kernel.util.FileUtil;
37  import com.liferay.portal.kernel.util.StringPool;
38  import com.liferay.portal.kernel.util.Validator;
39  import com.liferay.portal.util.PrefsPropsUtil;
40  import com.liferay.portal.util.PropsKeys;
41  import com.liferay.portal.util.PropsValues;
42  import com.liferay.util.SystemProperties;
43  
44  import java.io.ByteArrayOutputStream;
45  import java.io.File;
46  import java.io.FileInputStream;
47  import java.io.IOException;
48  import java.io.InputStream;
49  
50  import java.util.ArrayList;
51  import java.util.HashMap;
52  import java.util.List;
53  import java.util.Map;
54  
55  /**
56   * <a href="DocumentConversionUtil.java.html"><b><i>View Source</i></b></a>
57   *
58   * @author Bruno Farache
59   *
60   */
61  public class DocumentConversionUtil {
62  
63      public static InputStream convert(
64              String id, InputStream is, String sourceExtension,
65              String targetExtension)
66          throws IOException, SystemException {
67  
68          return _instance._convert(id, is, sourceExtension, targetExtension);
69      }
70  
71      public static void disconnect() {
72          _instance._disconnect();
73      }
74  
75      public static String[] getConversions(String extension) {
76          return _instance._getConversions(extension);
77      }
78  
79      public static String getTempFileId(long id, double version) {
80          StringBuilder sb = new StringBuilder();
81  
82          sb.append(id);
83          sb.append(StringPool.PERIOD);
84          sb.append(version);
85  
86          return sb.toString();
87      }
88  
89      private DocumentConversionUtil() {
90          _conversionsMap.put("svg", _DRAWING_CONVERSIONS);
91          _conversionsMap.put("swf", _DRAWING_CONVERSIONS);
92  
93          _conversionsMap.put("odp", _PRESENTATION_CONVERSIONS);
94          _conversionsMap.put("ppt", _PRESENTATION_CONVERSIONS);
95          _conversionsMap.put("sxi", _PRESENTATION_CONVERSIONS);
96  
97          _conversionsMap.put("csv", _SPREADSHEET_CONVERSIONS);
98          _conversionsMap.put("ods", _SPREADSHEET_CONVERSIONS);
99          _conversionsMap.put("sxc", _SPREADSHEET_CONVERSIONS);
100         _conversionsMap.put("tsv", _SPREADSHEET_CONVERSIONS);
101         _conversionsMap.put("xls", _SPREADSHEET_CONVERSIONS);
102 
103         _conversionsMap.put("doc", _TEXT_CONVERSIONS);
104         _conversionsMap.put("htm", _TEXT_CONVERSIONS);
105         _conversionsMap.put("html", _TEXT_CONVERSIONS);
106         _conversionsMap.put("odt", _TEXT_CONVERSIONS);
107         _conversionsMap.put("rtf", _TEXT_CONVERSIONS);
108         _conversionsMap.put("sxw", _TEXT_CONVERSIONS);
109         _conversionsMap.put("txt", _TEXT_CONVERSIONS);
110         _conversionsMap.put("wpd", _TEXT_CONVERSIONS);
111     }
112 
113     private InputStream _convert(
114             String id, InputStream is, String sourceExtension,
115             String targetExtension)
116         throws IOException, SystemException {
117 
118         if (!PrefsPropsUtil.getBoolean(
119                 PropsKeys.OPENOFFICE_SERVER_ENABLED,
120                 PropsValues.OPENOFFICE_SERVER_ENABLED)) {
121 
122             return null;
123         }
124 
125         StringBuilder sb = new StringBuilder();
126 
127         sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
128         sb.append("/liferay/document_conversion/");
129         sb.append(id);
130         sb.append(StringPool.PERIOD);
131         sb.append(targetExtension);
132 
133         String fileName = sb.toString();
134 
135         File file = new File(fileName);
136 
137         if (!PropsValues.OPENOFFICE_CACHE_ENABLED || !file.exists()) {
138             DocumentFormatRegistry registry =
139                 new DefaultDocumentFormatRegistry();
140 
141             DocumentConverter converter = _getConverter(registry);
142 
143             if (sourceExtension.equals("htm")) {
144                 sourceExtension = "html";
145             }
146 
147             DocumentFormat inputFormat = registry.getFormatByFileExtension(
148                 sourceExtension);
149 
150             ByteArrayOutputStream baos = new ByteArrayOutputStream();
151 
152             DocumentFormat outputFormat = registry.getFormatByFileExtension(
153                 targetExtension);
154 
155             converter.convert(is, inputFormat, baos, outputFormat);
156 
157             FileUtil.write(file, baos.toByteArray());
158         }
159 
160         return new FileInputStream(file);
161     }
162 
163     private void _disconnect() {
164         if (_connection != null) {
165             _connection.disconnect();
166         }
167     }
168 
169     private String[] _getConversions(String extension) {
170         String[] conversions = _conversionsMap.get(extension);
171 
172         if (conversions == null) {
173             conversions = _DEFAULT_CONVERSIONS;
174         }
175         else {
176             if (ArrayUtil.contains(conversions, extension)) {
177                 List<String> list = new ArrayList<String>();
178 
179                 for (int i = 0; i < conversions.length; i++) {
180                     String conversion = conversions[i];
181 
182                     if (!conversion.equals(extension)) {
183                         list.add(conversion);
184                     }
185                 }
186 
187                 conversions = list.toArray(new String[list.size()]);
188             }
189         }
190 
191         return conversions;
192     }
193 
194     private DocumentConverter _getConverter(DocumentFormatRegistry registry)
195         throws SystemException {
196 
197         if ((_connection == null) || (_converter == null)) {
198             String host = PrefsPropsUtil.getString(
199                 PropsKeys.OPENOFFICE_SERVER_HOST);
200             int port = PrefsPropsUtil.getInteger(
201                 PropsKeys.OPENOFFICE_SERVER_PORT,
202                 PropsValues.OPENOFFICE_SERVER_PORT);
203 
204             if (_isRemoteOpenOfficeHost(host)) {
205                 _connection = new SocketOpenOfficeConnection(host, port);
206                 _converter = new StreamOpenOfficeDocumentConverter(_connection);
207             }
208             else {
209                 _connection = new SocketOpenOfficeConnection(port);
210                 _converter = new OpenOfficeDocumentConverter(_connection);
211             }
212         }
213 
214         return _converter;
215     }
216 
217     private boolean _isRemoteOpenOfficeHost(String host) {
218         if (Validator.isNotNull(host) && !host.equals(_LOCALHOST_IP) &&
219             !host.startsWith(_LOCALHOST)) {
220 
221             return true;
222         }
223         else {
224             return false;
225         }
226     }
227 
228     private static final String[] _DEFAULT_CONVERSIONS = new String[0];
229 
230     private static final String[] _DRAWING_CONVERSIONS = new String[] {"odg"};
231 
232     private static final String _LOCALHOST = "localhost";
233 
234     private static final String _LOCALHOST_IP = "127.0.0.1";
235 
236     private static final String[] _PRESENTATION_CONVERSIONS = new String[] {
237         "odp", "pdf", "ppt", "swf", "sxi"
238     };
239 
240     private static final String[] _SPREADSHEET_CONVERSIONS = new String[] {
241         "csv", "ods", "pdf", "sxc", "tsv", "xls"
242     };
243 
244     private static final String[] _TEXT_CONVERSIONS = new String[] {
245         "doc", "odt", "pdf", "rtf", "sxw", "txt"
246     };
247 
248     private static DocumentConversionUtil _instance =
249         new DocumentConversionUtil();
250 
251     private Map<String, String[]> _conversionsMap =
252         new HashMap<String, String[]>();
253     private OpenOfficeConnection _connection;
254     private DocumentConverter _converter;
255 
256 }