1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portlet.imagegallery.lar;
16  
17  import com.liferay.portal.PortalException;
18  import com.liferay.portal.SystemException;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.util.FileUtil;
22  import com.liferay.portal.kernel.util.MapUtil;
23  import com.liferay.portal.kernel.util.StringBundler;
24  import com.liferay.portal.kernel.util.StringPool;
25  import com.liferay.portal.kernel.util.Validator;
26  import com.liferay.portal.kernel.xml.Document;
27  import com.liferay.portal.kernel.xml.Element;
28  import com.liferay.portal.kernel.xml.SAXReaderUtil;
29  import com.liferay.portal.lar.BasePortletDataHandler;
30  import com.liferay.portal.lar.PortletDataContext;
31  import com.liferay.portal.lar.PortletDataException;
32  import com.liferay.portal.lar.PortletDataHandlerBoolean;
33  import com.liferay.portal.lar.PortletDataHandlerControl;
34  import com.liferay.portal.lar.PortletDataHandlerKeys;
35  import com.liferay.portal.model.Image;
36  import com.liferay.portal.service.ServiceContext;
37  import com.liferay.portal.service.persistence.ImageUtil;
38  import com.liferay.portal.util.PortletKeys;
39  import com.liferay.portlet.imagegallery.NoSuchFolderException;
40  import com.liferay.portlet.imagegallery.NoSuchImageException;
41  import com.liferay.portlet.imagegallery.model.IGFolder;
42  import com.liferay.portlet.imagegallery.model.IGImage;
43  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
44  import com.liferay.portlet.imagegallery.service.IGFolderLocalServiceUtil;
45  import com.liferay.portlet.imagegallery.service.IGImageLocalServiceUtil;
46  import com.liferay.portlet.imagegallery.service.persistence.IGFolderUtil;
47  import com.liferay.portlet.imagegallery.service.persistence.IGImageUtil;
48  
49  import java.io.File;
50  
51  import java.util.List;
52  import java.util.Map;
53  import java.util.regex.Pattern;
54  
55  import javax.portlet.PortletPreferences;
56  
57  /**
58   * <a href="IGPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
59   *
60   * @author Bruno Farache
61   * @author Raymond Augé
62   */
63  public class IGPortletDataHandlerImpl extends BasePortletDataHandler {
64  
65      public static void exportImage(
66              PortletDataContext context, Element foldersEl, Element imagesEl,
67              IGImage image)
68          throws PortalException, SystemException {
69  
70          if (!context.isWithinDateRange(image.getModifiedDate())) {
71              return;
72          }
73  
74          exportParentFolder(context, foldersEl, image.getFolderId());
75  
76          String path = getImagePath(context, image);
77  
78          if (context.isPathNotProcessed(path)) {
79              Element imageEl = imagesEl.addElement("image");
80  
81              imageEl.addAttribute("path", path);
82              imageEl.addAttribute("bin-path", getImageBinPath(context, image));
83  
84              if (context.getBooleanParameter(_NAMESPACE, "tags")) {
85                  context.addTagsEntries(IGImage.class, image.getImageId());
86              }
87  
88              image.setUserUuid(image.getUserUuid());
89  
90              Image largeImage = ImageUtil.findByPrimaryKey(
91                  image.getLargeImageId());
92  
93              image.setImageType(largeImage.getType());
94  
95              context.addPermissions(IGImage.class, image.getImageId());
96  
97              context.addZipEntry(
98                  getImageBinPath(context, image), largeImage.getTextObj());
99  
100             context.addZipEntry(path, image);
101         }
102     }
103 
104     public static void importFolder(
105             PortletDataContext context, Map<Long, Long> folderPKs,
106             IGFolder folder)
107         throws Exception {
108 
109         long userId = context.getUserId(folder.getUserUuid());
110         long parentFolderId = MapUtil.getLong(
111             folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
112 
113         ServiceContext serviceContext = new ServiceContext();
114 
115         serviceContext.setAddCommunityPermissions(true);
116         serviceContext.setAddGuestPermissions(true);
117         serviceContext.setCreateDate(folder.getCreateDate());
118         serviceContext.setModifiedDate(folder.getModifiedDate());
119         serviceContext.setScopeGroupId(context.getScopeGroupId());
120 
121         if ((parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) &&
122             (parentFolderId == folder.getParentFolderId())) {
123 
124             String path = getImportFolderPath(context, parentFolderId);
125 
126             IGFolder parentFolder = (IGFolder)context.getZipEntryAsObject(path);
127 
128             importFolder(context, folderPKs, parentFolder);
129 
130             parentFolderId = MapUtil.getLong(
131                 folderPKs, folder.getParentFolderId(),
132                 folder.getParentFolderId());
133         }
134 
135         IGFolder existingFolder = null;
136 
137         try {
138             if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
139                 IGFolderUtil.findByPrimaryKey(parentFolderId);
140             }
141 
142             if (context.getDataStrategy().equals(
143                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
144 
145                 existingFolder = IGFolderUtil.fetchByUUID_G(
146                     folder.getUuid(), context.getScopeGroupId());
147 
148                 if (existingFolder == null) {
149                     String name = getFolderName(
150                         null, context.getCompanyId(), context.getScopeGroupId(),
151                         parentFolderId, folder.getName(), 2);
152 
153                     existingFolder = IGFolderLocalServiceUtil.addFolder(
154                         folder.getUuid(), userId, parentFolderId, name,
155                         folder.getDescription(), serviceContext);
156                 }
157                 else {
158                     String name = getFolderName(
159                         folder.getUuid(), context.getCompanyId(),
160                         context.getScopeGroupId(), parentFolderId,
161                         folder.getName(), 2);
162 
163                     existingFolder = IGFolderLocalServiceUtil.updateFolder(
164                         existingFolder.getFolderId(), parentFolderId, name,
165                         folder.getDescription(), false, serviceContext);
166                 }
167             }
168             else {
169                 String name = getFolderName(
170                     null, context.getCompanyId(), context.getScopeGroupId(),
171                     parentFolderId, folder.getName(), 2);
172 
173                 existingFolder = IGFolderLocalServiceUtil.addFolder(
174                     userId, parentFolderId, name, folder.getDescription(),
175                     serviceContext);
176             }
177 
178             folderPKs.put(folder.getFolderId(), existingFolder.getFolderId());
179 
180             context.importPermissions(
181                 IGFolder.class, folder.getFolderId(),
182                 existingFolder.getFolderId());
183         }
184         catch (NoSuchFolderException nsfe) {
185             _log.error(
186                 "Could not find the parent folder for folder " +
187                     folder.getFolderId());
188         }
189     }
190 
191     public static void importImage(
192             PortletDataContext context, Map<Long, Long> folderPKs,
193             IGImage image, String binPath)
194         throws Exception {
195 
196         long userId = context.getUserId(image.getUserUuid());
197         long folderId = MapUtil.getLong(
198             folderPKs, image.getFolderId(), image.getFolderId());
199 
200         File imageFile = null;
201 
202         byte[] bytes = context.getZipEntryAsByteArray(binPath);
203 
204         if (bytes == null) {
205             _log.error(
206                 "Could not find image file for image " + image.getImageId());
207 
208             return;
209         }
210         else {
211             imageFile = File.createTempFile(
212                 String.valueOf(image.getPrimaryKey()),
213                 StringPool.PERIOD + image.getImageType());
214 
215             FileUtil.write(imageFile, bytes);
216         }
217 
218         String[] tagsEntries = null;
219 
220         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
221             tagsEntries = context.getTagsEntries(
222                 IGImage.class, image.getImageId());
223         }
224 
225         ServiceContext serviceContext = new ServiceContext();
226 
227         serviceContext.setAddCommunityPermissions(true);
228         serviceContext.setAddGuestPermissions(true);
229         serviceContext.setCreateDate(image.getCreateDate());
230         serviceContext.setModifiedDate(image.getModifiedDate());
231         serviceContext.setTagsEntries(tagsEntries);
232 
233         if ((folderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) &&
234             (folderId == image.getFolderId())) {
235 
236             String path = getImportFolderPath(context, folderId);
237 
238             IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
239 
240             importFolder(context, folderPKs, folder);
241 
242             folderId = MapUtil.getLong(
243                 folderPKs, image.getFolderId(), image.getFolderId());
244         }
245 
246         IGImage existingImage = null;
247 
248         try {
249             IGFolderUtil.findByPrimaryKey(folderId);
250 
251             if (context.getDataStrategy().equals(
252                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
253 
254                 try {
255                     existingImage = IGImageUtil.findByUUID_G(
256                         image.getUuid(), context.getScopeGroupId());
257 
258                     existingImage = IGImageLocalServiceUtil.updateImage(
259                         userId, existingImage.getImageId(), folderId,
260                         image.getName(), image.getDescription(), imageFile,
261                         image.getImageType(), serviceContext);
262                 }
263                 catch (NoSuchImageException nsie) {
264                     existingImage = IGImageLocalServiceUtil.addImage(
265                         image.getUuid(), userId, folderId, image.getName(),
266                         image.getDescription(), imageFile, image.getImageType(),
267                         serviceContext);
268                 }
269             }
270             else {
271                 existingImage = IGImageLocalServiceUtil.addImage(
272                     userId, folderId, image.getName(), image.getDescription(),
273                     imageFile, image.getImageType(), serviceContext);
274             }
275 
276             context.importPermissions(
277                 IGImage.class, image.getImageId(), existingImage.getImageId());
278         }
279         catch (NoSuchFolderException nsfe) {
280             _log.error(
281                 "Could not find the parent folder for image " +
282                     image.getImageId());
283         }
284     }
285 
286     public PortletPreferences deleteData(
287             PortletDataContext context, String portletId,
288             PortletPreferences preferences)
289         throws PortletDataException {
290 
291         try {
292             if (!context.addPrimaryKey(
293                     IGPortletDataHandlerImpl.class, "deleteData")) {
294 
295                 IGFolderLocalServiceUtil.deleteFolders(
296                     context.getScopeGroupId());
297             }
298 
299             return null;
300         }
301         catch (Exception e) {
302             throw new PortletDataException(e);
303         }
304     }
305 
306     public String exportData(
307             PortletDataContext context, String portletId,
308             PortletPreferences preferences)
309         throws PortletDataException {
310 
311         try {
312             context.addPermissions(
313                 "com.liferay.portlet.imagegallery", context.getScopeGroupId());
314 
315             Document doc = SAXReaderUtil.createDocument();
316 
317             Element root = doc.addElement("image-gallery");
318 
319             root.addAttribute(
320                 "group-id", String.valueOf(context.getScopeGroupId()));
321 
322             Element foldersEl = root.addElement("folders");
323             Element imagesEl = root.addElement("images");
324 
325             List<IGFolder> folders = IGFolderUtil.findByGroupId(
326                 context.getScopeGroupId());
327 
328             for (IGFolder folder : folders) {
329                 exportFolder(context, foldersEl, imagesEl, folder);
330             }
331 
332             return doc.formattedString();
333         }
334         catch (Exception e) {
335             throw new PortletDataException(e);
336         }
337     }
338 
339     public PortletDataHandlerControl[] getExportControls() {
340         return new PortletDataHandlerControl[] {_foldersAndImages, _tags};
341     }
342 
343     public PortletDataHandlerControl[] getImportControls() {
344         return new PortletDataHandlerControl[] {_foldersAndImages, _tags};
345     }
346 
347     public PortletPreferences importData(
348             PortletDataContext context, String portletId,
349             PortletPreferences preferences, String data)
350         throws PortletDataException {
351 
352         try {
353             context.importPermissions(
354                 "com.liferay.portlet.imagegallery",
355                 context.getSourceGroupId(), context.getScopeGroupId());
356 
357             Document doc = SAXReaderUtil.read(data);
358 
359             Element root = doc.getRootElement();
360 
361             List<Element> folderEls = root.element("folders").elements(
362                 "folder");
363 
364             Map<Long, Long> folderPKs =
365                 (Map<Long, Long>)context.getNewPrimaryKeysMap(IGFolder.class);
366 
367             for (Element folderEl : folderEls) {
368                 String path = folderEl.attributeValue("path");
369 
370                 if (!context.isPathNotProcessed(path)) {
371                     continue;
372                 }
373 
374                 IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
375 
376                 importFolder(context, folderPKs, folder);
377             }
378 
379             List<Element> imageEls = root.element("images").elements("image");
380 
381             for (Element imageEl : imageEls) {
382                 String path = imageEl.attributeValue("path");
383 
384                 if (!context.isPathNotProcessed(path)) {
385                     continue;
386                 }
387 
388                 IGImage image = (IGImage)context.getZipEntryAsObject(path);
389 
390                 String binPath = imageEl.attributeValue("bin-path");
391 
392                 importImage(context, folderPKs, image, binPath);
393             }
394 
395             return null;
396         }
397         catch (Exception e) {
398             throw new PortletDataException(e);
399         }
400     }
401 
402     protected static void exportFolder(
403             PortletDataContext context, Element foldersEl, Element imagesEl,
404             IGFolder folder)
405         throws PortalException, SystemException {
406 
407         if (context.isWithinDateRange(folder.getModifiedDate())) {
408             exportParentFolder(context, foldersEl, folder.getParentFolderId());
409 
410             String path = getFolderPath(context, folder.getFolderId());
411 
412             if (context.isPathNotProcessed(path)) {
413                 Element folderEl = foldersEl.addElement("folder");
414 
415                 folderEl.addAttribute("path", path);
416 
417                 folder.setUserUuid(folder.getUserUuid());
418 
419                 context.addPermissions(IGFolder.class, folder.getFolderId());
420 
421                 context.addZipEntry(path, folder);
422             }
423         }
424 
425         List<IGImage> images = IGImageUtil.findByFolderId(folder.getFolderId());
426 
427         for (IGImage image : images) {
428             exportImage(context, foldersEl, imagesEl, image);
429         }
430     }
431 
432     protected static void exportParentFolder(
433             PortletDataContext context, Element foldersEl, long folderId)
434         throws PortalException, SystemException {
435 
436         if (folderId == IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
437             return;
438         }
439 
440         IGFolder folder = IGFolderUtil.findByPrimaryKey(folderId);
441 
442         exportParentFolder(context, foldersEl, folder.getParentFolderId());
443 
444         String path = getFolderPath(context, folder.getFolderId());
445 
446         if (context.isPathNotProcessed(path)) {
447             Element folderEl = foldersEl.addElement("folder");
448 
449             folderEl.addAttribute("path", path);
450 
451             folder.setUserUuid(folder.getUserUuid());
452 
453             context.addPermissions(IGFolder.class, folder.getFolderId());
454 
455             context.addZipEntry(path, folder);
456         }
457     }
458 
459     protected static String getFolderName(
460             String uuid, long companyId, long groupId, long parentFolderId,
461             String name, int count)
462         throws SystemException {
463 
464         IGFolder folder = IGFolderUtil.fetchByG_P_N(
465             groupId, parentFolderId, name);
466 
467         if (folder == null) {
468             return name;
469         }
470 
471         if (Validator.isNotNull(uuid) && uuid.equals(folder.getUuid())) {
472             return name;
473         }
474 
475         if (Pattern.matches(".* \\(\\d+\\)", name)) {
476             int pos = name.lastIndexOf(" (");
477 
478             name = name.substring(0, pos);
479         }
480 
481         StringBundler sb = new StringBundler(5);
482 
483         sb.append(name);
484         sb.append(StringPool.SPACE);
485         sb.append(StringPool.OPEN_PARENTHESIS);
486         sb.append(count);
487         sb.append(StringPool.CLOSE_PARENTHESIS);
488 
489         name = sb.toString();
490 
491         return getFolderName(
492             uuid, companyId, groupId, parentFolderId, name, ++count);
493     }
494 
495     protected static String getFolderPath(
496         PortletDataContext context, long folderId) {
497 
498         StringBundler sb = new StringBundler(4);
499 
500         sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
501         sb.append("/folders/");
502         sb.append(folderId);
503         sb.append(".xml");
504 
505         return sb.toString();
506     }
507 
508     protected static String getImageBinPath(
509         PortletDataContext context, IGImage image) {
510 
511         StringBundler sb = new StringBundler(5);
512 
513         sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
514         sb.append("/bin/");
515         sb.append(image.getImageId());
516         sb.append(StringPool.PERIOD);
517         sb.append(image.getImageType());
518 
519         return sb.toString();
520     }
521 
522     protected static String getImagePath(
523         PortletDataContext context, IGImage image) {
524 
525         StringBundler sb = new StringBundler(4);
526 
527         sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
528         sb.append("/images/");
529         sb.append(image.getImageId());
530         sb.append(".xml");
531 
532         return sb.toString();
533     }
534 
535     protected static String getImportFolderPath(
536         PortletDataContext context, long folderId) {
537 
538         StringBundler sb = new StringBundler(4);
539 
540         sb.append(context.getSourcePortletPath(PortletKeys.IMAGE_GALLERY));
541         sb.append("/folders/");
542         sb.append(folderId);
543         sb.append(".xml");
544 
545         return sb.toString();
546     }
547 
548     private static final String _NAMESPACE = "image_gallery";
549 
550     private static final PortletDataHandlerBoolean _foldersAndImages =
551         new PortletDataHandlerBoolean(
552             _NAMESPACE, "folders-and-images", true, true);
553 
554     private static final PortletDataHandlerBoolean _tags =
555         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
556 
557     private static Log _log = LogFactoryUtil.getLog(
558         IGPortletDataHandlerImpl.class);
559 
560 }