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