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