001
014
015 package com.liferay.portlet.documentlibrary.util;
016
017 import com.liferay.portal.kernel.image.ImageBag;
018 import com.liferay.portal.kernel.image.ImageProcessorUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.messaging.DestinationNames;
022 import com.liferay.portal.kernel.messaging.MessageBusUtil;
023 import com.liferay.portal.kernel.repository.model.FileEntry;
024 import com.liferay.portal.kernel.repository.model.FileVersion;
025 import com.liferay.portal.kernel.util.FileUtil;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.SetUtil;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.model.CompanyConstants;
031 import com.liferay.portal.util.PrefsPropsUtil;
032 import com.liferay.portal.util.PropsValues;
033 import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
034 import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
035
036 import java.awt.image.RenderedImage;
037
038 import java.io.File;
039 import java.io.IOException;
040 import java.io.InputStream;
041
042 import java.util.List;
043 import java.util.Set;
044 import java.util.Vector;
045
046
050 public class ImageProcessor extends DLPreviewableProcessor {
051
052 public void cleanUp(FileEntry fileEntry) {
053 deleteFiles(fileEntry, null);
054 }
055
056 public void cleanUp(FileVersion fileVersion) {
057 String type = _instance._getType(fileVersion);
058
059 deleteFiles(fileVersion, type);
060 }
061
062 public static void generateImages(FileVersion fileVersion) {
063 _instance._generateImages(fileVersion);
064 }
065
066 public static InputStream getCustom1AsStream(FileVersion fileVersion)
067 throws Exception {
068
069 String type = _instance._getType(fileVersion);
070
071 return _instance._getCustomAsStream(fileVersion, type, 1);
072 }
073
074 public static long getCustom1FileSize(FileVersion fileVersion)
075 throws Exception {
076
077 String type = _instance._getType(fileVersion);
078
079 return _instance._getCustomFileSize(fileVersion, type, 1);
080 }
081
082 public static InputStream getCustom2AsStream(FileVersion fileVersion)
083 throws Exception {
084
085 String type = _instance._getType(fileVersion);
086
087 return _instance._getCustomAsStream(fileVersion, type, 2);
088 }
089
090 public static long getCustom2FileSize(FileVersion fileVersion)
091 throws Exception {
092
093 String type = _instance._getType(fileVersion);
094
095 return _instance._getCustomFileSize(fileVersion, type, 2);
096 }
097
098 public static Set<String> getImageMimeTypes() {
099 return _imageMimeTypes;
100 }
101
102 public static InputStream getThumbnailAsStream(FileVersion fileVersion)
103 throws Exception {
104
105 String type = _instance._getType(fileVersion);
106
107 return _instance.doGetThumbnailAsStream(fileVersion, type);
108 }
109
110 public static long getThumbnailFileSize(FileVersion fileVersion)
111 throws Exception {
112
113 String type = _instance._getType(fileVersion);
114
115 return _instance.doGetThumbnailFileSize(fileVersion, type);
116 }
117
118 public static boolean hasImages(FileVersion fileVersion) {
119 if (!PropsValues.DL_FILE_ENTRY_THUMBNAIL_ENABLED) {
120 return false;
121 }
122
123 boolean hasImages = false;
124
125 try {
126 hasImages = _instance._hasImages(fileVersion);
127
128 if (!hasImages && _instance.isSupported(fileVersion)) {
129 _instance._queueGeneration(fileVersion);
130 }
131 }
132 catch (Exception e) {
133 _log.error(e, e);
134 }
135
136 return hasImages;
137 }
138
139 public static boolean hasThumbnailImage(FileVersion fileVersion) {
140 return _instance._hasThumbnailImage(fileVersion);
141 }
142
143 public static void storeThumbnail(
144 long companyId, long groupId, long fileEntryId, long fileVersionId,
145 long custom1ImageId, long custom2ImageId,
146 InputStream is, String type)
147 throws Exception {
148
149 _instance._storeThumbnail(
150 companyId, groupId, fileEntryId, fileVersionId, custom1ImageId,
151 custom2ImageId, is, type);
152 }
153
154 public boolean isSupported(String mimeType) {
155 return _imageMimeTypes.contains(mimeType);
156 }
157
158 public void trigger(FileVersion fileVersion) {
159 _instance._queueGeneration(fileVersion);
160 }
161
162 private void _generateImages(FileVersion fileVersion) {
163 try {
164 if (!PropsValues.DL_FILE_ENTRY_THUMBNAIL_ENABLED) {
165 return;
166 }
167
168 InputStream inputStream = fileVersion.getContentStream(false);
169
170 byte[] bytes = FileUtil.getBytes(inputStream);
171
172 ImageBag imageBag = ImageProcessorUtil.read(bytes);
173
174 RenderedImage renderedImage = imageBag.getRenderedImage();
175
176 if (renderedImage == null) {
177 return;
178 }
179
180 String type = _instance._getType(fileVersion);
181
182 _saveThumbnailImage(
183 fileVersion, renderedImage,
184 PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT,
185 PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH,
186 getThumbnailFilePath(fileVersion, type));
187
188 if ((PrefsPropsUtil.getInteger(
189 PropsKeys.
190 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT) > 0) ||
191 (PrefsPropsUtil.getInteger(
192 PropsKeys.
193 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH) > 0)) {
194
195 _saveThumbnailImage(
196 fileVersion, renderedImage,
197 PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT,
198 PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH,
199 _getCustom1FilePath(fileVersion, type));
200 }
201
202 if ((PrefsPropsUtil.getInteger(
203 PropsKeys.
204 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT) > 0) ||
205 (PrefsPropsUtil.getInteger(
206 PropsKeys.
207 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH) > 0)) {
208
209 _saveThumbnailImage(
210 fileVersion, renderedImage,
211 PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT,
212 PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH,
213 _getCustom2FilePath(fileVersion, type));
214 }
215 }
216 catch (NoSuchFileEntryException nsfee) {
217 }
218 catch (Exception e) {
219 _log.error(e, e);
220 }
221 finally {
222 _fileVersionIds.remove(fileVersion.getFileVersionId());
223 }
224 }
225
226 private String _getCustom1FilePath(
227 FileVersion fileVersion, String type) {
228
229 return _getCustomFilePath(fileVersion, type, 1);
230 }
231
232 private String _getCustom2FilePath(
233 FileVersion fileVersion, String type) {
234
235 return _getCustomFilePath(fileVersion, type, 2);
236 }
237
238 private InputStream _getCustomAsStream(
239 FileVersion fileVersion, String type, int index)
240 throws Exception {
241
242 return DLStoreUtil.getFileAsStream(
243 fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
244 _getCustomFilePath(fileVersion, type, index));
245 }
246
247 private String _getCustomFilePath(
248 FileVersion fileVersion, String type, int index) {
249
250 StringBundler sb = new StringBundler(5);
251
252 sb.append(getPathSegment(fileVersion, false));
253 sb.append(StringPool.DASH);
254 sb.append(index);
255 sb.append(StringPool.PERIOD);
256 sb.append(type);
257
258 return sb.toString();
259 }
260
261 private long _getCustomFileSize(
262 FileVersion fileVersion, String type, int index)
263 throws Exception {
264
265 return DLStoreUtil.getFileSize(
266 fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
267 _getCustomFilePath(fileVersion, type, index));
268 }
269
270 private String _getType(FileVersion fileVersion) {
271 String type = fileVersion.getExtension();
272
273 if (type.equals("jpeg")) {
274 type = "jpg";
275 }
276
277 return type;
278 }
279
280 private boolean _hasCustomImage(FileVersion fileVersion, int index) {
281 try {
282 String type = _getType(fileVersion);
283
284 return DLStoreUtil.hasFile(
285 fileVersion.getCompanyId(), REPOSITORY_ID,
286 _getCustomFilePath(fileVersion, type, index));
287 }
288 catch (Exception e) {
289 _log.error(e, e);
290 }
291
292 return false;
293 }
294
295 private boolean _hasImages(FileVersion fileVersion) {
296 if (!_hasThumbnailImage(fileVersion)) {
297 return false;
298 }
299
300 try {
301 if ((PrefsPropsUtil.getInteger(
302 PropsKeys.
303 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT) > 0) ||
304 (PrefsPropsUtil.getInteger(
305 PropsKeys.
306 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH) > 0)) {
307
308 if (!_hasCustomImage(fileVersion, 1)) {
309 return false;
310 }
311 }
312
313 if ((PrefsPropsUtil.getInteger(
314 PropsKeys.
315 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT) > 0) ||
316 (PrefsPropsUtil.getInteger(
317 PropsKeys.
318 DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH) > 0)) {
319
320 if (!_hasCustomImage(fileVersion, 2)) {
321 return false;
322 }
323 }
324 }
325 catch (Exception e) {
326 _log.error(e, e);
327 }
328
329 return true;
330 }
331
332 private boolean _hasThumbnailImage(FileVersion fileVersion) {
333 try {
334 String imageType = _getType(fileVersion);
335
336 return DLStoreUtil.hasFile(
337 fileVersion.getCompanyId(), REPOSITORY_ID,
338 getThumbnailFilePath(fileVersion, imageType));
339 }
340 catch (Exception e) {
341 _log.error(e, e);
342 }
343
344 return false;
345 }
346
347 private void _queueGeneration(FileVersion fileVersion) {
348 if (!_fileVersionIds.contains(fileVersion.getFileVersionId()) &&
349 isSupported(fileVersion) && !_hasImages(fileVersion)) {
350 _fileVersionIds.add(fileVersion.getFileVersionId());
351
352 MessageBusUtil.sendMessage(
353 DestinationNames.DOCUMENT_LIBRARY_IMAGE_PROCESSOR,
354 fileVersion);
355 }
356 }
357
358 private void _saveThumbnailImage(
359 FileVersion fileVersion, RenderedImage renderedImage,
360 String maxHeightPropsKey, String maxWidthPropsKey, String filePath)
361 throws Exception {
362
363 File file = _scaleImage(
364 renderedImage, fileVersion.getMimeType(),
365 PrefsPropsUtil.getInteger(maxHeightPropsKey),
366 PrefsPropsUtil.getInteger(maxWidthPropsKey));
367
368 try {
369 addFileToStore(
370 fileVersion.getCompanyId(), THUMBNAIL_PATH, filePath, file);
371 }
372 finally {
373 FileUtil.delete(file);
374 }
375 }
376
377 private File _scaleImage(
378 RenderedImage renderedImage, String contentType, int height,
379 int width)
380 throws IOException {
381
382 RenderedImage thumbnailRenderedImage = ImageProcessorUtil.scale(
383 renderedImage, height, width);
384
385 byte[] bytes = ImageProcessorUtil.getBytes(
386 thumbnailRenderedImage, contentType);
387
388 return FileUtil.createTempFile(bytes);
389 }
390
391 private void _storeThumbnail(
392 long companyId, long groupId, long fileEntryId, long fileVersionId,
393 long custom1ImageId, long custom2ImageId, InputStream is,
394 String type)
395 throws Exception {
396
397 StringBundler sb = new StringBundler(5);
398
399 sb.append(getPathSegment(groupId, fileEntryId, fileVersionId, false));
400
401 if (custom1ImageId != 0) {
402 sb.append(StringPool.DASH);
403 sb.append(1);
404 }
405 else if (custom2ImageId != 0) {
406 sb.append(StringPool.DASH);
407 sb.append(2);
408 }
409
410 sb.append(StringPool.PERIOD);
411 sb.append(type);
412
413 String filePath = sb.toString();
414
415 File file = null;
416
417 try {
418 file = FileUtil.createTempFile(is);
419
420 addFileToStore(companyId, THUMBNAIL_PATH, filePath, file);
421 }
422 finally {
423 FileUtil.delete(file);
424 }
425 }
426
427 private static Log _log = LogFactoryUtil.getLog(ImageProcessor.class);
428
429 private static ImageProcessor _instance = new ImageProcessor();
430
431 private static List<Long> _fileVersionIds = new Vector<Long>();
432 private static Set<String> _imageMimeTypes = SetUtil.fromArray(
433 PropsValues.DL_FILE_ENTRY_PREVIEW_IMAGE_MIME_TYPES);
434
435 }