001
014
015 package com.liferay.portlet.imagegallery.lar;
016
017 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
018 import com.liferay.portal.kernel.lar.PortletDataContext;
019 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
020 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.FileUtil;
024 import com.liferay.portal.kernel.util.MapUtil;
025 import com.liferay.portal.kernel.util.StringBundler;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.xml.Document;
028 import com.liferay.portal.kernel.xml.Element;
029 import com.liferay.portal.kernel.xml.SAXReaderUtil;
030 import com.liferay.portal.model.Image;
031 import com.liferay.portal.service.ServiceContext;
032 import com.liferay.portal.service.persistence.ImageUtil;
033 import com.liferay.portal.util.PortletKeys;
034 import com.liferay.portal.util.PropsValues;
035 import com.liferay.portlet.imagegallery.DuplicateImageNameException;
036 import com.liferay.portlet.imagegallery.model.IGFolder;
037 import com.liferay.portlet.imagegallery.model.IGFolderConstants;
038 import com.liferay.portlet.imagegallery.model.IGImage;
039 import com.liferay.portlet.imagegallery.service.IGFolderLocalServiceUtil;
040 import com.liferay.portlet.imagegallery.service.IGImageLocalServiceUtil;
041 import com.liferay.portlet.imagegallery.service.persistence.IGFolderUtil;
042 import com.liferay.portlet.imagegallery.service.persistence.IGImageUtil;
043 import com.liferay.util.PwdGenerator;
044
045 import java.io.File;
046
047 import java.util.List;
048 import java.util.Map;
049 import java.util.regex.Pattern;
050
051 import javax.portlet.PortletPreferences;
052
053
058 public class IGPortletDataHandlerImpl extends BasePortletDataHandler {
059
060 public static void exportImage(
061 PortletDataContext context, Element foldersElement,
062 Element imagesElement, IGImage image, boolean checkDateRange)
063 throws Exception {
064
065 if (checkDateRange &&
066 !context.isWithinDateRange(image.getModifiedDate())) {
067
068 return;
069 }
070
071 if (foldersElement != null) {
072 exportParentFolder(context, foldersElement, image.getFolderId());
073 }
074
075 String path = getImagePath(context, image);
076
077 if (context.isPathNotProcessed(path)) {
078 Element imageElement = imagesElement.addElement("image");
079
080 imageElement.addAttribute("path", path);
081 imageElement.addAttribute(
082 "bin-path", getImageBinPath(context, image));
083
084 if (context.getBooleanParameter(_NAMESPACE, "categories")) {
085 context.addAssetCategories(IGImage.class, image.getImageId());
086 }
087
088 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
089 context.addRatingsEntries(IGImage.class, image.getImageId());
090 }
091
092 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
093 context.addAssetTags(IGImage.class, image.getImageId());
094 }
095
096 image.setUserUuid(image.getUserUuid());
097
098 Image largeImage = ImageUtil.findByPrimaryKey(
099 image.getLargeImageId());
100
101 image.setImageType(largeImage.getType());
102
103 context.addPermissions(IGImage.class, image.getImageId());
104
105 context.addZipEntry(
106 getImageBinPath(context, image), largeImage.getTextObj());
107
108 context.addZipEntry(path, image);
109 }
110 }
111
112 public static String getImagePath(
113 PortletDataContext context, IGImage image) {
114
115 StringBundler sb = new StringBundler(4);
116
117 sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
118 sb.append("/images/");
119 sb.append(image.getImageId());
120 sb.append(".xml");
121
122 return sb.toString();
123 }
124
125 public static void importFolder(
126 PortletDataContext context, Element folderElement)
127 throws Exception {
128
129 String path = folderElement.attributeValue("path");
130
131 if (!context.isPathNotProcessed(path)) {
132 return;
133 }
134
135 IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
136
137 importFolder(context, folder);
138 }
139
140 public static void importImage(
141 PortletDataContext context, Element imageElement)
142 throws Exception {
143
144 String path = imageElement.attributeValue("path");
145
146 String binPath = imageElement.attributeValue("bin-path");
147
148 if (!context.isPathNotProcessed(path)) {
149 return;
150 }
151
152 IGImage image = (IGImage)context.getZipEntryAsObject(path);
153
154 importImage(context, image, binPath);
155 }
156
157 public PortletDataHandlerControl[] getExportControls() {
158 return new PortletDataHandlerControl[] {
159 _foldersAndImages, _categories, _ratings, _tags
160 };
161 }
162
163 public PortletDataHandlerControl[] getImportControls() {
164 return new PortletDataHandlerControl[] {
165 _foldersAndImages, _categories, _ratings, _tags
166 };
167 }
168
169 public boolean isAlwaysExportable() {
170 return _ALWAYS_EXPORTABLE;
171 }
172
173 public boolean isPublishToLiveByDefault() {
174 return PropsValues.DL_PUBLISH_TO_LIVE_BY_DEFAULT;
175 }
176
177 protected static void importFolder(
178 PortletDataContext context, IGFolder folder)
179 throws Exception {
180
181 long userId = context.getUserId(folder.getUserUuid());
182
183 Map<Long, Long> folderPKs =
184 (Map<Long, Long>)context.getNewPrimaryKeysMap(IGFolder.class);
185
186 long parentFolderId = MapUtil.getLong(
187 folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
188
189 ServiceContext serviceContext = new ServiceContext();
190
191 serviceContext.setAddCommunityPermissions(true);
192 serviceContext.setAddGuestPermissions(true);
193 serviceContext.setCreateDate(folder.getCreateDate());
194 serviceContext.setModifiedDate(folder.getModifiedDate());
195 serviceContext.setScopeGroupId(context.getScopeGroupId());
196
197 if ((parentFolderId != IGFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
198 (parentFolderId == folder.getParentFolderId())) {
199
200 String path = getImportFolderPath(context, parentFolderId);
201
202 IGFolder parentFolder = (IGFolder)context.getZipEntryAsObject(path);
203
204 importFolder(context, parentFolder);
205
206 parentFolderId = MapUtil.getLong(
207 folderPKs, folder.getParentFolderId(),
208 folder.getParentFolderId());
209 }
210
211 IGFolder importedFolder = null;
212
213 if (context.isDataStrategyMirror()) {
214 IGFolder existingFolder = IGFolderUtil.fetchByUUID_G(
215 folder.getUuid(), context.getScopeGroupId());
216
217 if (existingFolder == null) {
218 String name = getFolderName(
219 context.getCompanyId(), context.getScopeGroupId(),
220 parentFolderId, folder.getName(), 2);
221
222 serviceContext.setUuid(folder.getUuid());
223
224 importedFolder = IGFolderLocalServiceUtil.addFolder(
225 userId, parentFolderId, name, folder.getDescription(),
226 serviceContext);
227 }
228 else {
229 importedFolder = IGFolderLocalServiceUtil.updateFolder(
230 existingFolder.getFolderId(), parentFolderId,
231 folder.getName(), folder.getDescription(), false,
232 serviceContext);
233 }
234 }
235 else {
236 String name = getFolderName(
237 context.getCompanyId(), context.getScopeGroupId(),
238 parentFolderId, folder.getName(), 2);
239
240 importedFolder = IGFolderLocalServiceUtil.addFolder(
241 userId, parentFolderId, name, folder.getDescription(),
242 serviceContext);
243 }
244
245 folderPKs.put(folder.getFolderId(), importedFolder.getFolderId());
246
247 context.importPermissions(
248 IGFolder.class, folder.getFolderId(), importedFolder.getFolderId());
249 }
250
251 protected static void importImage(
252 PortletDataContext context, IGImage image, String binPath)
253 throws Exception {
254
255 long userId = context.getUserId(image.getUserUuid());
256
257 Map<Long, Long> folderPKs =
258 (Map<Long, Long>)context.getNewPrimaryKeysMap(IGFolder.class);
259
260 long folderId = MapUtil.getLong(
261 folderPKs, image.getFolderId(), image.getFolderId());
262
263 File imageFile = null;
264
265 byte[] bytes = context.getZipEntryAsByteArray(binPath);
266
267 if (bytes == null) {
268 _log.error(
269 "Could not find image file for image " + image.getImageId());
270
271 return;
272 }
273 else {
274 imageFile = File.createTempFile(
275 String.valueOf(image.getPrimaryKey()),
276 StringPool.PERIOD + image.getImageType());
277
278 FileUtil.write(imageFile, bytes);
279 }
280
281 long[] assetCategoryIds = null;
282 String[] assetTagNames = null;
283
284 if (context.getBooleanParameter(_NAMESPACE, "categories")) {
285 assetCategoryIds = context.getAssetCategoryIds(
286 IGImage.class, image.getImageId());
287 }
288
289 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
290 assetTagNames = context.getAssetTagNames(
291 IGImage.class, image.getImageId());
292 }
293
294 ServiceContext serviceContext = new ServiceContext();
295
296 serviceContext.setAddCommunityPermissions(true);
297 serviceContext.setAddGuestPermissions(true);
298 serviceContext.setAssetCategoryIds(assetCategoryIds);
299 serviceContext.setAssetTagNames(assetTagNames);
300 serviceContext.setCreateDate(image.getCreateDate());
301 serviceContext.setModifiedDate(image.getModifiedDate());
302
303 if ((folderId != IGFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
304 (folderId == image.getFolderId())) {
305
306 String path = getImportFolderPath(context, folderId);
307
308 IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
309
310 importFolder(context, folder);
311
312 folderId = MapUtil.getLong(
313 folderPKs, image.getFolderId(), image.getFolderId());
314 }
315
316 IGImage importedImage = null;
317
318 if (context.isDataStrategyMirror()) {
319 IGImage existingImage = IGImageUtil.fetchByUUID_G(
320 image.getUuid(), context.getScopeGroupId());
321
322 if (existingImage == null) {
323 serviceContext.setUuid(image.getUuid());
324
325 importedImage = IGImageLocalServiceUtil.addImage(
326 userId, context.getScopeGroupId(), folderId,
327 image.getName(), image.getDescription(), imageFile,
328 image.getImageType(), serviceContext);
329 }
330 else {
331 importedImage = IGImageLocalServiceUtil.updateImage(
332 userId, existingImage.getImageId(),
333 context.getScopeGroupId(), folderId, image.getName(),
334 image.getDescription(), imageFile, image.getImageType(),
335 serviceContext);
336 }
337 }
338 else {
339 String name = image.getName();
340
341 try {
342 importedImage = IGImageLocalServiceUtil.addImage(
343 userId, context.getScopeGroupId(), folderId, name,
344 image.getDescription(), imageFile, image.getImageType(),
345 serviceContext);
346 }
347 catch (DuplicateImageNameException dine) {
348 String[] nameParts = name.split("\\.", 2);
349
350 name = nameParts[0] + PwdGenerator.getPassword();
351
352 if (nameParts.length > 1) {
353 name += StringPool.PERIOD + nameParts[1];
354 }
355
356 importedImage = IGImageLocalServiceUtil.addImage(
357 userId, context.getScopeGroupId(), folderId, name,
358 image.getDescription(), imageFile, image.getImageType(),
359 serviceContext);
360 }
361 }
362
363 context.importPermissions(
364 IGImage.class, image.getImageId(), importedImage.getImageId());
365
366 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
367 context.importRatingsEntries(
368 IGImage.class, image.getImageId(), importedImage.getImageId());
369 }
370
371 Map<Long, Long> igImagePKs =
372 (Map<Long, Long>)context.getNewPrimaryKeysMap(IGImage.class);
373
374 igImagePKs.put(image.getImageId(), importedImage.getImageId());
375 }
376
377 protected static void exportFolder(
378 PortletDataContext context, Element foldersElement,
379 Element imagesElement, IGFolder folder)
380 throws Exception {
381
382 if (context.isWithinDateRange(folder.getModifiedDate())) {
383 exportParentFolder(
384 context, foldersElement, folder.getParentFolderId());
385
386 String path = getFolderPath(context, folder.getFolderId());
387
388 if (context.isPathNotProcessed(path)) {
389 Element folderElement = foldersElement.addElement("folder");
390
391 folderElement.addAttribute("path", path);
392
393 folder.setUserUuid(folder.getUserUuid());
394
395 context.addPermissions(IGFolder.class, folder.getFolderId());
396
397 context.addZipEntry(path, folder);
398 }
399 }
400
401 List<IGImage> images = IGImageUtil.findByG_F(
402 folder.getGroupId(), folder.getFolderId());
403
404 for (IGImage image : images) {
405 exportImage(context, foldersElement, imagesElement, image, true);
406 }
407 }
408
409 protected static void exportParentFolder(
410 PortletDataContext context, Element foldersElement, long folderId)
411 throws Exception {
412
413 if (folderId == IGFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
414 return;
415 }
416
417 IGFolder folder = IGFolderUtil.findByPrimaryKey(folderId);
418
419 exportParentFolder(context, foldersElement, folder.getParentFolderId());
420
421 String path = getFolderPath(context, folder.getFolderId());
422
423 if (context.isPathNotProcessed(path)) {
424 Element folderElement = foldersElement.addElement("folder");
425
426 folderElement.addAttribute("path", path);
427
428 folder.setUserUuid(folder.getUserUuid());
429
430 context.addPermissions(IGFolder.class, folder.getFolderId());
431
432 context.addZipEntry(path, folder);
433 }
434 }
435
436 protected static String getFolderName(
437 long companyId, long groupId, long parentFolderId, String name,
438 int count)
439 throws Exception {
440
441 IGFolder folder = IGFolderUtil.fetchByG_P_N(
442 groupId, parentFolderId, name);
443
444 if (folder == null) {
445 return name;
446 }
447
448 if (Pattern.matches(".* \\(\\d+\\)", name)) {
449 int pos = name.lastIndexOf(" (");
450
451 name = name.substring(0, pos);
452 }
453
454 StringBundler sb = new StringBundler(5);
455
456 sb.append(name);
457 sb.append(StringPool.SPACE);
458 sb.append(StringPool.OPEN_PARENTHESIS);
459 sb.append(count);
460 sb.append(StringPool.CLOSE_PARENTHESIS);
461
462 name = sb.toString();
463
464 return getFolderName(companyId, groupId, parentFolderId, name, ++count);
465 }
466
467 protected static String getFolderPath(
468 PortletDataContext context, long folderId) {
469
470 StringBundler sb = new StringBundler(4);
471
472 sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
473 sb.append("/folders/");
474 sb.append(folderId);
475 sb.append(".xml");
476
477 return sb.toString();
478 }
479
480 protected static String getImageBinPath(
481 PortletDataContext context, IGImage image) {
482
483 StringBundler sb = new StringBundler(5);
484
485 sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
486 sb.append("/bin/");
487 sb.append(image.getImageId());
488 sb.append(StringPool.PERIOD);
489 sb.append(image.getImageType());
490
491 return sb.toString();
492 }
493
494 protected static String getImportFolderPath(
495 PortletDataContext context, long folderId) {
496
497 StringBundler sb = new StringBundler(4);
498
499 sb.append(context.getSourcePortletPath(PortletKeys.IMAGE_GALLERY));
500 sb.append("/folders/");
501 sb.append(folderId);
502 sb.append(".xml");
503
504 return sb.toString();
505 }
506
507 protected PortletPreferences doDeleteData(
508 PortletDataContext context, String portletId,
509 PortletPreferences preferences)
510 throws Exception {
511
512 if (!context.addPrimaryKey(
513 IGPortletDataHandlerImpl.class, "deleteData")) {
514
515 IGFolderLocalServiceUtil.deleteFolders(context.getScopeGroupId());
516
517 IGImageLocalServiceUtil.deleteImages(
518 context.getScopeGroupId(),
519 IGFolderConstants.DEFAULT_PARENT_FOLDER_ID);
520 }
521
522 return null;
523 }
524
525 protected String doExportData(
526 PortletDataContext context, String portletId,
527 PortletPreferences preferences)
528 throws Exception {
529
530 context.addPermissions(
531 "com.liferay.portlet.imagegallery", context.getScopeGroupId());
532
533 Document document = SAXReaderUtil.createDocument();
534
535 Element rootElement = document.addElement("image-gallery");
536
537 rootElement.addAttribute(
538 "group-id", String.valueOf(context.getScopeGroupId()));
539
540 Element foldersElement = rootElement.addElement("folders");
541 Element imagesElement = rootElement.addElement("images");
542
543 List<IGFolder> folders = IGFolderUtil.findByGroupId(
544 context.getScopeGroupId());
545
546 for (IGFolder folder : folders) {
547 exportFolder(context, foldersElement, imagesElement, folder);
548 }
549
550 List<IGImage> images = IGImageUtil.findByG_F(
551 context.getScopeGroupId(),
552 IGFolderConstants.DEFAULT_PARENT_FOLDER_ID);
553
554 for (IGImage image : images) {
555 exportImage(context, null, imagesElement, image, true);
556 }
557
558 return document.formattedString();
559 }
560
561 protected PortletPreferences doImportData(
562 PortletDataContext context, String portletId,
563 PortletPreferences preferences, String data)
564 throws Exception {
565
566 context.importPermissions(
567 "com.liferay.portlet.imagegallery",
568 context.getSourceGroupId(), context.getScopeGroupId());
569
570 Document document = SAXReaderUtil.read(data);
571
572 Element rootElement = document.getRootElement();
573
574 Element foldersElement = rootElement.element("folders");
575
576 List<Element> folderElements = foldersElement.elements("folder");
577
578 for (Element folderElement : folderElements) {
579 String path = folderElement.attributeValue("path");
580
581 if (!context.isPathNotProcessed(path)) {
582 continue;
583 }
584
585 IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
586
587 importFolder(context, folder);
588 }
589
590 Element imagesElement = rootElement.element("images");
591
592 List<Element> imageElements = imagesElement.elements("image");
593
594 for (Element imageElement : imageElements) {
595 String path = imageElement.attributeValue("path");
596
597 if (!context.isPathNotProcessed(path)) {
598 continue;
599 }
600
601 IGImage image = (IGImage)context.getZipEntryAsObject(path);
602
603 String binPath = imageElement.attributeValue("bin-path");
604
605 importImage(context, image, binPath);
606 }
607
608 return null;
609 }
610
611 private static final boolean _ALWAYS_EXPORTABLE = true;
612
613 private static final String _NAMESPACE = "image_gallery";
614
615 private static Log _log = LogFactoryUtil.getLog(
616 IGPortletDataHandlerImpl.class);
617
618 private static PortletDataHandlerBoolean _categories =
619 new PortletDataHandlerBoolean(_NAMESPACE, "categories");
620
621 private static PortletDataHandlerBoolean _foldersAndImages =
622 new PortletDataHandlerBoolean(
623 _NAMESPACE, "folders-and-images", true, true);
624
625 private static PortletDataHandlerBoolean _ratings =
626 new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
627
628 private static PortletDataHandlerBoolean _tags =
629 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
630
631 }