001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.util;
016    
017    import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
018    import com.artofsolving.jodconverter.DocumentConverter;
019    import com.artofsolving.jodconverter.DocumentFormat;
020    import com.artofsolving.jodconverter.DocumentFormatRegistry;
021    import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
022    import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
023    import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
024    import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
025    
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
028    import com.liferay.portal.kernel.util.ArrayUtil;
029    import com.liferay.portal.kernel.util.FileUtil;
030    import com.liferay.portal.kernel.util.PropsKeys;
031    import com.liferay.portal.kernel.util.StringBundler;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.util.PrefsPropsUtil;
035    import com.liferay.portal.util.PropsValues;
036    import com.liferay.util.SystemProperties;
037    
038    import java.io.File;
039    import java.io.FileInputStream;
040    import java.io.IOException;
041    import java.io.InputStream;
042    
043    import java.util.ArrayList;
044    import java.util.HashMap;
045    import java.util.List;
046    import java.util.Map;
047    
048    /**
049     * @author Bruno Farache
050     */
051    public class DocumentConversionUtil {
052    
053            public static InputStream convert(
054                            String id, InputStream is, String sourceExtension,
055                            String targetExtension)
056                    throws IOException, SystemException {
057    
058                    return _instance._convert(id, is, sourceExtension, targetExtension);
059            }
060    
061            public static void disconnect() {
062                    _instance._disconnect();
063            }
064    
065            public static String[] getConversions(String extension) {
066                    return _instance._getConversions(extension);
067            }
068    
069            public static String getTempFileId(long id, String version) {
070                    return String.valueOf(id).concat(StringPool.PERIOD).concat(version);
071            }
072    
073            private DocumentConversionUtil() {
074                    _conversionsMap.put("svg", _DRAWING_CONVERSIONS);
075                    _conversionsMap.put("swf", _DRAWING_CONVERSIONS);
076    
077                    _conversionsMap.put("odp", _PRESENTATION_CONVERSIONS);
078                    _conversionsMap.put("ppt", _PRESENTATION_CONVERSIONS);
079                    _conversionsMap.put("pptx", _PRESENTATION_CONVERSIONS);
080                    _conversionsMap.put("sxi", _PRESENTATION_CONVERSIONS);
081    
082                    _conversionsMap.put("csv", _SPREADSHEET_CONVERSIONS);
083                    _conversionsMap.put("ods", _SPREADSHEET_CONVERSIONS);
084                    _conversionsMap.put("sxc", _SPREADSHEET_CONVERSIONS);
085                    _conversionsMap.put("tsv", _SPREADSHEET_CONVERSIONS);
086                    _conversionsMap.put("xls", _SPREADSHEET_CONVERSIONS);
087                    _conversionsMap.put("xlsx", _SPREADSHEET_CONVERSIONS);
088    
089                    _conversionsMap.put("doc", _TEXT_CONVERSIONS);
090                    _conversionsMap.put("docx", _TEXT_CONVERSIONS);
091                    _conversionsMap.put("htm", _TEXT_CONVERSIONS);
092                    _conversionsMap.put("html", _TEXT_CONVERSIONS);
093                    _conversionsMap.put("odt", _TEXT_CONVERSIONS);
094                    _conversionsMap.put("rtf", _TEXT_CONVERSIONS);
095                    _conversionsMap.put("sxw", _TEXT_CONVERSIONS);
096                    _conversionsMap.put("txt", _TEXT_CONVERSIONS);
097                    _conversionsMap.put("wpd", _TEXT_CONVERSIONS);
098            }
099    
100            private InputStream _convert(
101                            String id, InputStream is, String sourceExtension,
102                            String targetExtension)
103                    throws IOException, SystemException {
104    
105                    if (!PrefsPropsUtil.getBoolean(
106                                    PropsKeys.OPENOFFICE_SERVER_ENABLED,
107                                    PropsValues.OPENOFFICE_SERVER_ENABLED)) {
108    
109                            return null;
110                    }
111    
112                    StringBundler sb = new StringBundler(5);
113    
114                    sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
115                    sb.append("/liferay/document_conversion/");
116                    sb.append(id);
117                    sb.append(StringPool.PERIOD);
118                    sb.append(targetExtension);
119    
120                    String fileName = sb.toString();
121    
122                    File file = new File(fileName);
123    
124                    if (!PropsValues.OPENOFFICE_CACHE_ENABLED || !file.exists()) {
125                            DocumentFormatRegistry registry =
126                                    new DefaultDocumentFormatRegistry();
127    
128                            DocumentConverter converter = _getConverter(registry);
129    
130                            if (sourceExtension.equals("htm")) {
131                                    sourceExtension = "html";
132                            }
133    
134                            DocumentFormat inputFormat = registry.getFormatByFileExtension(
135                                    sourceExtension);
136    
137                            UnsyncByteArrayOutputStream ubaos =
138                                    new UnsyncByteArrayOutputStream();
139    
140                            DocumentFormat outputFormat = registry.getFormatByFileExtension(
141                                    targetExtension);
142    
143                            converter.convert(is, inputFormat, ubaos, outputFormat);
144    
145                            FileUtil.write(file, ubaos.unsafeGetByteArray(), 0, ubaos.size());
146                    }
147    
148                    return new FileInputStream(file);
149            }
150    
151            private void _disconnect() {
152                    if (_connection != null) {
153                            _connection.disconnect();
154                    }
155            }
156    
157            private String[] _getConversions(String extension) {
158                    String[] conversions = _conversionsMap.get(extension);
159    
160                    if (conversions == null) {
161                            conversions = _DEFAULT_CONVERSIONS;
162                    }
163                    else {
164                            if (ArrayUtil.contains(conversions, extension)) {
165                                    List<String> list = new ArrayList<String>();
166    
167                                    for (int i = 0; i < conversions.length; i++) {
168                                            String conversion = conversions[i];
169    
170                                            if (!conversion.equals(extension)) {
171                                                    list.add(conversion);
172                                            }
173                                    }
174    
175                                    conversions = list.toArray(new String[list.size()]);
176                            }
177                    }
178    
179                    return conversions;
180            }
181    
182            private DocumentConverter _getConverter(DocumentFormatRegistry registry)
183                    throws SystemException {
184    
185                    if ((_connection == null) || (_converter == null)) {
186                            String host = PrefsPropsUtil.getString(
187                                    PropsKeys.OPENOFFICE_SERVER_HOST);
188                            int port = PrefsPropsUtil.getInteger(
189                                    PropsKeys.OPENOFFICE_SERVER_PORT,
190                                    PropsValues.OPENOFFICE_SERVER_PORT);
191    
192                            if (_isRemoteOpenOfficeHost(host)) {
193                                    _connection = new SocketOpenOfficeConnection(host, port);
194                                    _converter = new StreamOpenOfficeDocumentConverter(_connection);
195                            }
196                            else {
197                                    _connection = new SocketOpenOfficeConnection(port);
198                                    _converter = new OpenOfficeDocumentConverter(_connection);
199                            }
200                    }
201    
202                    return _converter;
203            }
204    
205            private boolean _isRemoteOpenOfficeHost(String host) {
206                    if (Validator.isNotNull(host) && !host.equals(_LOCALHOST_IP) &&
207                            !host.startsWith(_LOCALHOST)) {
208    
209                            return true;
210                    }
211                    else {
212                            return false;
213                    }
214            }
215    
216            private static final String[] _DEFAULT_CONVERSIONS = new String[0];
217    
218            private static final String[] _DRAWING_CONVERSIONS = new String[] {"odg"};
219    
220            private static final String _LOCALHOST = "localhost";
221    
222            private static final String _LOCALHOST_IP = "127.0.0.1";
223    
224            private static final String[] _PRESENTATION_CONVERSIONS = new String[] {
225                    "odp", "pdf", "ppt", "swf", "sxi"
226            };
227    
228            private static final String[] _SPREADSHEET_CONVERSIONS = new String[] {
229                    "csv", "ods", "pdf", "sxc", "tsv", "xls"
230            };
231    
232            private static final String[] _TEXT_CONVERSIONS = new String[] {
233                    "doc", "odt", "pdf", "rtf", "sxw", "txt"
234            };
235    
236            private static DocumentConversionUtil _instance =
237                    new DocumentConversionUtil();
238    
239            private Map<String, String[]> _conversionsMap =
240                    new HashMap<String, String[]>();
241            private OpenOfficeConnection _connection;
242            private DocumentConverter _converter;
243    
244    }