1   /**
2    * Copyright (c) 2000-2009 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.bookmarks.lar;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.xml.Document;
30  import com.liferay.portal.kernel.xml.Element;
31  import com.liferay.portal.kernel.xml.SAXReaderUtil;
32  import com.liferay.portal.lar.BasePortletDataHandler;
33  import com.liferay.portal.lar.PortletDataContext;
34  import com.liferay.portal.lar.PortletDataException;
35  import com.liferay.portal.lar.PortletDataHandlerBoolean;
36  import com.liferay.portal.lar.PortletDataHandlerControl;
37  import com.liferay.portal.lar.PortletDataHandlerKeys;
38  import com.liferay.portal.service.ServiceContext;
39  import com.liferay.portal.util.PortletKeys;
40  import com.liferay.portlet.bookmarks.NoSuchEntryException;
41  import com.liferay.portlet.bookmarks.NoSuchFolderException;
42  import com.liferay.portlet.bookmarks.model.BookmarksEntry;
43  import com.liferay.portlet.bookmarks.model.BookmarksFolder;
44  import com.liferay.portlet.bookmarks.model.impl.BookmarksFolderImpl;
45  import com.liferay.portlet.bookmarks.service.BookmarksEntryLocalServiceUtil;
46  import com.liferay.portlet.bookmarks.service.BookmarksFolderLocalServiceUtil;
47  import com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryFinderUtil;
48  import com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryUtil;
49  import com.liferay.portlet.bookmarks.service.persistence.BookmarksFolderUtil;
50  import com.liferay.util.MapUtil;
51  
52  import java.util.List;
53  import java.util.Map;
54  
55  import javax.portlet.PortletPreferences;
56  
57  /**
58   * <a href="BookmarksPortletDataHandlerImpl.java.html"><b><i>View Source</i></b>
59   * </a>
60   *
61   * @author Jorge Ferrer
62   * @author Bruno Farache
63   * @author Raymond Augé
64   *
65   */
66  public class BookmarksPortletDataHandlerImpl extends BasePortletDataHandler {
67  
68      public PortletPreferences deleteData(
69              PortletDataContext context, String portletId,
70              PortletPreferences preferences)
71          throws PortletDataException {
72  
73          try {
74              if (!context.addPrimaryKey(
75                      BookmarksPortletDataHandlerImpl.class, "deleteData")) {
76  
77                  BookmarksFolderLocalServiceUtil.deleteFolders(
78                      context.getGroupId());
79              }
80  
81              return null;
82          }
83          catch (Exception e) {
84              throw new PortletDataException(e);
85          }
86      }
87  
88      public String exportData(
89              PortletDataContext context, String portletId,
90              PortletPreferences preferences)
91          throws PortletDataException {
92  
93          try {
94              Document doc = SAXReaderUtil.createDocument();
95  
96              Element root = doc.addElement("bookmarks-data");
97  
98              root.addAttribute("group-id", String.valueOf(context.getGroupId()));
99  
100             Element foldersEl = root.addElement("folders");
101             Element entriesEl = root.addElement("entries");
102 
103             List<BookmarksFolder> folders = BookmarksFolderUtil.findByGroupId(
104                 context.getGroupId());
105 
106             for (BookmarksFolder folder : folders) {
107                 exportFolder(context, foldersEl, entriesEl, folder);
108             }
109 
110             return doc.formattedString();
111         }
112         catch (Exception e) {
113             throw new PortletDataException(e);
114         }
115     }
116 
117     public PortletDataHandlerControl[] getExportControls() {
118         return new PortletDataHandlerControl[] {_foldersAndEntries, _tags};
119     }
120 
121     public PortletDataHandlerControl[] getImportControls() {
122         return new PortletDataHandlerControl[] {_foldersAndEntries, _tags};
123     }
124 
125     public PortletPreferences importData(
126             PortletDataContext context, String portletId,
127             PortletPreferences preferences, String data)
128         throws PortletDataException {
129 
130         try {
131             Document doc = SAXReaderUtil.read(data);
132 
133             Element root = doc.getRootElement();
134 
135             List<Element> folderEls = root.element("folders").elements(
136                 "folder");
137 
138             Map<Long, Long> folderPKs =
139                 (Map<Long, Long>)context.getNewPrimaryKeysMap(
140                     BookmarksFolder.class);
141 
142             for (Element folderEl : folderEls) {
143                 String path = folderEl.attributeValue("path");
144 
145                 if (!context.isPathNotProcessed(path)) {
146                     continue;
147                 }
148 
149                 BookmarksFolder folder =
150                     (BookmarksFolder)context.getZipEntryAsObject(path);
151 
152                 importFolder(context, folderPKs, folder);
153             }
154 
155             List<Element> entryEls = root.element("entries").elements("entry");
156 
157             for (Element entryEl : entryEls) {
158                 String path = entryEl.attributeValue("path");
159 
160                 if (!context.isPathNotProcessed(path)) {
161                     continue;
162                 }
163 
164                 BookmarksEntry entry =
165                     (BookmarksEntry)context.getZipEntryAsObject(path);
166 
167                 importEntry(context, folderPKs, entry);
168             }
169 
170             return null;
171         }
172         catch (Exception e) {
173             throw new PortletDataException(e);
174         }
175     }
176 
177     protected void exportFolder(
178             PortletDataContext context, Element foldersEl, Element entriesEl,
179             BookmarksFolder folder)
180         throws PortalException, SystemException {
181 
182         if (context.isWithinDateRange(folder.getModifiedDate())) {
183             exportParentFolder(context, foldersEl, folder.getParentFolderId());
184 
185             String path = getFolderPath(context, folder);
186 
187             if (context.isPathNotProcessed(path)) {
188                 Element folderEl = foldersEl.addElement("folder");
189 
190                 folderEl.addAttribute("path", path);
191 
192                 folder.setUserUuid(folder.getUserUuid());
193 
194                 context.addZipEntry(path, folder);
195             }
196         }
197 
198         List<BookmarksEntry> entries = BookmarksEntryUtil.findByFolderId(
199             folder.getFolderId());
200 
201         for (BookmarksEntry entry : entries) {
202             exportEntry(context, foldersEl, entriesEl, entry);
203         }
204     }
205 
206     protected void exportEntry(
207             PortletDataContext context, Element foldersEl, Element entriesEl,
208             BookmarksEntry entry)
209         throws PortalException, SystemException {
210 
211         if (!context.isWithinDateRange(entry.getModifiedDate())) {
212             return;
213         }
214 
215         exportParentFolder(context, foldersEl, entry.getFolderId());
216 
217         String path = getEntryPath(context, entry);
218 
219         if (context.isPathNotProcessed(path)) {
220             Element entryEl = entriesEl.addElement("entry");
221 
222             entryEl.addAttribute("path", path);
223 
224             if (context.getBooleanParameter(_NAMESPACE, "tags")) {
225                 context.addTagsEntries(
226                     BookmarksEntry.class, entry.getEntryId());
227             }
228 
229             entry.setUserUuid(entry.getUserUuid());
230 
231             context.addZipEntry(path, entry);
232         }
233     }
234 
235     protected void exportParentFolder(
236             PortletDataContext context, Element foldersEl, long folderId)
237         throws PortalException, SystemException {
238 
239         if (folderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
240             return;
241         }
242 
243         BookmarksFolder folder = BookmarksFolderUtil.findByPrimaryKey(folderId);
244 
245         exportParentFolder(context, foldersEl, folder.getParentFolderId());
246 
247         String path = getFolderPath(context, folder);
248 
249         if (context.isPathNotProcessed(path)) {
250             Element folderEl = foldersEl.addElement("folder");
251 
252             folderEl.addAttribute("path", path);
253 
254             folder.setUserUuid(folder.getUserUuid());
255 
256             context.addZipEntry(path, folder);
257         }
258     }
259 
260     protected String getEntryPath(
261         PortletDataContext context, BookmarksEntry entry) {
262 
263         StringBuilder sb = new StringBuilder();
264 
265         sb.append(context.getPortletPath(PortletKeys.BOOKMARKS));
266         sb.append("/entries/");
267         sb.append(entry.getEntryId());
268         sb.append(".xml");
269 
270         return sb.toString();
271     }
272 
273     protected String getFolderPath(
274         PortletDataContext context, BookmarksFolder folder) {
275 
276         StringBuilder sb = new StringBuilder();
277 
278         sb.append(context.getPortletPath(PortletKeys.BOOKMARKS));
279         sb.append("/folders/");
280         sb.append(folder.getFolderId());
281         sb.append(".xml");
282 
283         return sb.toString();
284     }
285 
286     protected String getImportFolderPath(
287         PortletDataContext context, long folderId) {
288 
289         StringBuilder sb = new StringBuilder();
290 
291         sb.append(context.getSourcePortletPath(PortletKeys.BOOKMARKS));
292         sb.append("/folders/");
293         sb.append(folderId);
294         sb.append(".xml");
295 
296         return sb.toString();
297     }
298 
299     protected void importEntry(
300             PortletDataContext context, Map<Long, Long> folderPKs,
301             BookmarksEntry entry)
302         throws Exception {
303 
304         long userId = context.getUserId(entry.getUserUuid());
305         long folderId = MapUtil.getLong(
306             folderPKs, entry.getFolderId(), entry.getFolderId());
307 
308         String[] tagsEntries = null;
309 
310         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
311             tagsEntries = context.getTagsEntries(
312                 BookmarksEntry.class, entry.getEntryId());
313         }
314 
315         ServiceContext serviceContext = new ServiceContext();
316 
317         serviceContext.setAddCommunityPermissions(true);
318         serviceContext.setAddGuestPermissions(true);
319         serviceContext.setTagsEntries(tagsEntries);
320 
321         if ((folderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) &&
322             (folderId == entry.getFolderId())) {
323 
324             String path = getImportFolderPath(context, folderId);
325 
326             BookmarksFolder folder =
327                 (BookmarksFolder)context.getZipEntryAsObject(path);
328 
329             importFolder(context, folderPKs, folder);
330 
331             folderId = MapUtil.getLong(
332                 folderPKs, entry.getFolderId(), entry.getFolderId());
333         }
334 
335         BookmarksEntry existingEntry = null;
336 
337         try {
338             BookmarksFolderUtil.findByPrimaryKey(folderId);
339 
340             if (context.getDataStrategy().equals(
341                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
342 
343                 try {
344                     existingEntry = BookmarksEntryFinderUtil.findByUuid_G(
345                         entry.getUuid(), context.getGroupId());
346 
347                     BookmarksEntryLocalServiceUtil.updateEntry(
348                         userId, existingEntry.getEntryId(), folderId,
349                         entry.getName(), entry.getUrl(), entry.getComments(),
350                         serviceContext);
351                 }
352                 catch (NoSuchEntryException nsee) {
353                     BookmarksEntryLocalServiceUtil.addEntry(
354                         entry.getUuid(), userId, folderId, entry.getName(),
355                         entry.getUrl(), entry.getComments(), serviceContext);
356                 }
357             }
358             else {
359                 BookmarksEntryLocalServiceUtil.addEntry(
360                     userId, folderId, entry.getName(), entry.getUrl(),
361                     entry.getComments(), serviceContext);
362             }
363         }
364         catch (NoSuchFolderException nsfe) {
365             _log.error(
366                 "Could not find the parent folder for entry " +
367                     entry.getEntryId());
368         }
369     }
370 
371     protected void importFolder(
372             PortletDataContext context, Map<Long, Long> folderPKs,
373             BookmarksFolder folder)
374         throws Exception {
375 
376         long userId = context.getUserId(folder.getUserUuid());
377         long parentFolderId = MapUtil.getLong(
378             folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
379 
380         ServiceContext serviceContext = new ServiceContext();
381 
382         serviceContext.setAddCommunityPermissions(true);
383         serviceContext.setAddGuestPermissions(true);
384         serviceContext.setScopeGroupId(context.getScopeGroupId());
385 
386         if ((parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) &&
387             (parentFolderId == folder.getParentFolderId())) {
388 
389             String path = getImportFolderPath(context, parentFolderId);
390 
391             BookmarksFolder parentFolder =
392                 (BookmarksFolder)context.getZipEntryAsObject(path);
393 
394             importFolder(context, folderPKs, parentFolder);
395 
396             parentFolderId = MapUtil.getLong(
397                 folderPKs, folder.getParentFolderId(),
398                 folder.getParentFolderId());
399         }
400 
401         BookmarksFolder existingFolder = null;
402 
403         try {
404             if (parentFolderId !=
405                     BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
406 
407                 BookmarksFolderUtil.findByPrimaryKey(parentFolderId);
408             }
409 
410             if (context.getDataStrategy().equals(
411                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
412                 existingFolder = BookmarksFolderUtil.fetchByUUID_G(
413                     folder.getUuid(), context.getGroupId());
414 
415                 if (existingFolder == null) {
416                     existingFolder = BookmarksFolderLocalServiceUtil.addFolder(
417                         folder.getUuid(), userId, parentFolderId,
418                         folder.getName(), folder.getDescription(),
419                         serviceContext);
420                 }
421                 else {
422                     existingFolder =
423                         BookmarksFolderLocalServiceUtil.updateFolder(
424                             existingFolder.getFolderId(), parentFolderId,
425                             folder.getName(), folder.getDescription(), false);
426                 }
427             }
428             else {
429                 existingFolder = BookmarksFolderLocalServiceUtil.addFolder(
430                     userId, parentFolderId, folder.getName(),
431                     folder.getDescription(), serviceContext);
432             }
433 
434             folderPKs.put(folder.getFolderId(), existingFolder.getFolderId());
435         }
436         catch (NoSuchFolderException nsfe) {
437             _log.error(
438                 "Could not find the parent folder for folder " +
439                     folder.getFolderId());
440         }
441     }
442 
443     private static final String _NAMESPACE = "bookmarks";
444 
445     private static final PortletDataHandlerBoolean _foldersAndEntries =
446         new PortletDataHandlerBoolean(
447             _NAMESPACE, "folders-and-entries", true, true);
448 
449     private static final PortletDataHandlerBoolean _tags =
450         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
451 
452     private static Log _log =
453         LogFactoryUtil.getLog(BookmarksPortletDataHandlerImpl.class);
454 
455 }