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