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