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.documentlibrary.lar;
24  
25  import com.liferay.portal.SystemException;
26  import com.liferay.portal.kernel.lar.PortletDataContext;
27  import com.liferay.portal.kernel.lar.PortletDataException;
28  import com.liferay.portal.kernel.lar.PortletDataHandler;
29  import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
30  import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
31  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
32  import com.liferay.portal.kernel.util.StringMaker;
33  import com.liferay.portal.kernel.util.StringPool;
34  import com.liferay.portal.util.DocumentUtil;
35  import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
36  import com.liferay.portlet.documentlibrary.NoSuchFileShortcutException;
37  import com.liferay.portlet.documentlibrary.NoSuchFolderException;
38  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
39  import com.liferay.portlet.documentlibrary.model.DLFileRank;
40  import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
41  import com.liferay.portlet.documentlibrary.model.DLFolder;
42  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
43  import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
44  import com.liferay.portlet.documentlibrary.service.DLFileRankLocalServiceUtil;
45  import com.liferay.portlet.documentlibrary.service.DLFileShortcutLocalServiceUtil;
46  import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
47  import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryFinderUtil;
48  import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryUtil;
49  import com.liferay.portlet.documentlibrary.service.persistence.DLFileRankUtil;
50  import com.liferay.portlet.documentlibrary.service.persistence.DLFileShortcutFinderUtil;
51  import com.liferay.portlet.documentlibrary.service.persistence.DLFileShortcutUtil;
52  import com.liferay.portlet.documentlibrary.service.persistence.DLFolderUtil;
53  import com.liferay.util.FileUtil;
54  import com.liferay.util.MapUtil;
55  
56  import com.thoughtworks.xstream.XStream;
57  
58  import java.io.InputStream;
59  
60  import java.util.ArrayList;
61  import java.util.Iterator;
62  import java.util.List;
63  import java.util.Map;
64  import java.util.regex.Pattern;
65  
66  import javax.portlet.PortletPreferences;
67  
68  import org.apache.commons.logging.Log;
69  import org.apache.commons.logging.LogFactory;
70  
71  import org.dom4j.Document;
72  import org.dom4j.DocumentHelper;
73  import org.dom4j.Element;
74  
75  /**
76   * <a href="DLPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
77   *
78   * @author Bruno Farache
79   *
80   */
81  public class DLPortletDataHandlerImpl implements PortletDataHandler {
82  
83      public PortletPreferences deleteData(
84              PortletDataContext context, String portletId,
85              PortletPreferences prefs)
86          throws PortletDataException {
87  
88          try {
89  
90              // Folders
91  
92              if (!context.addPrimaryKey(
93                      DLPortletDataHandlerImpl.class, "deleteData")) {
94  
95                  DLFolderLocalServiceUtil.deleteFolders(context.getGroupId());
96              }
97  
98              return null;
99          }
100         catch (Exception e) {
101             throw new PortletDataException(e);
102         }
103     }
104 
105     public String exportData(
106             PortletDataContext context, String portletId,
107             PortletPreferences prefs)
108         throws PortletDataException {
109 
110         try {
111             XStream xStream = new XStream();
112 
113             Document doc = DocumentHelper.createDocument();
114 
115             Element root = doc.addElement("documentlibrary-data");
116 
117             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
118 
119             // Folders
120 
121             List<DLFolder> folders = DLFolderUtil.findByGroupId(
122                 context.getGroupId());
123 
124             List<DLFileEntry> entries = new ArrayList<DLFileEntry>();
125 
126             List<DLFileShortcut> shortcuts = new ArrayList<DLFileShortcut>();
127 
128             Iterator<DLFolder> foldersItr = folders.iterator();
129 
130             while (foldersItr.hasNext()) {
131                 DLFolder folder = foldersItr.next();
132 
133                 if (context.addPrimaryKey(
134                         DLFolder.class, folder.getPrimaryKeyObj())) {
135 
136                     foldersItr.remove();
137                 }
138                 else {
139                     folder.setUserUuid(folder.getUserUuid());
140 
141                     List<DLFileEntry> folderEntries =
142                         DLFileEntryUtil.findByFolderId(folder.getFolderId());
143 
144                     entries.addAll(folderEntries);
145 
146                     if (context.getBooleanParameter(_NAMESPACE, "shortcuts")) {
147                         List<DLFileShortcut> folderShortcuts =
148                             DLFileShortcutUtil.findByFolderId(
149                                 folder.getFolderId());
150 
151                         shortcuts.addAll(folderShortcuts);
152                     }
153                 }
154             }
155 
156             String xml = xStream.toXML(folders);
157 
158             Element el = root.addElement("documentlibrary-folders");
159 
160             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
161 
162             el.content().add(tempDoc.getRootElement().createCopy());
163 
164             // Entries
165 
166             List<DLFileRank> ranks = new ArrayList<DLFileRank>();
167 
168             Iterator<DLFileEntry> entriesItr = entries.iterator();
169 
170             while (entriesItr.hasNext()) {
171                 DLFileEntry entry = entriesItr.next();
172 
173                 if (context.addPrimaryKey(
174                         DLFileEntry.class, entry.getPrimaryKeyObj())) {
175 
176                     entriesItr.remove();
177                 }
178                 else {
179                     entry.setUserUuid(entry.getUserUuid());
180 
181                     if (context.getBooleanParameter(_NAMESPACE, "comments")) {
182                         context.addComments(
183                             DLFileEntry.class, entry.getPrimaryKeyObj());
184                     }
185 
186                     if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
187                         context.addRatingsEntries(
188                             DLFileEntry.class, entry.getPrimaryKeyObj());
189                     }
190 
191                     if (context.getBooleanParameter(_NAMESPACE, "tags")) {
192                         context.addTagsEntries(
193                             DLFileEntry.class, entry.getPrimaryKeyObj());
194                     }
195 
196                     InputStream in =
197                         DLFileEntryLocalServiceUtil.getFileAsStream(
198                             entry.getCompanyId(), entry.getUserId(),
199                             entry.getFolderId(), entry.getName());
200 
201                     context.getZipWriter().addEntry(
202                         _ZIP_FOLDER + entry.getName(), FileUtil.getBytes(in));
203 
204                     if (context.getBooleanParameter(_NAMESPACE, "ranks")) {
205                         List<DLFileRank> entryRanks = DLFileRankUtil.findByF_N(
206                             entry.getFolderId(), entry.getName());
207 
208                         ranks.addAll(entryRanks);
209                     }
210                 }
211             }
212 
213             xml = xStream.toXML(entries);
214 
215             el = root.addElement("documentlibrary-entries");
216 
217             tempDoc = DocumentUtil.readDocumentFromXML(xml);
218 
219             el.content().add(tempDoc.getRootElement().createCopy());
220 
221             // Shortcuts
222 
223             Iterator<DLFileShortcut> shortcutsItr = shortcuts.iterator();
224 
225             while (shortcutsItr.hasNext()) {
226                 DLFileShortcut shortcut = shortcutsItr.next();
227 
228                 if (context.addPrimaryKey(
229                         DLFileShortcut.class, shortcut.getPrimaryKeyObj())) {
230 
231                     shortcutsItr.remove();
232                 }
233                 else {
234                     shortcut.setUserUuid(shortcut.getUserUuid());
235                 }
236             }
237 
238             xml = xStream.toXML(shortcuts);
239 
240             el = root.addElement("documentlibrary-shortcuts");
241 
242             tempDoc = DocumentUtil.readDocumentFromXML(xml);
243 
244             el.content().add(tempDoc.getRootElement().createCopy());
245 
246             // Ranks
247 
248             Iterator<DLFileRank> ranksItr = ranks.iterator();
249 
250             while (ranksItr.hasNext()) {
251                 DLFileRank rank = ranksItr.next();
252 
253                 if (context.addPrimaryKey(
254                         DLFileRank.class, rank.getPrimaryKeyObj())) {
255 
256                     ranksItr.remove();
257                 }
258                 else {
259                     rank.setUserUuid(rank.getUserUuid());
260                 }
261             }
262 
263             xml = xStream.toXML(ranks);
264 
265             el = root.addElement("documentlibrary-ranks");
266 
267             tempDoc = DocumentUtil.readDocumentFromXML(xml);
268 
269             el.content().add(tempDoc.getRootElement().createCopy());
270 
271             return doc.asXML();
272         }
273         catch (Exception e) {
274             throw new PortletDataException(e);
275         }
276     }
277 
278     public PortletDataHandlerControl[] getExportControls()
279         throws PortletDataException {
280 
281         return new PortletDataHandlerControl[] {
282             _foldersAndDocuments, _shortcuts, _ranks, _comments, _ratings, _tags
283         };
284     }
285 
286     public PortletDataHandlerControl[] getImportControls()
287         throws PortletDataException {
288 
289         return new PortletDataHandlerControl[] {
290             _foldersAndDocuments, _shortcuts, _ranks, _comments, _ratings, _tags
291         };
292     }
293 
294     public PortletPreferences importData(
295             PortletDataContext context, String portletId,
296             PortletPreferences prefs, String data)
297         throws PortletDataException {
298 
299         try {
300             XStream xStream = new XStream();
301 
302             Document doc = DocumentUtil.readDocumentFromXML(data);
303 
304             Element root = doc.getRootElement();
305 
306             // Folders
307 
308             Element el = root.element(
309                 "documentlibrary-folders").element("list");
310 
311             Document tempDoc = DocumentHelper.createDocument();
312 
313             tempDoc.content().add(el.createCopy());
314 
315             Map folderPKs = context.getNewPrimaryKeysMap(DLFolder.class);
316 
317             List folders = (List)xStream.fromXML(tempDoc.asXML());
318 
319             Iterator itr = folders.iterator();
320 
321             while (itr.hasNext()) {
322                 DLFolder folder = (DLFolder)itr.next();
323 
324                 importFolder(context, folderPKs, folder);
325             }
326 
327             // Entries
328 
329             el = root.element("documentlibrary-entries").element("list");
330 
331             tempDoc = DocumentHelper.createDocument();
332 
333             tempDoc.content().add(el.createCopy());
334 
335             Map entryNames = context.getNewPrimaryKeysMap(DLFileEntry.class);
336 
337             List entries = (List)xStream.fromXML(tempDoc.asXML());
338 
339             itr = entries.iterator();
340 
341             while (itr.hasNext()) {
342                 DLFileEntry entry = (DLFileEntry)itr.next();
343 
344                 importEntry(context, folderPKs, entryNames, entry);
345             }
346 
347             // Shortcuts
348 
349             if (context.getBooleanParameter(_NAMESPACE, "shortcuts")) {
350                 el = root.element("documentlibrary-shortcuts").element("list");
351 
352                 tempDoc = DocumentHelper.createDocument();
353 
354                 tempDoc.content().add(el.createCopy());
355 
356                 List shortcuts = (List)xStream.fromXML(tempDoc.asXML());
357 
358                 itr = shortcuts.iterator();
359 
360                 while (itr.hasNext()) {
361                     DLFileShortcut shortcut = (DLFileShortcut)itr.next();
362 
363                     importShortcut(context, folderPKs, entryNames, shortcut);
364                 }
365             }
366 
367             // Ranks
368 
369             if (context.getBooleanParameter(_NAMESPACE, "ranks")) {
370                 el = root.element("documentlibrary-ranks").element("list");
371 
372                 tempDoc = DocumentHelper.createDocument();
373 
374                 tempDoc.content().add(el.createCopy());
375 
376                 List ranks = (List)xStream.fromXML(tempDoc.asXML());
377 
378                 itr = ranks.iterator();
379 
380                 while (itr.hasNext()) {
381                     DLFileRank rank = (DLFileRank)itr.next();
382 
383                     importRank(context, folderPKs, entryNames, rank);
384                 }
385             }
386 
387             return null;
388         }
389         catch (Exception e) {
390             throw new PortletDataException(e);
391         }
392     }
393 
394     public boolean isPublishToLiveByDefault() {
395         return false;
396     }
397 
398     protected String getFolderName(
399             long companyId, long groupId, long parentFolderId, String name,
400             int count)
401         throws SystemException {
402 
403         DLFolder folder = DLFolderUtil.fetchByG_P_N(
404             groupId, parentFolderId, name);
405 
406         if (folder == null) {
407             return name;
408         }
409 
410         if (Pattern.matches(".* \\(\\d+\\)", name)) {
411             int pos = name.lastIndexOf(" (");
412 
413             name = name.substring(0, pos);
414         }
415 
416         StringMaker sm = new StringMaker();
417 
418         sm.append(name);
419         sm.append(StringPool.SPACE);
420         sm.append(StringPool.OPEN_PARENTHESIS);
421         sm.append(count);
422         sm.append(StringPool.CLOSE_PARENTHESIS);
423 
424         name = sm.toString();
425 
426         return getFolderName(
427             companyId, groupId, parentFolderId, name, ++count);
428     }
429 
430     protected void importEntry(
431             PortletDataContext context, Map folderPKs, Map entryNames,
432             DLFileEntry entry)
433         throws Exception {
434 
435         long userId = context.getUserId(entry.getUserUuid());
436         long folderId = MapUtil.getLong(
437             folderPKs, entry.getFolderId(), entry.getFolderId());
438 
439         String[] tagsEntries = null;
440 
441         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
442             tagsEntries = context.getTagsEntries(
443                 DLFileEntry.class, entry.getPrimaryKeyObj());
444         }
445 
446         boolean addCommunityPermissions = true;
447         boolean addGuestPermissions = true;
448 
449         byte[] byteArray = context.getZipReader().getEntryAsByteArray(
450             _ZIP_FOLDER + entry.getName());
451 
452         DLFileEntry existingEntry = null;
453 
454         try {
455             DLFolderUtil.findByPrimaryKey(folderId);
456 
457             if (context.getDataStrategy().equals(
458                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
459 
460                 try {
461                     existingEntry = DLFileEntryFinderUtil.findByUuid_G(
462                         entry.getUuid(), context.getGroupId());
463 
464                     existingEntry = DLFileEntryLocalServiceUtil.updateFileEntry(
465                         userId, existingEntry.getFolderId(), folderId,
466                         existingEntry.getName(), entry.getName(),
467                         entry.getTitle(), entry.getDescription(), tagsEntries,
468                         entry.getExtraSettings(), byteArray);
469                 }
470                 catch (NoSuchFileEntryException nsfee) {
471                     existingEntry = DLFileEntryLocalServiceUtil.addFileEntry(
472                         entry.getUuid(), userId, folderId, entry.getName(),
473                         entry.getTitle(), entry.getDescription(),
474                         tagsEntries, entry.getExtraSettings(), byteArray,
475                         addCommunityPermissions, addGuestPermissions);
476                 }
477             }
478             else {
479                 existingEntry = DLFileEntryLocalServiceUtil.addFileEntry(
480                     userId, folderId, entry.getName(), entry.getTitle(),
481                     entry.getDescription(), tagsEntries,
482                     entry.getExtraSettings(), byteArray,
483                     addCommunityPermissions, addGuestPermissions);
484             }
485 
486             entryNames.put(entry.getName(), existingEntry.getName());
487 
488             if (context.getBooleanParameter(_NAMESPACE, "comments")) {
489                 context.importComments(
490                     DLFileEntry.class, entry.getPrimaryKeyObj(),
491                     existingEntry.getPrimaryKeyObj(), context.getGroupId());
492             }
493 
494             if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
495                 context.importRatingsEntries(
496                     DLFileEntry.class, entry.getPrimaryKeyObj(),
497                     existingEntry.getPrimaryKeyObj());
498             }
499         }
500         catch (NoSuchFolderException nsfe) {
501             _log.error(
502                 "Could not find the parent folder for entry " +
503                     entry.getFileEntryId());
504         }
505     }
506 
507     protected void importFolder(
508             PortletDataContext context, Map folderPKs, DLFolder folder)
509         throws Exception {
510 
511         long userId = context.getUserId(folder.getUserUuid());
512         long plid = context.getPlid();
513         long parentFolderId = MapUtil.getLong(
514             folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
515 
516         boolean addCommunityPermissions = true;
517         boolean addGuestPermissions = true;
518 
519         DLFolder existingFolder = null;
520 
521         try {
522             if (parentFolderId != DLFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
523                 DLFolderUtil.findByPrimaryKey(parentFolderId);
524             }
525 
526             if (context.getDataStrategy().equals(
527                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
528 
529                 existingFolder = DLFolderUtil.fetchByUUID_G(
530                     folder.getUuid(), context.getGroupId());
531 
532                 if (existingFolder == null) {
533                     String name = getFolderName(
534                         context.getCompanyId(), context.getGroupId(),
535                         parentFolderId, folder.getName(), 2);
536 
537                     existingFolder = DLFolderLocalServiceUtil.addFolder(
538                         folder.getUuid(), userId, plid, parentFolderId,
539                         name, folder.getDescription(), addCommunityPermissions,
540                         addGuestPermissions);
541                 }
542                 else {
543                     existingFolder = DLFolderLocalServiceUtil.updateFolder(
544                         existingFolder.getFolderId(), parentFolderId,
545                         folder.getName(), folder.getDescription());
546                 }
547             }
548             else {
549                 String name = getFolderName(
550                     context.getCompanyId(), context.getGroupId(),
551                     parentFolderId, folder.getName(), 2);
552 
553                 existingFolder = DLFolderLocalServiceUtil.addFolder(
554                     userId, plid, parentFolderId, name, folder.getDescription(),
555                     addCommunityPermissions, addGuestPermissions);
556             }
557 
558             folderPKs.put(
559                 folder.getPrimaryKeyObj(), existingFolder.getPrimaryKeyObj());
560         }
561         catch (NoSuchFolderException nsfe) {
562             _log.error(
563                 "Could not find the parent folder for folder " +
564                     folder.getFolderId());
565         }
566     }
567 
568     protected void importRank(
569             PortletDataContext context, Map folderPKs, Map entryNames,
570             DLFileRank rank)
571         throws Exception {
572 
573         long userId = context.getUserId(rank.getUserUuid());
574         long folderId = MapUtil.getLong(
575             folderPKs, rank.getFolderId(), rank.getFolderId());
576 
577         String name = (String)folderPKs.get(rank.getName());
578 
579         if (name == null) {
580             name = rank.getName();
581         }
582 
583         try {
584             DLFolderUtil.findByPrimaryKey(folderId);
585 
586             DLFileRankLocalServiceUtil.updateFileRank(
587                 context.getGroupId(), context.getCompanyId(), userId, folderId,
588                 name);
589         }
590         catch (NoSuchFolderException nsfe) {
591             _log.error(
592                 "Could not find the folder for rank " + rank.getFileRankId());
593         }
594     }
595 
596     protected void importShortcut(
597             PortletDataContext context, Map folderPKs, Map entryNames,
598             DLFileShortcut shortcut)
599         throws Exception {
600 
601         long userId = context.getUserId(shortcut.getUserUuid());
602         long folderId = MapUtil.getLong(
603             folderPKs, shortcut.getFolderId(), shortcut.getFolderId());
604         long toFolderId = MapUtil.getLong(
605             folderPKs, shortcut.getToFolderId(), shortcut.getToFolderId());
606         String toName = MapUtil.getString(
607             entryNames, shortcut.getToName(), shortcut.getToName());
608 
609         boolean addCommunityPermissions = true;
610         boolean addGuestPermissions = true;
611 
612         try {
613             DLFolderUtil.findByPrimaryKey(folderId);
614             DLFolderUtil.findByPrimaryKey(toFolderId);
615 
616             if (context.getDataStrategy().equals(
617                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
618 
619                 try {
620                     DLFileShortcut existingShortcut =
621                         DLFileShortcutFinderUtil.findByUuid_G(
622                             shortcut.getUuid(), context.getGroupId());
623 
624                     DLFileShortcutLocalServiceUtil.updateFileShortcut(
625                         userId, existingShortcut.getFileShortcutId(), folderId,
626                         toFolderId, toName);
627                 }
628                 catch (NoSuchFileShortcutException nsfse) {
629                     DLFileShortcutLocalServiceUtil.addFileShortcut(
630                         shortcut.getUuid(), userId, folderId, toFolderId,
631                         toName, addCommunityPermissions, addGuestPermissions);
632                 }
633             }
634             else {
635                 DLFileShortcutLocalServiceUtil.addFileShortcut(
636                     userId, folderId, toFolderId, toName,
637                     addCommunityPermissions, addGuestPermissions);
638             }
639         }
640         catch (NoSuchFolderException nsfe) {
641             _log.error(
642                 "Could not find the folder for shortcut " +
643                     shortcut.getFileShortcutId());
644         }
645     }
646 
647     private static final String _NAMESPACE = "document_library";
648 
649     private static final String _ZIP_FOLDER = "document-library/";
650 
651     private static final PortletDataHandlerBoolean _foldersAndDocuments =
652         new PortletDataHandlerBoolean(
653             _NAMESPACE, "folders-and-documents", true, true);
654 
655     private static final PortletDataHandlerBoolean _ranks =
656         new PortletDataHandlerBoolean(_NAMESPACE, "ranks");
657 
658     private static final PortletDataHandlerBoolean _shortcuts=
659         new PortletDataHandlerBoolean(_NAMESPACE, "shortcuts");
660 
661     private static final PortletDataHandlerBoolean _comments =
662         new PortletDataHandlerBoolean(_NAMESPACE, "comments");
663 
664     private static final PortletDataHandlerBoolean _ratings =
665         new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
666 
667     private static final PortletDataHandlerBoolean _tags =
668         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
669 
670     private static Log _log =
671         LogFactory.getLog(DLPortletDataHandlerImpl.class);
672 
673 }