1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.imagegallery.lar;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.lar.PortletDataContext;
28  import com.liferay.portal.kernel.lar.PortletDataException;
29  import com.liferay.portal.kernel.lar.PortletDataHandler;
30  import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
31  import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
32  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
33  import com.liferay.portal.kernel.util.FileUtil;
34  import com.liferay.portal.kernel.util.StringPool;
35  import com.liferay.portal.model.Image;
36  import com.liferay.portal.service.persistence.ImageUtil;
37  import com.liferay.portal.util.DocumentUtil;
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.IGImageFinderUtil;
48  import com.liferay.portlet.imagegallery.service.persistence.IGImageUtil;
49  import com.liferay.util.MapUtil;
50  import com.liferay.util.xml.XMLFormatter;
51  
52  import java.io.File;
53  
54  import java.util.List;
55  import java.util.Map;
56  import java.util.regex.Pattern;
57  
58  import javax.portlet.PortletPreferences;
59  
60  import org.apache.commons.logging.Log;
61  import org.apache.commons.logging.LogFactory;
62  
63  import org.dom4j.Document;
64  import org.dom4j.DocumentHelper;
65  import org.dom4j.Element;
66  
67  /**
68   * <a href="IGPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
69   *
70   * @author Bruno Farache
71   * @author Raymond Augé
72   *
73   */
74  public class IGPortletDataHandlerImpl implements PortletDataHandler {
75  
76      public static void exportImage(
77              PortletDataContext context, Element foldersEl, Element imagesEl,
78              IGImage image)
79          throws PortalException, SystemException {
80  
81          if (!context.isWithinDateRange(image.getModifiedDate())) {
82              return;
83          }
84  
85          String path = getImagePath(context, image);
86  
87          Element imageEl = imagesEl.addElement("image");
88  
89          imageEl.addAttribute("path", path);
90          imageEl.addAttribute("bin-path", getImageBinPath(context, image));
91  
92          if (context.isPathNotProcessed(path)) {
93              if (context.getBooleanParameter(_NAMESPACE, "tags")) {
94                  context.addTagsEntries(IGImage.class, image.getImageId());
95              }
96  
97              image.setUserUuid(image.getUserUuid());
98  
99              Image largeImage = ImageUtil.findByPrimaryKey(
100                 image.getLargeImageId());
101 
102             image.setImageType(largeImage.getType());
103 
104             context.addZipEntry(
105                 getImageBinPath(context, image), largeImage.getTextObj());
106 
107             context.addZipEntry(path, image);
108         }
109 
110         exportParentFolder(context, foldersEl, image.getFolderId());
111     }
112 
113     public static void importFolder(
114             PortletDataContext context, Map<Long, Long> folderPKs,
115             IGFolder folder)
116         throws Exception {
117 
118         long userId = context.getUserId(folder.getUserUuid());
119         long plid = context.getPlid();
120         long parentFolderId = MapUtil.getLong(
121             folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
122 
123         boolean addCommunityPermissions = true;
124         boolean addGuestPermissions = true;
125 
126         IGFolder existingFolder = null;
127 
128         try {
129             if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
130                 IGFolderUtil.findByPrimaryKey(parentFolderId);
131             }
132 
133             if (context.getDataStrategy().equals(
134                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
135 
136                 existingFolder = IGFolderUtil.fetchByUUID_G(
137                     folder.getUuid(), context.getGroupId());
138 
139                 if (existingFolder == null) {
140                     String name = getFolderName(
141                         context.getCompanyId(), context.getGroupId(),
142                         parentFolderId, folder.getName(), 2);
143 
144                     existingFolder = IGFolderLocalServiceUtil.addFolder(
145                         folder.getUuid(), userId, plid, parentFolderId,
146                         name, folder.getDescription(), addCommunityPermissions,
147                         addGuestPermissions);
148                 }
149                 else {
150                     existingFolder =
151                         IGFolderLocalServiceUtil.updateFolder(
152                         existingFolder.getFolderId(), parentFolderId,
153                         folder.getName(), folder.getDescription(),
154                         false);
155                 }
156             }
157             else {
158                 String name = getFolderName(
159                     context.getCompanyId(), context.getGroupId(),
160                     parentFolderId, folder.getName(), 2);
161 
162                 existingFolder = IGFolderLocalServiceUtil.addFolder(
163                     userId, plid, parentFolderId, name, folder.getDescription(),
164                     addCommunityPermissions, addGuestPermissions);
165             }
166 
167             folderPKs.put(folder.getFolderId(), existingFolder.getFolderId());
168         }
169         catch (NoSuchFolderException nsfe) {
170             _log.error(
171                 "Could not find the parent folder for folder " +
172                     folder.getFolderId());
173         }
174     }
175 
176     public static void importImage(
177             PortletDataContext context, Map<Long, Long> folderPKs,
178             IGImage image, String binPath)
179         throws Exception {
180 
181         long userId = context.getUserId(image.getUserUuid());
182         long folderId = MapUtil.getLong(
183             folderPKs, image.getFolderId(), image.getFolderId());
184 
185         File imageFile = null;
186 
187         byte[] bytes = context.getZipEntryAsByteArray(binPath);
188 
189         if (bytes == null) {
190             _log.error(
191                 "Could not find image file for image " + image.getImageId());
192 
193             return;
194         }
195         else {
196             imageFile = File.createTempFile(
197                 String.valueOf(image.getPrimaryKey()),
198                 StringPool.PERIOD + image.getImageType());
199 
200             FileUtil.write(imageFile, bytes);
201         }
202 
203         String[] tagsEntries = null;
204 
205         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
206             tagsEntries = context.getTagsEntries(
207                 IGImage.class, image.getImageId());
208         }
209 
210         boolean addCommunityPermissions = true;
211         boolean addGuestPermissions = true;
212 
213         IGImage existingImage = null;
214 
215         try {
216             IGFolderUtil.findByPrimaryKey(folderId);
217 
218             if (context.getDataStrategy().equals(
219                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
220 
221                 try {
222                     existingImage = IGImageFinderUtil.findByUuid_G(
223                         image.getUuid(), context.getGroupId());
224 
225                     IGImageLocalServiceUtil.updateImage(
226                         userId, existingImage.getImageId(), folderId,
227                         image.getName(), image.getDescription(), imageFile,
228                         image.getImageType(), tagsEntries);
229                 }
230                 catch (NoSuchImageException nsie) {
231                     IGImageLocalServiceUtil.addImage(
232                         image.getUuid(), userId, folderId,
233                         image.getName(), image.getDescription(), imageFile,
234                         image.getImageType(), tagsEntries,
235                         addCommunityPermissions, addGuestPermissions);
236                 }
237             }
238             else {
239                 IGImageLocalServiceUtil.addImage(
240                     userId, folderId, image.getName(),
241                     image.getDescription(), imageFile, image.getImageType(),
242                     tagsEntries, addCommunityPermissions, addGuestPermissions);
243             }
244         }
245         catch (NoSuchFolderException nsfe) {
246             _log.error(
247                 "Could not find the parent folder for image " +
248                     image.getImageId());
249         }
250     }
251 
252     public PortletPreferences deleteData(
253             PortletDataContext context, String portletId,
254             PortletPreferences prefs)
255         throws PortletDataException {
256 
257         try {
258             if (!context.addPrimaryKey(
259                     IGPortletDataHandlerImpl.class, "deleteData")) {
260 
261                 IGFolderLocalServiceUtil.deleteFolders(context.getGroupId());
262             }
263 
264             return null;
265         }
266         catch (Exception e) {
267             throw new PortletDataException(e);
268         }
269     }
270 
271     public String exportData(
272             PortletDataContext context, String portletId,
273             PortletPreferences prefs)
274         throws PortletDataException {
275 
276         try {
277             Document doc = DocumentHelper.createDocument();
278 
279             Element root = doc.addElement("image-gallery");
280 
281             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
282 
283             Element foldersEl = root.addElement("folders");
284             Element imagesEl = root.addElement("images");
285 
286             List<IGFolder> folders = IGFolderUtil.findByGroupId(
287                 context.getGroupId());
288 
289             for (IGFolder folder : folders) {
290                 exportFolder(context, foldersEl, imagesEl, folder);
291             }
292 
293             return XMLFormatter.toString(doc);
294         }
295         catch (Exception e) {
296             throw new PortletDataException(e);
297         }
298     }
299 
300     public PortletDataHandlerControl[] getExportControls() {
301         return new PortletDataHandlerControl[] {_foldersAndImages, _tags};
302     }
303 
304     public PortletDataHandlerControl[] getImportControls() {
305         return new PortletDataHandlerControl[] {_foldersAndImages, _tags};
306     }
307 
308     public PortletPreferences importData(
309             PortletDataContext context, String portletId,
310             PortletPreferences prefs, String data)
311         throws PortletDataException {
312 
313         try {
314             Document doc = DocumentUtil.readDocumentFromXML(data);
315 
316             Element root = doc.getRootElement();
317 
318             List<Element> folderEls = root.element("folders").elements(
319                 "folder");
320 
321             Map<Long, Long> folderPKs = context.getNewPrimaryKeysMap(
322                 IGFolder.class);
323 
324             for (Element folderEl : folderEls) {
325                 String path = folderEl.attributeValue("path");
326 
327                 if (context.isPathNotProcessed(path)) {
328                     IGFolder folder = (IGFolder)context.getZipEntryAsObject(
329                         path);
330 
331                     importFolder(context, folderPKs, folder);
332                 }
333             }
334 
335             List<Element> imageEls = root.element("images").elements("image");
336 
337             for (Element imageEl : imageEls) {
338                 String path = imageEl.attributeValue("path");
339                 String binPath = imageEl.attributeValue("bin-path");
340 
341                 if (context.isPathNotProcessed(path)) {
342                     IGImage image = (IGImage)context.getZipEntryAsObject(path);
343 
344                     importImage(context, folderPKs, image, binPath);
345                 }
346             }
347 
348             return null;
349         }
350         catch (Exception e) {
351             throw new PortletDataException(e);
352         }
353     }
354 
355     public boolean isPublishToLiveByDefault() {
356         return false;
357     }
358 
359     protected static void exportFolder(
360             PortletDataContext context, Element foldersEl, Element imagesEl,
361             IGFolder folder)
362         throws PortalException, SystemException {
363 
364         if (context.isWithinDateRange(folder.getModifiedDate())) {
365             String path = getFolderPath(context, folder);
366 
367             Element folderEl = foldersEl.addElement("folder");
368 
369             folderEl.addAttribute("path", path);
370 
371             if (context.isPathNotProcessed(path)) {
372                 folder.setUserUuid(folder.getUserUuid());
373 
374                 context.addZipEntry(path, folder);
375             }
376 
377             exportParentFolder(context, foldersEl, folder.getParentFolderId());
378         }
379 
380         List<IGImage> images = IGImageUtil.findByFolderId(folder.getFolderId());
381 
382         for (IGImage image : images) {
383             exportImage(context, foldersEl, imagesEl, image);
384         }
385     }
386 
387     protected static void exportParentFolder(
388             PortletDataContext context, Element foldersEl, long folderId)
389         throws PortalException, SystemException {
390 
391         if (folderId == IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
392             return;
393         }
394 
395         IGFolder folder = IGFolderUtil.findByPrimaryKey(folderId);
396 
397         String path = getFolderPath(context, folder);
398 
399         Element folderEl = foldersEl.addElement("folder");
400 
401         folderEl.addAttribute("path", path);
402 
403         if (context.isPathNotProcessed(path)) {
404             folder.setUserUuid(folder.getUserUuid());
405 
406             context.addZipEntry(path, folder);
407         }
408 
409         exportParentFolder(context, foldersEl, folder.getParentFolderId());
410     }
411 
412     protected static String getFolderName(
413             long companyId, long groupId, long parentFolderId, String name,
414             int count)
415         throws SystemException {
416 
417         IGFolder folder = IGFolderUtil.fetchByG_P_N(
418             groupId, parentFolderId, name);
419 
420         if (folder == null) {
421             return name;
422         }
423 
424         if (Pattern.matches(".* \\(\\d+\\)", name)) {
425             int pos = name.lastIndexOf(" (");
426 
427             name = name.substring(0, pos);
428         }
429 
430         StringBuilder sb = new StringBuilder();
431 
432         sb.append(name);
433         sb.append(StringPool.SPACE);
434         sb.append(StringPool.OPEN_PARENTHESIS);
435         sb.append(count);
436         sb.append(StringPool.CLOSE_PARENTHESIS);
437 
438         name = sb.toString();
439 
440         return getFolderName(companyId, groupId, parentFolderId, name, ++count);
441     }
442 
443     protected static String getFolderPath(
444         PortletDataContext context, IGFolder folder) {
445 
446         StringBuilder sb = new StringBuilder();
447 
448         sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
449         sb.append("/folders/");
450         sb.append(folder.getFolderId());
451         sb.append(".xml");
452 
453         return sb.toString();
454     }
455 
456     protected static String getImageBinPath(
457         PortletDataContext context, IGImage image) {
458 
459         StringBuilder sb = new StringBuilder();
460 
461         sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
462         sb.append("/bin/");
463         sb.append(image.getImageId());
464         sb.append(StringPool.PERIOD);
465         sb.append(image.getImageType());
466 
467         return sb.toString();
468     }
469 
470     protected static String getImagePath(
471         PortletDataContext context, IGImage image) {
472 
473         StringBuilder sb = new StringBuilder();
474 
475         sb.append(context.getPortletPath(PortletKeys.IMAGE_GALLERY));
476         sb.append("/images/");
477         sb.append(image.getImageId());
478         sb.append(".xml");
479 
480         return sb.toString();
481     }
482 
483     private static final String _NAMESPACE = "image_gallery";
484 
485     private static final PortletDataHandlerBoolean _foldersAndImages =
486         new PortletDataHandlerBoolean(
487             _NAMESPACE, "folders-and-images", true, true);
488 
489     private static final PortletDataHandlerBoolean _tags =
490         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
491 
492     private static Log _log = LogFactory.getLog(IGPortletDataHandlerImpl.class);
493 
494 }