001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.bookmarks.lar;
016    
017    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
018    import com.liferay.portal.kernel.lar.PortletDataContext;
019    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
020    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
021    import com.liferay.portal.kernel.util.MapUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.xml.Document;
024    import com.liferay.portal.kernel.xml.Element;
025    import com.liferay.portal.kernel.xml.SAXReaderUtil;
026    import com.liferay.portal.service.ServiceContext;
027    import com.liferay.portal.util.PortletKeys;
028    import com.liferay.portlet.bookmarks.model.BookmarksEntry;
029    import com.liferay.portlet.bookmarks.model.BookmarksFolder;
030    import com.liferay.portlet.bookmarks.model.BookmarksFolderConstants;
031    import com.liferay.portlet.bookmarks.service.BookmarksEntryLocalServiceUtil;
032    import com.liferay.portlet.bookmarks.service.BookmarksFolderLocalServiceUtil;
033    import com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryUtil;
034    import com.liferay.portlet.bookmarks.service.persistence.BookmarksFolderUtil;
035    
036    import java.util.List;
037    import java.util.Map;
038    
039    import javax.portlet.PortletPreferences;
040    
041    /**
042     * @author Jorge Ferrer
043     * @author Bruno Farache
044     * @author Raymond Aug??
045     * @author Juan Fern??ndez
046     */
047    public class BookmarksPortletDataHandlerImpl extends BasePortletDataHandler {
048    
049            @Override
050            public PortletDataHandlerControl[] getExportControls() {
051                    return new PortletDataHandlerControl[] {
052                            _foldersAndEntries
053                    };
054            }
055    
056            @Override
057            public PortletDataHandlerControl[] getExportMetadataControls() {
058                    return new PortletDataHandlerControl[] {
059                            new PortletDataHandlerBoolean(
060                                    _NAMESPACE, "bookmarks", true, _metadataControls)
061                    };
062            }
063    
064            @Override
065            public PortletDataHandlerControl[] getImportControls() {
066                    return new PortletDataHandlerControl[] {
067                            _foldersAndEntries
068                    };
069            }
070    
071            @Override
072            public PortletDataHandlerControl[] getImportMetadataControls() {
073                    return new PortletDataHandlerControl[] {
074                            new PortletDataHandlerBoolean(
075                                    _NAMESPACE, "bookmarks", true, _metadataControls)
076                    };
077            }
078    
079            @Override
080            public boolean isAlwaysExportable() {
081                    return _ALWAYS_EXPORTABLE;
082            }
083    
084            @Override
085            public boolean isPublishToLiveByDefault() {
086                    return _PUBLISH_TO_LIVE_BY_DEFAULT;
087            }
088    
089            @Override
090            protected PortletPreferences doDeleteData(
091                            PortletDataContext portletDataContext, String portletId,
092                            PortletPreferences portletPreferences)
093                    throws Exception {
094    
095                    if (!portletDataContext.addPrimaryKey(
096                                    BookmarksPortletDataHandlerImpl.class, "deleteData")) {
097    
098                            BookmarksFolderLocalServiceUtil.deleteFolders(
099                                    portletDataContext.getScopeGroupId());
100    
101                            BookmarksEntryLocalServiceUtil.deleteEntries(
102                                    portletDataContext.getScopeGroupId(),
103                                    BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID);
104                    }
105    
106                    return null;
107            }
108    
109            @Override
110            protected String doExportData(
111                            PortletDataContext portletDataContext, String portletId,
112                            PortletPreferences portletPreferences)
113                    throws Exception {
114    
115                    portletDataContext.addPermissions(
116                            "com.liferay.portlet.bookmarks",
117                            portletDataContext.getScopeGroupId());
118    
119                    Document document = SAXReaderUtil.createDocument();
120    
121                    Element rootElement = document.addElement("bookmarks-data");
122    
123                    rootElement.addAttribute(
124                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
125    
126                    Element foldersElement = rootElement.addElement("folders");
127                    Element entriesElement = rootElement.addElement("entries");
128    
129                    List<BookmarksFolder> folders = BookmarksFolderUtil.findByGroupId(
130                            portletDataContext.getScopeGroupId());
131    
132                    for (BookmarksFolder folder : folders) {
133                            exportFolder(
134                                    portletDataContext, foldersElement, entriesElement, folder);
135                    }
136    
137                    List<BookmarksEntry> entries = BookmarksEntryUtil.findByG_F(
138                            portletDataContext.getScopeGroupId(),
139                            BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID);
140    
141                    for (BookmarksEntry entry : entries) {
142                            exportEntry(portletDataContext, null, entriesElement, entry);
143                    }
144    
145                    return document.formattedString();
146            }
147    
148            @Override
149            protected PortletPreferences doImportData(
150                            PortletDataContext portletDataContext, String portletId,
151                            PortletPreferences portletPreferences, String data)
152                    throws Exception {
153    
154                    portletDataContext.importPermissions(
155                            "com.liferay.portlet.bookmarks",
156                            portletDataContext.getSourceGroupId(),
157                            portletDataContext.getScopeGroupId());
158    
159                    Document document = SAXReaderUtil.read(data);
160    
161                    Element rootElement = document.getRootElement();
162    
163                    Element foldersElement = rootElement.element("folders");
164    
165                    for (Element folderElement : foldersElement.elements("folder")) {
166                            String path = folderElement.attributeValue("path");
167    
168                            if (!portletDataContext.isPathNotProcessed(path)) {
169                                    continue;
170                            }
171    
172                            BookmarksFolder folder =
173                                    (BookmarksFolder)portletDataContext.getZipEntryAsObject(path);
174    
175                            importFolder(portletDataContext, path, folder);
176                    }
177    
178                    Element entriesElement = rootElement.element("entries");
179    
180                    for (Element entryElement : entriesElement.elements("entry")) {
181                            String path = entryElement.attributeValue("path");
182    
183                            if (!portletDataContext.isPathNotProcessed(path)) {
184                                    continue;
185                            }
186    
187                            BookmarksEntry entry =
188                                    (BookmarksEntry)portletDataContext.getZipEntryAsObject(path);
189    
190                            importEntry(portletDataContext, entryElement, entry);
191                    }
192    
193                    return null;
194            }
195    
196            protected void exportEntry(
197                            PortletDataContext portletDataContext, Element foldersElement,
198                            Element entriesElement, BookmarksEntry entry)
199                    throws Exception {
200    
201                    if (!portletDataContext.isWithinDateRange(entry.getModifiedDate())) {
202                            return;
203                    }
204    
205                    if (foldersElement != null) {
206                            exportParentFolder(
207                                    portletDataContext, foldersElement, entry.getFolderId());
208                    }
209    
210                    String path = getEntryPath(portletDataContext, entry);
211    
212                    if (portletDataContext.isPathNotProcessed(path)) {
213                            Element entryElement = entriesElement.addElement("entry");
214    
215                            portletDataContext.addClassedModel(
216                                    entryElement, path, entry, _NAMESPACE);
217                    }
218            }
219    
220            protected void exportFolder(
221                            PortletDataContext portletDataContext, Element foldersElement,
222                            Element entriesElement, BookmarksFolder folder)
223                    throws Exception {
224    
225                    if (portletDataContext.isWithinDateRange(folder.getModifiedDate())) {
226                            exportParentFolder(
227                                    portletDataContext, foldersElement, folder.getParentFolderId());
228    
229                            String path = getFolderPath(portletDataContext, folder);
230    
231                            if (portletDataContext.isPathNotProcessed(path)) {
232                                    Element folderElement = foldersElement.addElement("folder");
233    
234                                    portletDataContext.addClassedModel(
235                                            folderElement, path, folder, _NAMESPACE);
236                            }
237                    }
238    
239                    List<BookmarksEntry> entries = BookmarksEntryUtil.findByG_F(
240                            folder.getGroupId(), folder.getFolderId());
241    
242                    for (BookmarksEntry entry : entries) {
243                            exportEntry(
244                                    portletDataContext, foldersElement, entriesElement, entry);
245                    }
246            }
247    
248            protected void exportParentFolder(
249                            PortletDataContext portletDataContext, Element foldersElement,
250                            long folderId)
251                    throws Exception {
252    
253                    if (folderId == BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
254                            return;
255                    }
256    
257                    BookmarksFolder folder = BookmarksFolderUtil.findByPrimaryKey(folderId);
258    
259                    exportParentFolder(
260                            portletDataContext, foldersElement, folder.getParentFolderId());
261    
262                    String path = getFolderPath(portletDataContext, folder);
263    
264                    if (portletDataContext.isPathNotProcessed(path)) {
265                            Element folderElement = foldersElement.addElement("folder");
266    
267                            portletDataContext.addClassedModel(
268                                    folderElement, path, folder, _NAMESPACE);
269                    }
270            }
271    
272            protected String getEntryPath(
273                    PortletDataContext portletDataContext, BookmarksEntry entry) {
274    
275                    StringBundler sb = new StringBundler(4);
276    
277                    sb.append(portletDataContext.getPortletPath(PortletKeys.BOOKMARKS));
278                    sb.append("/entries/");
279                    sb.append(entry.getEntryId());
280                    sb.append(".xml");
281    
282                    return sb.toString();
283            }
284    
285            protected String getFolderPath(
286                    PortletDataContext portletDataContext, BookmarksFolder folder) {
287    
288                    StringBundler sb = new StringBundler(4);
289    
290                    sb.append(portletDataContext.getPortletPath(PortletKeys.BOOKMARKS));
291                    sb.append("/folders/");
292                    sb.append(folder.getFolderId());
293                    sb.append(".xml");
294    
295                    return sb.toString();
296            }
297    
298            protected String getImportFolderPath(
299                    PortletDataContext portletDataContext, long folderId) {
300    
301                    StringBundler sb = new StringBundler(4);
302    
303                    sb.append(
304                            portletDataContext.getSourcePortletPath(PortletKeys.BOOKMARKS));
305                    sb.append("/folders/");
306                    sb.append(folderId);
307                    sb.append(".xml");
308    
309                    return sb.toString();
310            }
311    
312            protected void importEntry(
313                            PortletDataContext portletDataContext, Element entryElement,
314                            BookmarksEntry entry)
315                    throws Exception {
316    
317                    long userId = portletDataContext.getUserId(entry.getUserUuid());
318    
319                    Map<Long, Long> folderIds =
320                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
321                                    BookmarksFolder.class);
322    
323                    long folderId = MapUtil.getLong(
324                            folderIds, entry.getFolderId(), entry.getFolderId());
325    
326                    if ((folderId != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
327                            (folderId == entry.getFolderId())) {
328    
329                            String path = getImportFolderPath(portletDataContext, folderId);
330    
331                            BookmarksFolder folder =
332                                    (BookmarksFolder)portletDataContext.getZipEntryAsObject(path);
333    
334                            importFolder(portletDataContext, path, folder);
335    
336                            folderId = MapUtil.getLong(
337                                    folderIds, entry.getFolderId(), entry.getFolderId());
338                    }
339    
340                    ServiceContext serviceContext = portletDataContext.createServiceContext(
341                            entryElement, entry, _NAMESPACE);
342    
343                    BookmarksEntry importedEntry = null;
344    
345                    if (portletDataContext.isDataStrategyMirror()) {
346                            BookmarksEntry existingEntry = BookmarksEntryUtil.fetchByUUID_G(
347                                    entry.getUuid(), portletDataContext.getScopeGroupId());
348    
349                            if (existingEntry == null) {
350                                    serviceContext.setUuid(entry.getUuid());
351    
352                                    importedEntry = BookmarksEntryLocalServiceUtil.addEntry(
353                                            userId, portletDataContext.getScopeGroupId(), folderId,
354                                            entry.getName(), entry.getUrl(), entry.getDescription(),
355                                            serviceContext);
356                            }
357                            else {
358                                    importedEntry = BookmarksEntryLocalServiceUtil.updateEntry(
359                                            userId, existingEntry.getEntryId(),
360                                            portletDataContext.getScopeGroupId(), folderId,
361                                            entry.getName(), entry.getUrl(), entry.getDescription(),
362                                            serviceContext);
363                            }
364                    }
365                    else {
366                            importedEntry = BookmarksEntryLocalServiceUtil.addEntry(
367                                    userId, portletDataContext.getScopeGroupId(), folderId,
368                                    entry.getName(), entry.getUrl(), entry.getDescription(),
369                                    serviceContext);
370                    }
371    
372                    portletDataContext.importClassedModel(entry, importedEntry, _NAMESPACE);
373            }
374    
375            protected void importFolder(
376                            PortletDataContext portletDataContext, String folderPath,
377                            BookmarksFolder folder)
378                    throws Exception {
379    
380                    long userId = portletDataContext.getUserId(folder.getUserUuid());
381    
382                    Map<Long, Long> folderIds =
383                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
384                                    BookmarksFolder.class);
385    
386                    long parentFolderId = MapUtil.getLong(
387                            folderIds, folder.getParentFolderId(), folder.getParentFolderId());
388    
389                    if ((parentFolderId !=
390                                    BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
391                            (parentFolderId == folder.getParentFolderId())) {
392    
393                            String path = getImportFolderPath(
394                                    portletDataContext, parentFolderId);
395    
396                            BookmarksFolder parentFolder =
397                                    (BookmarksFolder)portletDataContext.getZipEntryAsObject(path);
398    
399                            importFolder(portletDataContext, path, parentFolder);
400    
401                            parentFolderId = MapUtil.getLong(
402                                    folderIds, folder.getParentFolderId(),
403                                    folder.getParentFolderId());
404                    }
405    
406                    ServiceContext serviceContext = portletDataContext.createServiceContext(
407                            folderPath, folder, _NAMESPACE);
408    
409                    BookmarksFolder importedFolder = null;
410    
411                    if (portletDataContext.isDataStrategyMirror()) {
412                            BookmarksFolder existingFolder = BookmarksFolderUtil.fetchByUUID_G(
413                                    folder.getUuid(), portletDataContext.getScopeGroupId());
414    
415                            if (existingFolder == null) {
416                                    serviceContext.setUuid(folder.getUuid());
417    
418                                    importedFolder = BookmarksFolderLocalServiceUtil.addFolder(
419                                            userId, parentFolderId, folder.getName(),
420                                            folder.getDescription(), serviceContext);
421                            }
422                            else {
423                                    importedFolder = BookmarksFolderLocalServiceUtil.updateFolder(
424                                            existingFolder.getFolderId(), parentFolderId,
425                                            folder.getName(), folder.getDescription(), false,
426                                            serviceContext);
427                            }
428                    }
429                    else {
430                            importedFolder = BookmarksFolderLocalServiceUtil.addFolder(
431                                    userId, parentFolderId, folder.getName(),
432                                    folder.getDescription(), serviceContext);
433                    }
434    
435                    portletDataContext.importClassedModel(
436                            folder, importedFolder, _NAMESPACE);
437            }
438    
439            private static final boolean _ALWAYS_EXPORTABLE = true;
440    
441            private static final String _NAMESPACE = "bookmarks";
442    
443            private static final boolean _PUBLISH_TO_LIVE_BY_DEFAULT = true;
444    
445            private static PortletDataHandlerBoolean _foldersAndEntries =
446                    new PortletDataHandlerBoolean(
447                            _NAMESPACE, "folders-and-entries", true, true);
448            private static PortletDataHandlerControl[] _metadataControls =
449                    new PortletDataHandlerControl[] {
450                            new PortletDataHandlerBoolean(_NAMESPACE, "categories"),
451                            new PortletDataHandlerBoolean(_NAMESPACE, "ratings"),
452                            new PortletDataHandlerBoolean(_NAMESPACE, "tags")
453                    };
454    
455    }