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