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.StringMaker;
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.portlet.imagegallery.NoSuchFolderException;
39  import com.liferay.portlet.imagegallery.NoSuchImageException;
40  import com.liferay.portlet.imagegallery.model.IGFolder;
41  import com.liferay.portlet.imagegallery.model.IGImage;
42  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
43  import com.liferay.portlet.imagegallery.service.IGFolderLocalServiceUtil;
44  import com.liferay.portlet.imagegallery.service.IGImageLocalServiceUtil;
45  import com.liferay.portlet.imagegallery.service.persistence.IGFolderUtil;
46  import com.liferay.portlet.imagegallery.service.persistence.IGImageFinderUtil;
47  import com.liferay.portlet.imagegallery.service.persistence.IGImageUtil;
48  import com.liferay.util.FileUtil;
49  import com.liferay.util.MapUtil;
50  
51  import com.thoughtworks.xstream.XStream;
52  
53  import java.io.File;
54  
55  import java.util.ArrayList;
56  import java.util.Iterator;
57  import java.util.List;
58  import java.util.Map;
59  import java.util.regex.Pattern;
60  
61  import javax.portlet.PortletPreferences;
62  
63  import org.apache.commons.logging.Log;
64  import org.apache.commons.logging.LogFactory;
65  
66  import org.dom4j.Document;
67  import org.dom4j.DocumentHelper;
68  import org.dom4j.Element;
69  
70  /**
71   * <a href="IGPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
72   *
73   * @author Bruno Farache
74   *
75   */
76  public class IGPortletDataHandlerImpl implements PortletDataHandler {
77  
78      public PortletPreferences deleteData(
79              PortletDataContext context, String portletId,
80              PortletPreferences prefs)
81          throws PortletDataException {
82  
83          try {
84  
85              // Folders
86  
87              if (!context.addPrimaryKey(
88                      IGPortletDataHandlerImpl.class, "deleteData")) {
89  
90                  IGFolderLocalServiceUtil.deleteFolders(context.getGroupId());
91              }
92  
93              return null;
94          }
95          catch (Exception e) {
96              throw new PortletDataException(e);
97          }
98      }
99  
100     public String exportData(
101             PortletDataContext context, String portletId,
102             PortletPreferences prefs)
103         throws PortletDataException {
104 
105         try {
106             XStream xStream = new XStream();
107 
108             Document doc = DocumentHelper.createDocument();
109 
110             Element root = doc.addElement("image-gallery");
111 
112             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
113 
114             // Folders
115 
116             List<IGFolder> folders = IGFolderUtil.findByGroupId(
117                 context.getGroupId());
118 
119             List<IGImage> igImages = new ArrayList<IGImage>();
120 
121             Iterator<IGFolder> foldersItr = folders.iterator();
122 
123             while (foldersItr.hasNext()) {
124                 IGFolder folder = foldersItr.next();
125 
126                 if (context.addPrimaryKey(
127                         IGFolder.class, folder.getPrimaryKeyObj())) {
128 
129                     foldersItr.remove();
130                 }
131                 else {
132                     folder.setUserUuid(folder.getUserUuid());
133 
134                     List<IGImage> folderIGImages = IGImageUtil.findByFolderId(
135                         folder.getFolderId());
136 
137                     igImages.addAll(folderIGImages);
138                 }
139             }
140 
141             String xml = xStream.toXML(folders);
142 
143             Element el = root.addElement("ig-folders");
144 
145             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
146 
147             el.content().add(tempDoc.getRootElement().createCopy());
148 
149             // IGImages
150 
151             Iterator<IGImage> imagesItr = igImages.iterator();
152 
153             while (imagesItr.hasNext()) {
154                 IGImage igImage = imagesItr.next();
155 
156                 if (context.addPrimaryKey(
157                         IGImage.class, igImage.getPrimaryKeyObj())) {
158 
159                     imagesItr.remove();
160                 }
161                 else {
162                     igImage.setUserUuid(igImage.getUserUuid());
163 
164                     if (context.getBooleanParameter(_NAMESPACE, "tags")) {
165                         context.addTagsEntries(
166                             IGImage.class, igImage.getPrimaryKeyObj());
167                     }
168 
169                     try {
170                         Image largeImage = ImageUtil.findByPrimaryKey(
171                             igImage.getLargeImageId());
172 
173                         igImage.setImageType(largeImage.getType());
174 
175                         context.getZipWriter().addEntry(
176                             getIGImageDir(igImage), largeImage.getTextObj());
177                     }
178                     catch (com.liferay.portal.NoSuchImageException nsie) {
179                     }
180                 }
181             }
182 
183             xml = xStream.toXML(igImages);
184 
185             el = root.addElement("ig-images");
186 
187             tempDoc = DocumentUtil.readDocumentFromXML(xml);
188 
189             el.content().add(tempDoc.getRootElement().createCopy());
190 
191             return doc.asXML();
192         }
193         catch (Exception e) {
194             throw new PortletDataException(e);
195         }
196     }
197 
198     public PortletDataHandlerControl[] getExportControls()
199         throws PortletDataException {
200 
201         return new PortletDataHandlerControl[] {_foldersAndImages, _tags};
202     }
203 
204     public PortletDataHandlerControl[] getImportControls()
205         throws PortletDataException {
206 
207         return new PortletDataHandlerControl[] {_foldersAndImages, _tags};
208     }
209 
210     public PortletPreferences importData(
211             PortletDataContext context, String portletId,
212             PortletPreferences prefs, String data)
213         throws PortletDataException {
214 
215         try {
216             XStream xStream = new XStream();
217 
218             Document doc = DocumentUtil.readDocumentFromXML(data);
219 
220             Element root = doc.getRootElement();
221 
222             // Folders
223 
224             Element el = root.element("ig-folders").element("list");
225 
226             Document tempDoc = DocumentHelper.createDocument();
227 
228             tempDoc.content().add(el.createCopy());
229 
230             Map<Long, Long> folderPKs = context.getNewPrimaryKeysMap(
231                 IGFolder.class);
232 
233             List<IGFolder> folders = (List<IGFolder>)xStream.fromXML(
234                 tempDoc.asXML());
235 
236             Iterator<IGFolder> foldersItr = folders.iterator();
237 
238             while (foldersItr.hasNext()) {
239                 IGFolder folder = foldersItr.next();
240 
241                 importFolder(context, folderPKs, folder);
242             }
243 
244             // IGImages
245 
246             el = root.element("ig-images").element("list");
247 
248             tempDoc = DocumentHelper.createDocument();
249 
250             tempDoc.content().add(el.createCopy());
251 
252             List<IGImage> igImages = (List<IGImage>)xStream.fromXML(
253                 tempDoc.asXML());
254 
255             Iterator<IGImage> imagesItr = igImages.iterator();
256 
257             while (imagesItr.hasNext()) {
258                 IGImage igImage = imagesItr.next();
259 
260                 importIGImage(context, folderPKs, igImage);
261             }
262 
263             return null;
264         }
265         catch (Exception e) {
266             throw new PortletDataException(e);
267         }
268     }
269 
270     public boolean isPublishToLiveByDefault() {
271         return false;
272     }
273 
274     protected String getFolderName(
275             long companyId, long groupId, long parentFolderId, String name,
276             int count)
277         throws SystemException {
278 
279         IGFolder folder = IGFolderUtil.fetchByG_P_N(
280             groupId, parentFolderId, name);
281 
282         if (folder == null) {
283             return name;
284         }
285 
286         if (Pattern.matches(".* \\(\\d+\\)", name)) {
287             int pos = name.lastIndexOf(" (");
288 
289             name = name.substring(0, pos);
290         }
291 
292         StringMaker sm = new StringMaker();
293 
294         sm.append(name);
295         sm.append(StringPool.SPACE);
296         sm.append(StringPool.OPEN_PARENTHESIS);
297         sm.append(count);
298         sm.append(StringPool.CLOSE_PARENTHESIS);
299 
300         name = sm.toString();
301 
302         return getFolderName(companyId, groupId, parentFolderId, name, ++count);
303     }
304 
305     protected String getIGImageDir(IGImage igImage)
306         throws PortalException, SystemException {
307 
308         return _IMAGE_GALLERY_FOLDER + igImage.getPrimaryKey() + "." +
309             igImage.getImageType();
310     }
311 
312     protected void importFolder(
313             PortletDataContext context, Map<Long, Long> folderPKs,
314             IGFolder folder)
315         throws Exception {
316 
317         long userId = context.getUserId(folder.getUserUuid());
318         long plid = context.getPlid();
319         long parentFolderId = MapUtil.getLong(
320             folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
321 
322         boolean addCommunityPermissions = true;
323         boolean addGuestPermissions = true;
324 
325         IGFolder existingFolder = null;
326 
327         try {
328             if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
329                 IGFolderUtil.findByPrimaryKey(parentFolderId);
330             }
331 
332             if (context.getDataStrategy().equals(
333                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
334 
335                 existingFolder = IGFolderUtil.fetchByUUID_G(
336                     folder.getUuid(), context.getGroupId());
337 
338                 if (existingFolder == null) {
339                     String name = getFolderName(
340                         context.getCompanyId(), context.getGroupId(),
341                         parentFolderId, folder.getName(), 2);
342 
343                     existingFolder = IGFolderLocalServiceUtil.addFolder(
344                         folder.getUuid(), userId, plid, parentFolderId,
345                         name, folder.getDescription(), addCommunityPermissions,
346                         addGuestPermissions);
347                 }
348                 else {
349                     existingFolder = IGFolderLocalServiceUtil.updateFolder(
350                         existingFolder.getFolderId(), parentFolderId,
351                         folder.getName(), folder.getDescription(), false);
352                 }
353             }
354             else {
355                 String name = getFolderName(
356                     context.getCompanyId(), context.getGroupId(),
357                     parentFolderId, folder.getName(), 2);
358 
359                 existingFolder = IGFolderLocalServiceUtil.addFolder(
360                     userId, plid, parentFolderId, name, folder.getDescription(),
361                     addCommunityPermissions, addGuestPermissions);
362             }
363 
364             folderPKs.put(folder.getFolderId(), existingFolder.getFolderId());
365         }
366         catch (NoSuchFolderException nsfe) {
367             _log.error(
368                 "Could not find the parent folder for folder " +
369                     folder.getFolderId());
370         }
371     }
372 
373     protected void importIGImage(
374             PortletDataContext context, Map<Long, Long> folderPKs,
375             IGImage igImage)
376         throws Exception {
377 
378         long userId = context.getUserId(igImage.getUserUuid());
379         long folderId = MapUtil.getLong(
380             folderPKs, igImage.getFolderId(), igImage.getFolderId());
381 
382         File imageFile = null;
383 
384         byte[] byteArray = context.getZipReader().getEntryAsByteArray(
385             getIGImageDir(igImage));
386 
387         if (byteArray == null) {
388             _log.error(
389                 "Could not find image for IG image " + igImage.getImageId());
390 
391             return;
392         }
393         else {
394             imageFile = File.createTempFile(
395                 String.valueOf(igImage.getPrimaryKey()),
396                 StringPool.PERIOD + igImage.getImageType());
397 
398             FileUtil.write(imageFile, byteArray);
399         }
400 
401         String[] tagsEntries = null;
402 
403         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
404             tagsEntries = context.getTagsEntries(
405                 IGImage.class, igImage.getPrimaryKeyObj());
406         }
407 
408         boolean addCommunityPermissions = true;
409         boolean addGuestPermissions = true;
410 
411         IGImage existingImage = null;
412 
413         try {
414             IGFolderUtil.findByPrimaryKey(folderId);
415 
416             if (context.getDataStrategy().equals(
417                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
418 
419                 try {
420                     existingImage = IGImageFinderUtil.findByUuid_G(
421                         igImage.getUuid(), context.getGroupId());
422 
423                     IGImageLocalServiceUtil.updateImage(
424                         userId, existingImage.getImageId(), folderId,
425                         igImage.getName(), igImage.getDescription(), imageFile,
426                         igImage.getImageType(), tagsEntries);
427                 }
428                 catch (NoSuchImageException nsie) {
429                     IGImageLocalServiceUtil.addImage(
430                         igImage.getUuid(), userId, folderId,
431                         igImage.getName(), igImage.getDescription(), imageFile,
432                         igImage.getImageType(), tagsEntries,
433                         addCommunityPermissions, addGuestPermissions);
434                 }
435             }
436             else {
437                 IGImageLocalServiceUtil.addImage(
438                     userId, folderId, igImage.getName(),
439                     igImage.getDescription(), imageFile, igImage.getImageType(),
440                     tagsEntries, addCommunityPermissions, addGuestPermissions);
441             }
442         }
443         catch (NoSuchFolderException nsfe) {
444             _log.error(
445                 "Could not find the parent folder for IG image " +
446                     igImage.getImageId());
447         }
448     }
449 
450     private static final String _NAMESPACE = "image_gallery";
451 
452     private static final String _IMAGE_GALLERY_FOLDER = "image-gallery/";
453 
454     private static final PortletDataHandlerBoolean _foldersAndImages =
455         new PortletDataHandlerBoolean(
456             _NAMESPACE, "folders-and-images", true, true);
457 
458     private static final PortletDataHandlerBoolean _tags =
459         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
460 
461     private static Log _log = LogFactory.getLog(IGPortletDataHandlerImpl.class);
462 
463 }