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