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