1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.documentlibrary.lar;
16  
17  import com.liferay.documentlibrary.service.DLLocalServiceUtil;
18  import com.liferay.portal.kernel.exception.PortalException;
19  import com.liferay.portal.kernel.exception.SystemException;
20  import com.liferay.portal.kernel.log.Log;
21  import com.liferay.portal.kernel.log.LogFactoryUtil;
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.workflow.StatusConstants;
26  import com.liferay.portal.kernel.xml.Document;
27  import com.liferay.portal.kernel.xml.Element;
28  import com.liferay.portal.kernel.xml.SAXReaderUtil;
29  import com.liferay.portal.lar.BasePortletDataHandler;
30  import com.liferay.portal.lar.PortletDataContext;
31  import com.liferay.portal.lar.PortletDataException;
32  import com.liferay.portal.lar.PortletDataHandlerBoolean;
33  import com.liferay.portal.lar.PortletDataHandlerControl;
34  import com.liferay.portal.lar.PortletDataHandlerKeys;
35  import com.liferay.portal.service.ServiceContext;
36  import com.liferay.portal.util.PortletKeys;
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.DLFileVersion;
42  import com.liferay.portlet.documentlibrary.model.DLFolder;
43  import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
44  import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
45  import com.liferay.portlet.documentlibrary.service.DLFileRankLocalServiceUtil;
46  import com.liferay.portlet.documentlibrary.service.DLFileShortcutLocalServiceUtil;
47  import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
48  import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
49  import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryUtil;
50  import com.liferay.portlet.documentlibrary.service.persistence.DLFileRankUtil;
51  import com.liferay.portlet.documentlibrary.service.persistence.DLFileShortcutUtil;
52  import com.liferay.portlet.documentlibrary.service.persistence.DLFolderUtil;
53  import com.liferay.portlet.documentlibrary.util.DLUtil;
54  
55  import java.io.IOException;
56  import java.io.InputStream;
57  
58  import java.util.List;
59  import java.util.Map;
60  import java.util.regex.Pattern;
61  
62  import javax.portlet.PortletPreferences;
63  
64  /**
65   * <a href="DLPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
66   *
67   * @author Bruno Farache
68   * @author Raymond Augé
69   */
70  public class DLPortletDataHandlerImpl extends BasePortletDataHandler {
71  
72      public static void exportFileEntry(
73              PortletDataContext context, Element foldersEl,
74              Element fileEntriesEl, Element fileRanksEl, DLFileEntry fileEntry)
75          throws PortalException, SystemException {
76  
77          if (!context.isWithinDateRange(fileEntry.getModifiedDate())) {
78              return;
79          }
80  
81          DLFileVersion fileVersion =
82              DLFileVersionLocalServiceUtil.getFileVersion(
83                  context.getGroupId(), fileEntry.getFolderId(),
84                  fileEntry.getName(), fileEntry.getVersion());
85  
86          if (fileVersion.getStatus() != StatusConstants.APPROVED) {
87              return;
88          }
89  
90          if (foldersEl != null) {
91              exportParentFolder(context, foldersEl, fileEntry.getFolderId());
92          }
93  
94          String path = getFileEntryPath(context, fileEntry);
95  
96          if (context.isPathNotProcessed(path)) {
97              Element fileEntryEl = fileEntriesEl.addElement("file-entry");
98  
99              fileEntryEl.addAttribute("path", path);
100 
101             String binPath = getFileEntryBinPath(context, fileEntry);
102 
103             fileEntryEl.addAttribute("bin-path", binPath);
104 
105             fileEntry.setUserUuid(fileEntry.getUserUuid());
106 
107             context.addPermissions(
108                 DLFileEntry.class, fileEntry.getFileEntryId());
109 
110             if (context.getBooleanParameter(_NAMESPACE, "categories")) {
111                 context.addAssetCategories(
112                     DLFileEntry.class, fileEntry.getFileEntryId());
113             }
114 
115             if (context.getBooleanParameter(_NAMESPACE, "comments")) {
116                 context.addComments(
117                     DLFileEntry.class, fileEntry.getFileEntryId());
118             }
119 
120             if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
121                 context.addRatingsEntries(
122                     DLFileEntry.class, fileEntry.getFileEntryId());
123             }
124 
125             if (context.getBooleanParameter(_NAMESPACE, "tags")) {
126                 context.addAssetTags(
127                     DLFileEntry.class, fileEntry.getFileEntryId());
128             }
129 
130             long repositoryId = getRepositoryId(
131                 fileEntry.getGroupId(), fileEntry.getFolderId());
132 
133             InputStream is = DLLocalServiceUtil.getFileAsStream(
134                 fileEntry.getCompanyId(), repositoryId, fileEntry.getName(),
135                 fileEntry.getVersion());
136 
137             if (is == null) {
138                 if (_log.isWarnEnabled()) {
139                     _log.warn(
140                         "No file found for file entry " +
141                             fileEntry.getFileEntryId());
142                 }
143 
144                 fileEntryEl.detach();
145 
146                 return;
147             }
148 
149             try {
150                 context.addZipEntry(
151                     getFileEntryBinPath(context, fileEntry), is);
152             }
153             finally {
154                 try {
155                     is.close();
156                 }
157                 catch (IOException ioe) {
158                     _log.error(ioe, ioe);
159                 }
160             }
161 
162             context.addZipEntry(path, fileEntry);
163 
164             if (context.getBooleanParameter(_NAMESPACE, "ranks")) {
165                 List<DLFileRank> fileRanks = DLFileRankUtil.findByF_N(
166                     fileEntry.getFolderId(), fileEntry.getName());
167 
168                 for (DLFileRank fileRank : fileRanks) {
169                     exportFileRank(context, fileRanksEl, fileRank);
170                 }
171             }
172         }
173     }
174 
175     public static void exportFolder(
176             PortletDataContext context, Element foldersEl,
177             Element fileEntriesEl, Element fileShortcutsEl, Element fileRanksEl,
178             DLFolder folder)
179         throws PortalException, SystemException {
180 
181         if (context.isWithinDateRange(folder.getModifiedDate())) {
182             exportParentFolder(context, foldersEl, folder.getParentFolderId());
183 
184             String path = getFolderPath(context, folder);
185 
186             if (context.isPathNotProcessed(path)) {
187                 Element folderEl = foldersEl.addElement("folder");
188 
189                 folderEl.addAttribute("path", path);
190 
191                 folder.setUserUuid(folder.getUserUuid());
192 
193                 context.addPermissions(DLFolder.class, folder.getFolderId());
194 
195                 context.addZipEntry(path, folder);
196             }
197         }
198 
199         List<DLFileEntry> fileEntries = DLFileEntryUtil.findByG_F(
200             folder.getGroupId(), folder.getFolderId());
201 
202         for (DLFileEntry fileEntry : fileEntries) {
203             exportFileEntry(
204                 context, foldersEl, fileEntriesEl, fileRanksEl, fileEntry);
205         }
206 
207         if (context.getBooleanParameter(_NAMESPACE, "shortcuts")) {
208             List<DLFileShortcut> fileShortcuts = DLFileShortcutUtil.findByG_F(
209                 folder.getGroupId(), folder.getFolderId());
210 
211             for (DLFileShortcut fileShortcut : fileShortcuts) {
212                 exportFileShortcut(
213                     context, foldersEl, fileShortcutsEl, fileShortcut);
214             }
215         }
216     }
217 
218     public static void importFileEntry(
219             PortletDataContext context, Map<Long, Long> folderPKs,
220             Map<String, String> fileEntryNames, DLFileEntry fileEntry,
221             String binPath)
222         throws Exception {
223 
224         long userId = context.getUserId(fileEntry.getUserUuid());
225         long groupId = context.getGroupId();
226         long folderId = MapUtil.getLong(
227             folderPKs, fileEntry.getFolderId(), fileEntry.getFolderId());
228 
229         long[] assetCategoryIds = null;
230         String[] assetTagNames = null;
231 
232         if (context.getBooleanParameter(_NAMESPACE, "categories")) {
233             assetCategoryIds = context.getAssetCategoryIds(
234                 DLFileEntry.class, fileEntry.getFileEntryId());
235         }
236 
237         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
238             assetTagNames = context.getAssetTagNames(
239                 DLFileEntry.class, fileEntry.getFileEntryId());
240         }
241 
242         ServiceContext serviceContext = new ServiceContext();
243 
244         serviceContext.setAddCommunityPermissions(true);
245         serviceContext.setAddGuestPermissions(true);
246         serviceContext.setAssetCategoryIds(assetCategoryIds);
247         serviceContext.setAssetTagNames(assetTagNames);
248         serviceContext.setCreateDate(fileEntry.getCreateDate());
249         serviceContext.setModifiedDate(fileEntry.getModifiedDate());
250         serviceContext.setScopeGroupId(groupId);
251         serviceContext.setStartWorkflow(false);
252 
253         InputStream is = context.getZipEntryAsInputStream(binPath);
254 
255         if ((folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
256             (folderId == fileEntry.getFolderId())) {
257 
258             String path = getImportFolderPath(context, folderId);
259 
260             DLFolder folder = (DLFolder)context.getZipEntryAsObject(path);
261 
262             importFolder(context, folderPKs, folder);
263 
264             folderId = MapUtil.getLong(
265                 folderPKs, fileEntry.getFolderId(), fileEntry.getFolderId());
266         }
267 
268         DLFileEntry importedFileEntry = null;
269 
270         try {
271             if ((folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
272                 (folderId > 0)) {
273 
274                 DLFolderUtil.findByPrimaryKey(folderId);
275             }
276 
277             if (context.getDataStrategy().equals(
278                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
279 
280                 DLFileEntry existingFileEntry = DLFileEntryUtil.fetchByUUID_G(
281                     fileEntry.getUuid(), groupId);
282 
283                 if (existingFileEntry == null) {
284                     importedFileEntry =
285                         DLFileEntryLocalServiceUtil.addFileEntry(
286                             fileEntry.getUuid(), userId, groupId, folderId,
287                             fileEntry.getName(), fileEntry.getTitle(),
288                             fileEntry.getDescription(), null,
289                             fileEntry.getExtraSettings(), is,
290                             fileEntry.getSize(), serviceContext);
291                 }
292                 else if (!isDuplicateFileEntry(fileEntry, existingFileEntry)) {
293                     importedFileEntry =
294                         DLFileEntryLocalServiceUtil.updateFileEntry(
295                             userId, groupId, existingFileEntry.getFolderId(),
296                             folderId, existingFileEntry.getName(),
297                             fileEntry.getTitle(), fileEntry.getTitle(),
298                             fileEntry.getDescription(), null, true,
299                             fileEntry.getExtraSettings(), is,
300                             fileEntry.getSize(), serviceContext);
301                 }
302             }
303             else {
304                 importedFileEntry = DLFileEntryLocalServiceUtil.addFileEntry(
305                     null, userId, groupId, folderId, fileEntry.getName(),
306                     fileEntry.getTitle(), fileEntry.getDescription(), null,
307                     fileEntry.getExtraSettings(), is, fileEntry.getSize(),
308                     serviceContext);
309             }
310 
311             fileEntryNames.put(
312                 fileEntry.getName(), importedFileEntry.getName());
313 
314             context.importPermissions(
315                 DLFileEntry.class, fileEntry.getFileEntryId(),
316                 importedFileEntry.getFileEntryId());
317 
318             if (context.getBooleanParameter(_NAMESPACE, "comments")) {
319                 context.importComments(
320                     DLFileEntry.class, fileEntry.getFileEntryId(),
321                     importedFileEntry.getFileEntryId(), groupId);
322             }
323 
324             if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
325                 context.importRatingsEntries(
326                     DLFileEntry.class, fileEntry.getFileEntryId(),
327                     importedFileEntry.getFileEntryId());
328             }
329         }
330         catch (NoSuchFolderException nsfe) {
331             _log.error(
332                 "Could not find the parent folder for entry " +
333                     fileEntry.getFileEntryId());
334         }
335     }
336 
337     public static void importFileRank(
338             PortletDataContext context, Map<Long, Long> folderPKs,
339             Map<String, String> fileEntryNames, DLFileRank rank)
340         throws Exception {
341 
342         long userId = context.getUserId(rank.getUserUuid());
343         long folderId = MapUtil.getLong(
344             folderPKs, rank.getFolderId(), rank.getFolderId());
345 
346         String name = fileEntryNames.get(rank.getName());
347 
348         if (name == null) {
349             name = rank.getName();
350         }
351 
352         ServiceContext serviceContext = new ServiceContext();
353 
354         serviceContext.setCreateDate(rank.getCreateDate());
355 
356         if ((folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
357             (folderId == rank.getFolderId())) {
358 
359             String path = getImportFolderPath(context, folderId);
360 
361             DLFolder folder = (DLFolder)context.getZipEntryAsObject(path);
362 
363             importFolder(context, folderPKs, folder);
364 
365             folderId = MapUtil.getLong(
366                 folderPKs, rank.getFolderId(), rank.getFolderId());
367         }
368 
369         try {
370             DLFolderUtil.findByPrimaryKey(folderId);
371 
372             DLFileRankLocalServiceUtil.updateFileRank(
373                 context.getGroupId(), context.getCompanyId(), userId, folderId,
374                 name, serviceContext);
375         }
376         catch (NoSuchFolderException nsfe) {
377             _log.error(
378                 "Could not find the folder for rank " + rank.getFileRankId());
379         }
380     }
381 
382     public static void importFolder(
383             PortletDataContext context, Map<Long, Long> folderPKs,
384             DLFolder folder)
385         throws Exception {
386 
387         long userId = context.getUserId(folder.getUserUuid());
388         long groupId = context.getGroupId();
389         long parentFolderId = MapUtil.getLong(
390             folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
391 
392         ServiceContext serviceContext = new ServiceContext();
393 
394         serviceContext.setAddCommunityPermissions(true);
395         serviceContext.setAddGuestPermissions(true);
396         serviceContext.setCreateDate(folder.getCreateDate());
397         serviceContext.setModifiedDate(folder.getModifiedDate());
398 
399         if ((parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
400             (parentFolderId == folder.getParentFolderId())) {
401 
402             String path = getImportFolderPath(context, parentFolderId);
403 
404             DLFolder parentFolder = (DLFolder)context.getZipEntryAsObject(path);
405 
406             importFolder(context, folderPKs, parentFolder);
407 
408             parentFolderId = MapUtil.getLong(
409                 folderPKs, folder.getParentFolderId(),
410                 folder.getParentFolderId());
411         }
412 
413         DLFolder importedFolder = null;
414 
415         try {
416             if (parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
417                 DLFolderUtil.findByPrimaryKey(parentFolderId);
418             }
419 
420             if (context.getDataStrategy().equals(
421                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
422 
423                 DLFolder existingFolder = DLFolderUtil.fetchByUUID_G(
424                     folder.getUuid(), groupId);
425 
426                 if (existingFolder == null) {
427                     String name = getFolderName(
428                         context.getCompanyId(), groupId, parentFolderId,
429                         folder.getName(), 2);
430 
431                     importedFolder = DLFolderLocalServiceUtil.addFolder(
432                         folder.getUuid(), userId, groupId, parentFolderId,
433                         name, folder.getDescription(), serviceContext);
434                 }
435                 else {
436                     importedFolder = DLFolderLocalServiceUtil.updateFolder(
437                         existingFolder.getFolderId(), parentFolderId,
438                         folder.getName(), folder.getDescription(),
439                         serviceContext);
440                 }
441             }
442             else {
443                 String name = getFolderName(
444                     context.getCompanyId(), groupId, parentFolderId,
445                     folder.getName(), 2);
446 
447                 importedFolder = DLFolderLocalServiceUtil.addFolder(
448                     null, userId, groupId, parentFolderId, name,
449                     folder.getDescription(), serviceContext);
450             }
451 
452             folderPKs.put(folder.getFolderId(), importedFolder.getFolderId());
453 
454             context.importPermissions(
455                 DLFolder.class, folder.getFolderId(),
456                 importedFolder.getFolderId());
457         }
458         catch (NoSuchFolderException nsfe) {
459             _log.error(
460                 "Could not find the parent folder for folder " +
461                     folder.getFolderId());
462         }
463     }
464 
465     public PortletPreferences deleteData(
466             PortletDataContext context, String portletId,
467             PortletPreferences preferences)
468         throws PortletDataException {
469 
470         try {
471             if (!context.addPrimaryKey(
472                     DLPortletDataHandlerImpl.class, "deleteData")) {
473 
474                 DLFolderLocalServiceUtil.deleteFolders(context.getGroupId());
475             }
476 
477             return null;
478         }
479         catch (Exception e) {
480             throw new PortletDataException(e);
481         }
482     }
483 
484     public String exportData(
485             PortletDataContext context, String portletId,
486             PortletPreferences preferences)
487         throws PortletDataException {
488 
489         try {
490             Document doc = SAXReaderUtil.createDocument();
491 
492             Element root = doc.addElement("documentlibrary-data");
493 
494             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
495 
496             Element foldersEl = root.addElement("folders");
497             Element fileEntriesEl = root.addElement("file-entries");
498             Element fileShortcutsEl = root.addElement("file-shortcuts");
499             Element fileRanksEl = root.addElement("file-ranks");
500 
501             List<DLFolder> folders = DLFolderUtil.findByGroupId(
502                 context.getGroupId());
503 
504             for (DLFolder folder : folders) {
505                 exportFolder(
506                     context, foldersEl, fileEntriesEl, fileShortcutsEl,
507                     fileRanksEl, folder);
508             }
509 
510             List<DLFileEntry> fileEntries = DLFileEntryUtil.findByG_F(
511                 context.getGroupId(),
512                 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
513 
514             for (DLFileEntry fileEntry : fileEntries) {
515                 exportFileEntry(
516                     context, foldersEl, fileEntriesEl, fileRanksEl, fileEntry);
517             }
518 
519             return doc.formattedString();
520         }
521         catch (Exception e) {
522             throw new PortletDataException(e);
523         }
524     }
525 
526     public PortletDataHandlerControl[] getExportControls() {
527         return new PortletDataHandlerControl[] {
528             _foldersAndDocuments, _shortcuts, _ranks, _categories, _comments,
529             _ratings, _tags
530         };
531     }
532 
533     public PortletDataHandlerControl[] getImportControls() {
534         return new PortletDataHandlerControl[] {
535             _foldersAndDocuments, _shortcuts, _ranks, _categories, _comments,
536             _ratings, _tags
537         };
538     }
539 
540     public PortletPreferences importData(
541             PortletDataContext context, String portletId,
542             PortletPreferences preferences, String data)
543         throws PortletDataException {
544 
545         try {
546             Document doc = SAXReaderUtil.read(data);
547 
548             Element root = doc.getRootElement();
549 
550             List<Element> folderEls = root.element("folders").elements(
551                 "folder");
552 
553             Map<Long, Long> folderPKs =
554                 (Map<Long, Long>)context.getNewPrimaryKeysMap(DLFolder.class);
555 
556             for (Element folderEl : folderEls) {
557                 String path = folderEl.attributeValue("path");
558 
559                 if (!context.isPathNotProcessed(path)) {
560                     continue;
561                 }
562 
563                 DLFolder folder = (DLFolder)context.getZipEntryAsObject(path);
564 
565                 importFolder(context, folderPKs, folder);
566             }
567 
568             List<Element> fileEntryEls = root.element("file-entries").elements(
569                 "file-entry");
570 
571             Map<String, String> fileEntryNames =
572                 (Map<String, String>)context.getNewPrimaryKeysMap(
573                     DLFileEntry.class);
574 
575             for (Element fileEntryEl : fileEntryEls) {
576                 String path = fileEntryEl.attributeValue("path");
577 
578                 if (!context.isPathNotProcessed(path)) {
579                     continue;
580                 }
581 
582                 DLFileEntry fileEntry =
583                     (DLFileEntry)context.getZipEntryAsObject(path);
584 
585                 String binPath = fileEntryEl.attributeValue("bin-path");
586 
587                 importFileEntry(
588                     context, folderPKs, fileEntryNames, fileEntry, binPath);
589             }
590 
591             if (context.getBooleanParameter(_NAMESPACE, "shortcuts")) {
592                 List<Element> fileShortcutEls = root.element(
593                     "file-shortcuts").elements("file-shortcut");
594 
595                 for (Element fileShortcutEl : fileShortcutEls) {
596                     String path = fileShortcutEl.attributeValue("path");
597 
598                     if (!context.isPathNotProcessed(path)) {
599                         continue;
600                     }
601 
602                     DLFileShortcut fileShortcut =
603                         (DLFileShortcut)context.getZipEntryAsObject(path);
604 
605                     importFileShortcut(
606                         context, folderPKs, fileEntryNames, fileShortcut);
607                 }
608             }
609 
610             if (context.getBooleanParameter(_NAMESPACE, "ranks")) {
611                 List<Element> fileRankEls = root.element("file-ranks").elements(
612                     "file-rank");
613 
614                 for (Element fileRankEl : fileRankEls) {
615                     String path = fileRankEl.attributeValue("path");
616 
617                     if (!context.isPathNotProcessed(path)) {
618                         continue;
619                     }
620 
621                     DLFileRank fileRank =
622                         (DLFileRank)context.getZipEntryAsObject(path);
623 
624                     importFileRank(
625                         context, folderPKs, fileEntryNames, fileRank);
626                 }
627             }
628 
629             return null;
630         }
631         catch (Exception e) {
632             throw new PortletDataException(e);
633         }
634     }
635 
636     protected static void exportFileRank(
637             PortletDataContext context, Element fileRanksEl,
638             DLFileRank fileRank)
639         throws SystemException {
640 
641         String path = getFileRankPath(context, fileRank);
642 
643         if (!context.isPathNotProcessed(path)) {
644             return;
645         }
646 
647         Element fileRankEl = fileRanksEl.addElement("file-rank");
648 
649         fileRankEl.addAttribute("path", path);
650 
651         fileRank.setUserUuid(fileRank.getUserUuid());
652 
653         context.addZipEntry(path, fileRank);
654     }
655 
656     protected static void exportFileShortcut(
657             PortletDataContext context, Element foldersEl,
658             Element fileShortcutsEl, DLFileShortcut fileShortcut)
659         throws PortalException, SystemException {
660 
661         exportParentFolder(context, foldersEl, fileShortcut.getFolderId());
662 
663         String path = getFileShortcutPath(context, fileShortcut);
664 
665         if (context.isPathNotProcessed(path)) {
666             Element fileShortcutEl = fileShortcutsEl.addElement(
667                 "file-shortcut");
668 
669             fileShortcutEl.addAttribute("path", path);
670 
671             fileShortcut.setUserUuid(fileShortcut.getUserUuid());
672 
673             context.addPermissions(
674                 DLFileShortcut.class, fileShortcut.getFileShortcutId());
675 
676             context.addZipEntry(path, fileShortcut);
677         }
678     }
679 
680     protected static void exportParentFolder(
681             PortletDataContext context, Element foldersEl, long folderId)
682         throws PortalException, SystemException {
683 
684         if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
685             return;
686         }
687 
688         DLFolder folder = DLFolderUtil.findByPrimaryKey(folderId);
689 
690         exportParentFolder(context, foldersEl, folder.getParentFolderId());
691 
692         String path = getFolderPath(context, folder);
693 
694         if (context.isPathNotProcessed(path)) {
695             Element folderEl = foldersEl.addElement("folder");
696 
697             folderEl.addAttribute("path", path);
698 
699             folder.setUserUuid(folder.getUserUuid());
700 
701             context.addPermissions(DLFolder.class, folder.getFolderId());
702 
703             context.addZipEntry(path, folder);
704         }
705     }
706 
707     protected static String getFileEntryBinPath(
708         PortletDataContext context, DLFileEntry fileEntry) {
709 
710         StringBundler sb = new StringBundler(5);
711 
712         sb.append(context.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
713         sb.append("/bin/");
714         sb.append(fileEntry.getFileEntryId());
715         sb.append(StringPool.SLASH);
716         sb.append(fileEntry.getVersion());
717 
718         return sb.toString();
719     }
720 
721     protected static String getFileEntryPath(
722         PortletDataContext context, DLFileEntry fileEntry) {
723 
724         StringBundler sb = new StringBundler(6);
725 
726         sb.append(context.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
727         sb.append("/file-entries/");
728         sb.append(fileEntry.getFileEntryId());
729         sb.append(StringPool.SLASH);
730         sb.append(fileEntry.getVersion());
731         sb.append(".xml");
732 
733         return sb.toString();
734     }
735 
736     protected static String getFolderName(
737             long companyId, long groupId, long parentFolderId, String name,
738             int count)
739         throws SystemException {
740 
741         DLFolder folder = DLFolderUtil.fetchByG_P_N(
742             groupId, parentFolderId, name);
743 
744         if (folder == null) {
745             return name;
746         }
747 
748         if (Pattern.matches(".* \\(\\d+\\)", name)) {
749             int pos = name.lastIndexOf(" (");
750 
751             name = name.substring(0, pos);
752         }
753 
754         StringBundler sb = new StringBundler(5);
755 
756         sb.append(name);
757         sb.append(StringPool.SPACE);
758         sb.append(StringPool.OPEN_PARENTHESIS);
759         sb.append(count);
760         sb.append(StringPool.CLOSE_PARENTHESIS);
761 
762         name = sb.toString();
763 
764         return getFolderName(companyId, groupId, parentFolderId, name, ++count);
765     }
766 
767     protected static String getFolderPath(
768         PortletDataContext context, DLFolder folder) {
769 
770         StringBundler sb = new StringBundler(4);
771 
772         sb.append(context.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
773         sb.append("/folders/");
774         sb.append(folder.getFolderId());
775         sb.append(".xml");
776 
777         return sb.toString();
778     }
779 
780     protected static String getFileRankPath(
781         PortletDataContext context, DLFileRank fileRank) {
782 
783         StringBundler sb = new StringBundler(4);
784 
785         sb.append(context.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
786         sb.append("/ranks/");
787         sb.append(fileRank.getFileRankId());
788         sb.append(".xml");
789 
790         return sb.toString();
791     }
792 
793     protected static String getFileShortcutPath(
794         PortletDataContext context, DLFileShortcut fileShortcut) {
795 
796         StringBundler sb = new StringBundler(4);
797 
798         sb.append(context.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
799         sb.append("/shortcuts/");
800         sb.append(fileShortcut.getFileShortcutId());
801         sb.append(".xml");
802 
803         return sb.toString();
804     }
805 
806     protected static String getImportFolderPath(
807         PortletDataContext context, long folderId) {
808 
809         StringBundler sb = new StringBundler(4);
810 
811         sb.append(context.getSourcePortletPath(PortletKeys.DOCUMENT_LIBRARY));
812         sb.append("/folders/");
813         sb.append(folderId);
814         sb.append(".xml");
815 
816         return sb.toString();
817     }
818 
819     protected static long getRepositoryId(long groupId, long folderId) {
820         if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
821             return groupId;
822         }
823         else {
824             return folderId;
825         }
826     }
827 
828     protected static void importFileShortcut(
829             PortletDataContext context, Map<Long, Long> folderPKs,
830             Map<String, String> fileEntryNames, DLFileShortcut fileShortcut)
831         throws Exception {
832 
833         long userId = context.getUserId(fileShortcut.getUserUuid());
834         long folderId = MapUtil.getLong(
835             folderPKs, fileShortcut.getFolderId(), fileShortcut.getFolderId());
836         long toFolderId = MapUtil.getLong(
837             folderPKs, fileShortcut.getToFolderId(),
838             fileShortcut.getToFolderId());
839         String toName = MapUtil.getString(
840             fileEntryNames, fileShortcut.getToName(), fileShortcut.getToName());
841 
842         try {
843             DLFolder folder = DLFolderUtil.findByPrimaryKey(folderId);
844             DLFolderUtil.findByPrimaryKey(toFolderId);
845 
846             long groupId = folder.getGroupId();
847 
848             DLFileEntry fileEntry = DLFileEntryLocalServiceUtil.getFileEntry(
849                 groupId, toFolderId, toName);
850 
851             long[] assetCategoryIds = null;
852             String[] assetTagNames = null;
853 
854             if (context.getBooleanParameter(_NAMESPACE, "categories")) {
855                 assetCategoryIds = context.getAssetCategoryIds(
856                     DLFileEntry.class, fileEntry.getFileEntryId());
857             }
858 
859             if (context.getBooleanParameter(_NAMESPACE, "tags")) {
860                 assetTagNames = context.getAssetTagNames(
861                     DLFileEntry.class, fileEntry.getFileEntryId());
862             }
863 
864             ServiceContext serviceContext = new ServiceContext();
865 
866             serviceContext.setAddCommunityPermissions(true);
867             serviceContext.setAddGuestPermissions(true);
868             serviceContext.setAssetCategoryIds(assetCategoryIds);
869             serviceContext.setAssetTagNames(assetTagNames);
870             serviceContext.setCreateDate(fileShortcut.getCreateDate());
871             serviceContext.setModifiedDate(fileShortcut.getModifiedDate());
872             serviceContext.setScopeGroupId(context.getGroupId());
873 
874             DLFileShortcut importedFileShortcut = null;
875 
876             if (context.getDataStrategy().equals(
877                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
878 
879                 DLFileShortcut existingFileShortcut =
880                     DLFileShortcutUtil.fetchByUUID_G(
881                         fileShortcut.getUuid(), context.getGroupId());
882 
883                 if (existingFileShortcut == null) {
884                     importedFileShortcut =
885                         DLFileShortcutLocalServiceUtil.addFileShortcut(
886                             fileShortcut.getUuid(), userId, groupId, folderId,
887                             toFolderId, toName, serviceContext);
888                 }
889                 else {
890                     importedFileShortcut =
891                         DLFileShortcutLocalServiceUtil.updateFileShortcut(
892                             userId, existingFileShortcut.getFileShortcutId(),
893                             folderId, toFolderId, toName, serviceContext);
894                 }
895             }
896             else {
897                 importedFileShortcut =
898                     DLFileShortcutLocalServiceUtil.addFileShortcut(
899                         null, userId, groupId, folderId, toFolderId, toName,
900                         serviceContext);
901             }
902 
903             context.importPermissions(
904                 DLFileShortcut.class, fileShortcut.getPrimaryKey(),
905                 importedFileShortcut.getPrimaryKey());
906         }
907         catch (NoSuchFolderException nsfe) {
908             _log.error(
909                 "Could not find the folder for shortcut " +
910                     fileShortcut.getFileShortcutId());
911         }
912     }
913 
914     protected static boolean isDuplicateFileEntry(
915         DLFileEntry fileEntry1, DLFileEntry fileEntry2) {
916 
917         try {
918             DLFolder folder1 = fileEntry1.getFolder();
919             DLFolder folder2 = fileEntry2.getFolder();
920 
921             if ((folder1.getUuid().equals(folder2.getUuid())) &&
922                 (fileEntry1.getSize() == fileEntry2.getSize()) &&
923                 (DLUtil.compareVersions(
924                     fileEntry1.getVersion(), fileEntry2.getVersion()) == 0) &&
925                 (fileEntry1.getVersionUserUuid().equals(
926                     fileEntry2.getVersionUserUuid()))) {
927 
928                 return true;
929             }
930             else {
931                 return false;
932             }
933         }
934         catch (SystemException se) {
935             return false;
936         }
937     }
938 
939     private static final String _NAMESPACE = "document_library";
940 
941     private static final PortletDataHandlerBoolean _foldersAndDocuments =
942         new PortletDataHandlerBoolean(
943             _NAMESPACE, "folders-and-documents", true, true);
944 
945     private static final PortletDataHandlerBoolean _ranks =
946         new PortletDataHandlerBoolean(_NAMESPACE, "ranks");
947 
948     private static final PortletDataHandlerBoolean _shortcuts=
949         new PortletDataHandlerBoolean(_NAMESPACE, "shortcuts");
950 
951     private static final PortletDataHandlerBoolean _categories =
952         new PortletDataHandlerBoolean(_NAMESPACE, "categories");
953 
954     private static final PortletDataHandlerBoolean _comments =
955         new PortletDataHandlerBoolean(_NAMESPACE, "comments");
956 
957     private static final PortletDataHandlerBoolean _ratings =
958         new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
959 
960     private static final PortletDataHandlerBoolean _tags =
961         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
962 
963     private static Log _log = LogFactoryUtil.getLog(
964         DLPortletDataHandlerImpl.class);
965 
966 }