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