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.journal.lar;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.util.GetterUtil;
20  import com.liferay.portal.kernel.util.MapUtil;
21  import com.liferay.portal.kernel.util.StringPool;
22  import com.liferay.portal.kernel.util.Validator;
23  import com.liferay.portal.kernel.workflow.StatusConstants;
24  import com.liferay.portal.kernel.xml.Document;
25  import com.liferay.portal.kernel.xml.Element;
26  import com.liferay.portal.kernel.xml.SAXReaderUtil;
27  import com.liferay.portal.lar.BasePortletDataHandler;
28  import com.liferay.portal.lar.PortletDataContext;
29  import com.liferay.portal.lar.PortletDataException;
30  import com.liferay.portal.lar.PortletDataHandlerBoolean;
31  import com.liferay.portal.lar.PortletDataHandlerControl;
32  import com.liferay.portal.model.Layout;
33  import com.liferay.portal.service.LayoutLocalServiceUtil;
34  import com.liferay.portlet.documentlibrary.lar.DLPortletDataHandlerImpl;
35  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
36  import com.liferay.portlet.documentlibrary.model.DLFileRank;
37  import com.liferay.portlet.documentlibrary.model.DLFolder;
38  import com.liferay.portlet.imagegallery.lar.IGPortletDataHandlerImpl;
39  import com.liferay.portlet.imagegallery.model.IGFolder;
40  import com.liferay.portlet.imagegallery.model.IGImage;
41  import com.liferay.portlet.journal.NoSuchArticleException;
42  import com.liferay.portlet.journal.model.JournalArticle;
43  import com.liferay.portlet.journal.model.JournalStructure;
44  import com.liferay.portlet.journal.model.JournalTemplate;
45  import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
46  import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
47  import com.liferay.portlet.journal.service.persistence.JournalStructureUtil;
48  import com.liferay.portlet.journal.service.persistence.JournalTemplateUtil;
49  
50  import java.util.Collections;
51  import java.util.List;
52  import java.util.Map;
53  
54  import javax.portlet.PortletPreferences;
55  
56  /**
57   * <a href="JournalContentPortletDataHandlerImpl.java.html"><b><i>View Source
58   * </i></b></a>
59   *
60   * <p>
61   * Provides the Journal Content portlet export and import functionality, which
62   * is to clone the article, structure, and template referenced in the Journal
63   * Content portlet if the article is associated with the layout's group. Upon
64   * import, a new instance of the corresponding article, structure, and template
65   * will be created or updated. The author of the newly created objects are
66   * determined by the JournalCreationStrategy class defined in
67   * <i>portal.properties</i>.
68   * </p>
69   *
70   * <p>
71   * This <code>PortletDataHandler</code> differs from from
72   * <code>JournalPortletDataHandlerImpl</code> in that it only exports articles
73   * referenced in Journal Content portlets. Articles not displayed in Journal
74   * Content portlets will not be exported unless
75   * <code>JournalPortletDataHandlerImpl</code> is activated.
76   * </p>
77   *
78   * @author Joel Kozikowski
79   * @author Raymond Augé
80   * @author Bruno Farache
81   * @see    com.liferay.portal.lar.PortletDataHandler
82   * @see    com.liferay.portlet.journal.lar.JournalCreationStrategy
83   * @see    com.liferay.portlet.journal.lar.JournalPortletDataHandlerImpl
84   */
85  public class JournalContentPortletDataHandlerImpl
86      extends BasePortletDataHandler {
87  
88      public PortletPreferences deleteData(
89              PortletDataContext context, String portletId,
90              PortletPreferences preferences)
91          throws PortletDataException {
92  
93          try {
94              preferences.setValue("group-id", StringPool.BLANK);
95              preferences.setValue("article-id", StringPool.BLANK);
96  
97              return preferences;
98          }
99          catch (Exception e) {
100             throw new PortletDataException(e);
101         }
102     }
103 
104     public String exportData(
105             PortletDataContext context, String portletId,
106             PortletPreferences preferences)
107         throws PortletDataException {
108 
109         try {
110             String articleId = preferences.getValue("article-id", null);
111 
112             if (articleId == null) {
113                 if (_log.isWarnEnabled()) {
114                     _log.warn(
115                         "No article id found in preferences of portlet " +
116                             portletId);
117                 }
118 
119                 return StringPool.BLANK;
120             }
121 
122             long articleGroupId = GetterUtil.getLong(
123                 preferences.getValue("group-id", StringPool.BLANK));
124 
125             if (articleGroupId <= 0) {
126                 if (_log.isWarnEnabled()) {
127                     _log.warn(
128                         "No group id found in preferences of portlet " +
129                             portletId);
130                 }
131 
132                 return StringPool.BLANK;
133             }
134 
135             JournalArticle article = null;
136 
137             try {
138                 article = JournalArticleLocalServiceUtil.getLatestArticle(
139                     articleGroupId, articleId, StatusConstants.APPROVED);
140             }
141             catch (NoSuchArticleException nsae) {
142                 if (_log.isWarnEnabled()) {
143                     _log.warn(
144                         "No approved article found with group id " +
145                             articleGroupId + " and article id " + articleId);
146                 }
147             }
148 
149             if (article == null) {
150                 return StringPool.BLANK;
151             }
152 
153             Document doc = SAXReaderUtil.createDocument();
154 
155             Element root = doc.addElement("journal-content-data");
156 
157             Element dlFoldersEl = root.addElement("dl-folders");
158             Element dlFilesEl = root.addElement("dl-file-entries");
159             Element dlFileRanksEl = root.addElement("dl-file-ranks");
160             Element igFoldersEl = root.addElement("ig-folders");
161             Element igImagesEl = root.addElement("ig-images");
162 
163             JournalPortletDataHandlerImpl.exportArticle(
164                 context, root, dlFoldersEl, dlFilesEl, dlFileRanksEl,
165                 igFoldersEl, igImagesEl, article);
166 
167             String structureId = article.getStructureId();
168 
169             if (Validator.isNotNull(structureId)) {
170                 JournalStructure structure = JournalStructureUtil.findByG_S(
171                     article.getGroupId(), structureId);
172 
173                 JournalPortletDataHandlerImpl.exportStructure(
174                     context, root, structure);
175             }
176 
177             String templateId = article.getTemplateId();
178 
179             if (Validator.isNotNull(templateId)) {
180                 JournalTemplate template = JournalTemplateUtil.findByG_T(
181                     article.getGroupId(), templateId);
182 
183                 JournalPortletDataHandlerImpl.exportTemplate(
184                     context, root, dlFoldersEl, dlFilesEl, dlFileRanksEl,
185                     igFoldersEl, igImagesEl, template);
186             }
187 
188             return doc.formattedString();
189         }
190         catch (Exception e) {
191             throw new PortletDataException(e);
192         }
193     }
194 
195     public PortletDataHandlerControl[] getExportControls() {
196         return new PortletDataHandlerControl[] {
197             _selectedArticles, _embeddedAssets, _images, _comments, _ratings,
198             _tags
199         };
200     }
201 
202     public PortletDataHandlerControl[] getImportControls() {
203         return new PortletDataHandlerControl[] {
204             _selectedArticles, _images, _comments, _ratings, _tags
205         };
206     }
207 
208     public PortletPreferences importData(
209             PortletDataContext context, String portletId,
210             PortletPreferences preferences, String data)
211         throws PortletDataException {
212 
213         try {
214             if (Validator.isNull(data)) {
215                 return null;
216             }
217 
218             Document doc = SAXReaderUtil.read(data);
219 
220             Element root = doc.getRootElement();
221 
222             Element structureEl = root.element("structure");
223 
224             Map<String, String> structureIds =
225                 (Map<String, String>)context.getNewPrimaryKeysMap(
226                     JournalStructure.class);
227 
228             if (structureEl != null) {
229                 JournalPortletDataHandlerImpl.importStructure(
230                     context, structureIds, structureEl);
231             }
232 
233             Element templateEl = root.element("template");
234 
235             Map<String, String> templateIds =
236                 (Map<String, String>)context.getNewPrimaryKeysMap(
237                     JournalTemplate.class);
238 
239             if (templateEl != null) {
240                 JournalPortletDataHandlerImpl.importTemplate(
241                     context, structureIds, templateIds, templateEl);
242             }
243 
244             Element articleEl = root.element("article");
245 
246             Map<String, String> articleIds =
247                 (Map<String, String>)context.getNewPrimaryKeysMap(
248                     JournalArticle.class);
249 
250             if (articleEl != null) {
251                 JournalPortletDataHandlerImpl.importArticle(
252                     context, structureIds, templateIds, articleIds, articleEl);
253             }
254 
255             Element dlFoldersEl = root.element("dl-folders");
256 
257             List<Element> dlFolderEls = Collections.EMPTY_LIST;
258 
259             if (dlFoldersEl != null) {
260                 dlFolderEls = dlFoldersEl.elements("folder");
261             }
262 
263             Map<Long, Long> dlFolderPKs =
264                 (Map<Long, Long>)context.getNewPrimaryKeysMap(DLFolder.class);
265 
266             for (Element folderEl : dlFolderEls) {
267                 String path = folderEl.attributeValue("path");
268 
269                 if (!context.isPathNotProcessed(path)) {
270                     continue;
271                 }
272 
273                 DLFolder folder = (DLFolder)context.getZipEntryAsObject(path);
274 
275                 DLPortletDataHandlerImpl.importFolder(
276                     context, dlFolderPKs, folder);
277             }
278 
279             Element dlFileEntriesEl = root.element("dl-file-entries");
280 
281             List<Element> dlFileEntryEls = Collections.EMPTY_LIST;
282 
283             if (dlFileEntriesEl != null) {
284                 dlFileEntryEls = dlFileEntriesEl.elements("file-entry");
285             }
286 
287             Map<String, String> fileEntryNames =
288                 (Map<String, String>)context.getNewPrimaryKeysMap(
289                     DLFileEntry.class);
290 
291             for (Element fileEntryEl : dlFileEntryEls) {
292                 String path = fileEntryEl.attributeValue("path");
293 
294                 if (!context.isPathNotProcessed(path)) {
295                     continue;
296                 }
297 
298                 DLFileEntry fileEntry =
299                     (DLFileEntry)context.getZipEntryAsObject(path);
300 
301                 String binPath = fileEntryEl.attributeValue("bin-path");
302 
303                 DLPortletDataHandlerImpl.importFileEntry(
304                     context, dlFolderPKs, fileEntryNames, fileEntry, binPath);
305             }
306 
307             Element dlFileRanksEl = root.element("dl-file-ranks");
308 
309             List<Element> dlFileRankEls = Collections.EMPTY_LIST;
310 
311             if (dlFileRanksEl != null) {
312                 dlFileRankEls = dlFileRanksEl.elements("file-rank");
313             }
314 
315             for (Element fileRankEl : dlFileRankEls) {
316                 String path = fileRankEl.attributeValue("path");
317 
318                 if (!context.isPathNotProcessed(path)) {
319                     continue;
320                 }
321 
322                 DLFileRank fileRank =
323                     (DLFileRank)context.getZipEntryAsObject(path);
324 
325                 DLPortletDataHandlerImpl.importFileRank(
326                     context, dlFolderPKs, fileEntryNames, fileRank);
327             }
328 
329             Element igFoldersEl = root.element("ig-folders");
330 
331             List<Element> igFolderEls = Collections.EMPTY_LIST;
332 
333             if (igFoldersEl != null) {
334                 igFolderEls = igFoldersEl.elements("folder");
335             }
336 
337             Map<Long, Long> igFolderPKs =
338                 (Map<Long, Long>)context.getNewPrimaryKeysMap(IGFolder.class);
339 
340             for (Element folderEl : igFolderEls) {
341                 String path = folderEl.attributeValue("path");
342 
343                 if (!context.isPathNotProcessed(path)) {
344                     continue;
345                 }
346 
347                 IGFolder folder = (IGFolder)context.getZipEntryAsObject(path);
348 
349                 IGPortletDataHandlerImpl.importFolder(
350                     context, igFolderPKs, folder);
351             }
352 
353             Element igImagesEl = root.element("ig-images");
354 
355             List<Element> igImageEls = Collections.EMPTY_LIST;
356 
357             if (igImagesEl != null) {
358                 igImageEls = igImagesEl.elements("image");
359             }
360 
361             for (Element imageEl : igImageEls) {
362                 String path = imageEl.attributeValue("path");
363 
364                 if (!context.isPathNotProcessed(path)) {
365                     continue;
366                 }
367 
368                 IGImage image = (IGImage)context.getZipEntryAsObject(path);
369 
370                 String binPath = imageEl.attributeValue("bin-path");
371 
372                 IGPortletDataHandlerImpl.importImage(
373                     context, igFolderPKs, image, binPath);
374             }
375 
376             String articleId = preferences.getValue(
377                 "article-id", StringPool.BLANK);
378 
379             if (Validator.isNotNull(articleId)) {
380                 articleId = MapUtil.getString(articleIds, articleId, articleId);
381 
382                 preferences.setValue(
383                     "group-id", String.valueOf(context.getGroupId()));
384                 preferences.setValue("article-id", articleId);
385 
386                 Layout layout = LayoutLocalServiceUtil.getLayout(
387                     context.getPlid());
388 
389                 JournalContentSearchLocalServiceUtil.updateContentSearch(
390                     context.getGroupId(), layout.isPrivateLayout(),
391                     layout.getLayoutId(), portletId, articleId, true);
392             }
393 
394             return preferences;
395         }
396         catch (Exception e) {
397             throw new PortletDataException(e);
398         }
399     }
400 
401     public boolean isPublishToLiveByDefault() {
402         return  _PUBLISH_TO_LIVE_BY_DEFAULT;
403     }
404 
405     private static final boolean _PUBLISH_TO_LIVE_BY_DEFAULT = true;
406 
407     private static final String _NAMESPACE = "journal";
408 
409     private static final PortletDataHandlerBoolean _selectedArticles =
410         new PortletDataHandlerBoolean(
411             _NAMESPACE, "selected-web-content", true, true);
412 
413     private static final PortletDataHandlerBoolean _embeddedAssets =
414         new PortletDataHandlerBoolean(_NAMESPACE, "embedded-assets");
415 
416     private static final PortletDataHandlerBoolean _images =
417         new PortletDataHandlerBoolean(_NAMESPACE, "images");
418 
419     private static final PortletDataHandlerBoolean _comments =
420         new PortletDataHandlerBoolean(_NAMESPACE, "comments");
421 
422     private static final PortletDataHandlerBoolean _ratings =
423         new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
424 
425     private static final PortletDataHandlerBoolean _tags =
426         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
427 
428     private static Log _log = LogFactoryUtil.getLog(
429         JournalContentPortletDataHandlerImpl.class);
430 
431 }