1   /**
2    * Copyright (c) 2000-2008 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.messageboards.lar;
24  
25  import com.liferay.documentlibrary.service.DLServiceUtil;
26  import com.liferay.portal.kernel.lar.PortletDataContext;
27  import com.liferay.portal.kernel.lar.PortletDataException;
28  import com.liferay.portal.kernel.lar.PortletDataHandler;
29  import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
30  import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
31  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
32  import com.liferay.portal.model.CompanyConstants;
33  import com.liferay.portal.model.User;
34  import com.liferay.portal.service.persistence.UserUtil;
35  import com.liferay.portal.theme.ThemeDisplay;
36  import com.liferay.portal.util.DocumentUtil;
37  import com.liferay.portlet.messageboards.NoSuchCategoryException;
38  import com.liferay.portlet.messageboards.NoSuchMessageException;
39  import com.liferay.portlet.messageboards.NoSuchThreadException;
40  import com.liferay.portlet.messageboards.model.MBBan;
41  import com.liferay.portlet.messageboards.model.MBCategory;
42  import com.liferay.portlet.messageboards.model.MBMessage;
43  import com.liferay.portlet.messageboards.model.MBMessageFlag;
44  import com.liferay.portlet.messageboards.model.MBThread;
45  import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
46  import com.liferay.portlet.messageboards.model.impl.MBMessageImpl;
47  import com.liferay.portlet.messageboards.service.MBBanLocalServiceUtil;
48  import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
49  import com.liferay.portlet.messageboards.service.MBMessageFlagLocalServiceUtil;
50  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
51  import com.liferay.portlet.messageboards.service.persistence.MBBanUtil;
52  import com.liferay.portlet.messageboards.service.persistence.MBCategoryUtil;
53  import com.liferay.portlet.messageboards.service.persistence.MBMessageFinderUtil;
54  import com.liferay.portlet.messageboards.service.persistence.MBMessageFlagUtil;
55  import com.liferay.portlet.messageboards.service.persistence.MBMessageUtil;
56  import com.liferay.portlet.messageboards.service.persistence.MBThreadUtil;
57  import com.liferay.util.MapUtil;
58  
59  import com.thoughtworks.xstream.XStream;
60  
61  import java.util.ArrayList;
62  import java.util.Iterator;
63  import java.util.List;
64  import java.util.Map;
65  
66  import javax.portlet.PortletPreferences;
67  
68  import org.apache.commons.logging.Log;
69  import org.apache.commons.logging.LogFactory;
70  
71  import org.dom4j.Document;
72  import org.dom4j.DocumentHelper;
73  import org.dom4j.Element;
74  
75  /**
76   * <a href="MBPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
77   *
78   * @author Bruno Farache
79   *
80   */
81  public class MBPortletDataHandlerImpl implements PortletDataHandler {
82  
83      public PortletPreferences deleteData(
84              PortletDataContext context, String portletId,
85              PortletPreferences prefs)
86          throws PortletDataException {
87  
88          try {
89  
90              // Categories
91  
92              if (!context.addPrimaryKey(
93                      MBPortletDataHandlerImpl.class, "deleteData")) {
94  
95                  MBCategoryLocalServiceUtil.deleteCategories(
96                      context.getGroupId());
97              }
98  
99              return null;
100         }
101         catch (Exception e) {
102             throw new PortletDataException(e);
103         }
104     }
105 
106     public String exportData(
107             PortletDataContext context, String portletId,
108             PortletPreferences prefs)
109         throws PortletDataException {
110 
111         try {
112             XStream xStream = new XStream();
113 
114             Document doc = DocumentHelper.createDocument();
115 
116             Element root = doc.addElement("message-boards-data");
117 
118             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
119 
120             // Categories
121 
122             List categories = MBCategoryUtil.findByGroupId(
123                 context.getGroupId());
124 
125             List messages = new ArrayList();
126 
127             Iterator itr = categories.iterator();
128 
129             while (itr.hasNext()) {
130                 MBCategory category = (MBCategory)itr.next();
131 
132                 if (context.addPrimaryKey(
133                         MBCategory.class, category.getPrimaryKeyObj())) {
134 
135                     itr.remove();
136                 }
137                 else {
138                     category.setUserUuid(category.getUserUuid());
139 
140                     List categoryMessages = MBMessageUtil.findByCategoryId(
141                         category.getCategoryId());
142 
143                     messages.addAll(categoryMessages);
144                 }
145             }
146 
147             String xml = xStream.toXML(categories);
148 
149             Element el = root.addElement("message-board-categories");
150 
151             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
152 
153             el.content().add(tempDoc.getRootElement().createCopy());
154 
155             // Messages
156 
157             List flags = new ArrayList();
158 
159             itr = messages.iterator();
160 
161             while (itr.hasNext()) {
162                 MBMessage message = (MBMessage)itr.next();
163 
164                 if (context.addPrimaryKey(
165                         MBMessage.class, message.getPrimaryKeyObj())) {
166 
167                     itr.remove();
168                 }
169                 else {
170                     message.setUserUuid(message.getUserUuid());
171                     message.setPriority(message.getPriority());
172 
173                     if (context.getBooleanParameter(_NAMESPACE, "tags")) {
174                         context.addTagsEntries(
175                             MBMessage.class, message.getPrimaryKeyObj());
176                     }
177 
178                     // Attachments
179 
180                     if (context.getBooleanParameter(
181                             _NAMESPACE, "attachments") &&
182                         message.isAttachments()) {
183 
184                         String[] attachments = message.getAttachmentsFiles();
185 
186                         for (int i = 0; i < attachments.length; i++) {
187                             String attachment = attachments[i];
188 
189                             byte[] byteArray = DLServiceUtil.getFile(
190                                 context.getCompanyId(), CompanyConstants.SYSTEM,
191                                 attachment);
192 
193                             context.getZipWriter().addEntry(
194                                 attachment, byteArray);
195                         }
196 
197                         message.setAttachmentsDir(message.getAttachmentsDir());
198                     }
199 
200                     if (context.getBooleanParameter(_NAMESPACE, "flags")) {
201                         List messageFlags = MBMessageFlagUtil.findByMessageId(
202                             message.getMessageId());
203 
204                         flags.addAll(messageFlags);
205                     }
206                 }
207             }
208 
209             xml = xStream.toXML(messages);
210 
211             el = root.addElement("message-board-messages");
212 
213             tempDoc = DocumentUtil.readDocumentFromXML(xml);
214 
215             el.content().add(tempDoc.getRootElement().createCopy());
216 
217             // Flags
218 
219             itr = flags.iterator();
220 
221             while (itr.hasNext()) {
222                 MBMessageFlag flag = (MBMessageFlag)itr.next();
223 
224                 if (context.addPrimaryKey(
225                         MBMessageFlag.class, flag.getPrimaryKeyObj())) {
226 
227                     itr.remove();
228                 }
229                 else {
230                     flag.setUserUuid(flag.getUserUuid());
231                 }
232             }
233 
234             xml = xStream.toXML(flags);
235 
236             el = root.addElement("message-board-flags");
237 
238             tempDoc = DocumentUtil.readDocumentFromXML(xml);
239 
240             el.content().add(tempDoc.getRootElement().createCopy());
241 
242             // Bans
243 
244             List bans = new ArrayList();
245 
246             if (context.getBooleanParameter(_NAMESPACE, "user-bans")) {
247                 bans = MBBanUtil.findByGroupId(context.getGroupId());
248 
249                 itr = bans.iterator();
250 
251                 while (itr.hasNext()) {
252                     MBBan ban = (MBBan)itr.next();
253 
254                     if (context.addPrimaryKey(
255                             MBBan.class, ban.getPrimaryKeyObj())) {
256 
257                         itr.remove();
258                     }
259                     else {
260                         ban.setBanUserUuid(ban.getBanUserUuid());
261 
262                         ban.setUserUuid(ban.getUserUuid());
263                     }
264                 }
265             }
266 
267             xml = xStream.toXML(bans);
268 
269             el = root.addElement("message-board-bans");
270 
271             tempDoc = DocumentUtil.readDocumentFromXML(xml);
272 
273             el.content().add(tempDoc.getRootElement().createCopy());
274 
275             return doc.asXML();
276         }
277         catch (Exception e) {
278             throw new PortletDataException(e);
279         }
280     }
281 
282     public PortletDataHandlerControl[] getExportControls()
283         throws PortletDataException {
284 
285         return new PortletDataHandlerControl[] {
286             _categoriesAndMessages, _attachments, _userBans, _flags, _tags
287         };
288     }
289 
290     public PortletDataHandlerControl[] getImportControls()
291         throws PortletDataException {
292 
293         return new PortletDataHandlerControl[] {
294             _categoriesAndMessages, _attachments, _userBans, _flags, _tags
295         };
296     }
297 
298     public PortletPreferences importData(
299             PortletDataContext context, String portletId,
300             PortletPreferences prefs, String data)
301         throws PortletDataException {
302 
303         try {
304             XStream xStream = new XStream();
305 
306             Document doc = DocumentUtil.readDocumentFromXML(data);
307 
308             Element root = doc.getRootElement();
309 
310             // Categories
311 
312             Element el = root.element(
313                 "message-board-categories").element("list");
314 
315             Document tempDoc = DocumentHelper.createDocument();
316 
317             tempDoc.content().add(el.createCopy());
318 
319             Map categoryPKs = context.getNewPrimaryKeysMap(MBCategory.class);
320 
321             List categories = (List)xStream.fromXML(tempDoc.asXML());
322 
323             Iterator itr = categories.iterator();
324 
325             while (itr.hasNext()) {
326                 MBCategory category = (MBCategory)itr.next();
327 
328                 importCategory(context, categoryPKs, category);
329             }
330 
331             // Messages
332 
333             el = root.element("message-board-messages").element("list");
334 
335             tempDoc = DocumentHelper.createDocument();
336 
337             tempDoc.content().add(el.createCopy());
338 
339             Map threadPKs = context.getNewPrimaryKeysMap(MBThread.class);
340             Map messagePKs = context.getNewPrimaryKeysMap(MBMessage.class);
341 
342             List messages = (List)xStream.fromXML(tempDoc.asXML());
343 
344             itr = messages.iterator();
345 
346             while (itr.hasNext()) {
347                 MBMessage message = (MBMessage)itr.next();
348 
349                 importMessage(
350                     context, categoryPKs, threadPKs, messagePKs, message);
351             }
352 
353             // Flags
354 
355             if (context.getBooleanParameter(_NAMESPACE, "flags")) {
356                 el = root.element("message-board-flags").element("list");
357 
358                 tempDoc = DocumentHelper.createDocument();
359 
360                 tempDoc.content().add(el.createCopy());
361 
362                 List flags = (List)xStream.fromXML(tempDoc.asXML());
363 
364                 itr = flags.iterator();
365 
366                 while (itr.hasNext()) {
367                     MBMessageFlag flag = (MBMessageFlag)itr.next();
368 
369                     importFlag(context, messagePKs, flag);
370                 }
371             }
372 
373             // Bans
374 
375             if (context.getBooleanParameter(_NAMESPACE, "user-bans")) {
376                 el = root.element("message-board-bans").element("list");
377 
378                 tempDoc = DocumentHelper.createDocument();
379 
380                 tempDoc.content().add(el.createCopy());
381 
382                 List bans = (List)xStream.fromXML(tempDoc.asXML());
383 
384                 itr = bans.iterator();
385 
386                 while (itr.hasNext()) {
387                     MBBan ban = (MBBan)itr.next();
388 
389                     importBan(context, ban);
390                 }
391             }
392 
393             return null;
394         }
395         catch (Exception e) {
396             throw new PortletDataException(e);
397         }
398     }
399 
400     public boolean isPublishToLiveByDefault() {
401         return false;
402     }
403 
404     protected void importBan(PortletDataContext context, MBBan ban)
405         throws Exception {
406 
407         long userId = context.getUserId(ban.getUserUuid());
408         long plid = context.getPlid();
409 
410         List users = UserUtil.findByUuid(ban.getBanUserUuid());
411 
412         Iterator itr = users.iterator();
413 
414         if (itr.hasNext()) {
415             User user = (User)itr.next();
416 
417             MBBanLocalServiceUtil.addBan(userId, plid, user.getUserId());
418         }
419         else {
420             _log.error(
421                 "Could not find banned user with uuid " + ban.getBanUserUuid());
422         }
423     }
424 
425     protected void importCategory(
426             PortletDataContext context, Map categoryPKs, MBCategory category)
427         throws Exception {
428 
429         long userId = context.getUserId(category.getUserUuid());
430         long plid = context.getPlid();
431         long parentCategoryId = MapUtil.getLong(
432             categoryPKs, category.getParentCategoryId(),
433             category.getParentCategoryId());
434 
435         boolean addCommunityPermissions = true;
436         boolean addGuestPermissions = true;
437 
438         MBCategory existingCategory = null;
439 
440         try {
441             if (parentCategoryId != MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) {
442                 MBCategoryUtil.findByPrimaryKey(parentCategoryId);
443             }
444 
445             if (context.getDataStrategy().equals(
446                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
447 
448                 existingCategory = MBCategoryUtil.fetchByUUID_G(
449                     category.getUuid(), context.getGroupId());
450 
451                 if (existingCategory == null) {
452                     existingCategory = MBCategoryLocalServiceUtil.addCategory(
453                         category.getUuid(), userId, plid, parentCategoryId,
454                         category.getName(), category.getDescription(),
455                         addCommunityPermissions, addGuestPermissions);
456                 }
457                 else {
458                     existingCategory =
459                         MBCategoryLocalServiceUtil.updateCategory(
460                             existingCategory.getCategoryId(), parentCategoryId,
461                             category.getName(), category.getDescription(),
462                             false);
463                 }
464             }
465             else {
466                 existingCategory = MBCategoryLocalServiceUtil.addCategory(
467                     userId, plid, parentCategoryId, category.getName(),
468                     category.getDescription(), addCommunityPermissions,
469                     addGuestPermissions);
470             }
471 
472             categoryPKs.put(
473                 category.getPrimaryKeyObj(),
474                 existingCategory.getPrimaryKeyObj());
475         }
476         catch (NoSuchCategoryException nsce) {
477             _log.error(
478                 "Could not find the parent category for category " +
479                     category.getCategoryId());
480         }
481     }
482 
483     protected void importFlag(
484             PortletDataContext context, Map messagePKs, MBMessageFlag flag)
485         throws Exception {
486 
487         long userId = context.getUserId(flag.getUserUuid());
488         long messageId = MapUtil.getLong(
489             messagePKs, flag.getMessageId(), flag.getMessageId());
490 
491         try {
492             List messages = new ArrayList();
493 
494             messages.add(MBMessageUtil.findByPrimaryKey(messageId));
495 
496             MBMessageFlagLocalServiceUtil.addReadFlags(userId, messages);
497         }
498         catch (NoSuchMessageException nsme) {
499             _log.error(
500                 "Could not find the message for flag " +
501                     flag.getMessageFlagId());
502         }
503     }
504 
505     protected void importMessage(
506             PortletDataContext context, Map categoryPKs, Map threadPKs,
507             Map messagePKs, MBMessage message)
508         throws Exception {
509 
510         long userId = context.getUserId(message.getUserUuid());
511         long categoryId = MapUtil.getLong(
512             categoryPKs, message.getCategoryId(), message.getCategoryId());
513         long threadId = MapUtil.getLong(
514             threadPKs, message.getThreadId(), message.getThreadId());
515         long parentMessageId = MapUtil.getLong(
516             messagePKs, message.getParentMessageId(),
517             message.getParentMessageId());
518 
519         List files = new ArrayList();
520         List existingFiles = new ArrayList();
521 
522         if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
523             message.isAttachments()) {
524 
525             files = context.getZipReader().getFolderEntries().get(
526                 message.getAttachmentsDir() + "/");
527 
528             if (files == null) {
529                 _log.error(
530                     "Could not find attachments for message " +
531                         message.getMessageId());
532 
533                 files = new ArrayList();
534             }
535         }
536 
537         String[] tagsEntries = null;
538 
539         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
540             tagsEntries = context.getTagsEntries(
541                 MBMessage.class, message.getPrimaryKeyObj());
542         }
543 
544         PortletPreferences prefs = null;
545 
546         boolean addCommunityPermissions = true;
547         boolean addGuestPermissions = true;
548 
549         ThemeDisplay themeDisplay = null;
550 
551         MBMessage existingMessage = null;
552 
553         try {
554             MBCategoryUtil.findByPrimaryKey(categoryId);
555 
556             if (parentMessageId != MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID) {
557                 MBMessageUtil.findByPrimaryKey(parentMessageId);
558                 MBThreadUtil.findByPrimaryKey(threadId);
559             }
560 
561             if (context.getDataStrategy().equals(
562                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
563 
564                 try {
565                     existingMessage = MBMessageFinderUtil.findByUuid_G(
566                         message.getUuid(), context.getGroupId());
567 
568                     MBMessageLocalServiceUtil.updateMessage(
569                         userId, existingMessage.getMessageId(),
570                         message.getSubject(), message.getBody(), files,
571                         existingFiles, message.getPriority(), tagsEntries,
572                         prefs, themeDisplay);
573                 }
574                 catch (NoSuchMessageException nsme) {
575                     existingMessage = MBMessageLocalServiceUtil.addMessage(
576                         message.getUuid(), userId, categoryId, threadId,
577                         parentMessageId, message.getSubject(),
578                         message.getBody(), files, message.getAnonymous(),
579                         message.getPriority(), tagsEntries, prefs,
580                         addCommunityPermissions, addGuestPermissions,
581                         themeDisplay);
582                 }
583             }
584             else {
585                 existingMessage = MBMessageLocalServiceUtil.addMessage(
586                     userId, categoryId, threadId, parentMessageId,
587                     message.getSubject(), message.getBody(), files,
588                     message.getAnonymous(), message.getPriority(), tagsEntries,
589                     prefs, addCommunityPermissions, addGuestPermissions,
590                     themeDisplay);
591             }
592 
593             threadPKs.put(
594                 new Long(message.getThreadId()),
595                 new Long(existingMessage.getThreadId()));
596             messagePKs.put(
597                 message.getPrimaryKeyObj(), existingMessage.getPrimaryKeyObj());
598         }
599         catch (NoSuchCategoryException nsce) {
600             _log.error(
601                 "Could not find the parent category for message " +
602                     message.getMessageId());
603         }
604         catch (NoSuchMessageException nsme) {
605             _log.error(
606                 "Could not find the parent message for message " +
607                     message.getMessageId());
608         }
609         catch (NoSuchThreadException nste) {
610             _log.error(
611                 "Could not find the thread for message " +
612                     message.getMessageId());
613         }
614     }
615 
616     private static final String _NAMESPACE = "message_board";
617 
618     private static final PortletDataHandlerBoolean _categoriesAndMessages =
619         new PortletDataHandlerBoolean(
620             _NAMESPACE, "categories-and-messages", true, true);
621 
622     private static final PortletDataHandlerBoolean _attachments =
623         new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
624 
625     private static final PortletDataHandlerBoolean _userBans =
626         new PortletDataHandlerBoolean(_NAMESPACE, "user-bans");
627 
628     private static final PortletDataHandlerBoolean _flags =
629         new PortletDataHandlerBoolean(_NAMESPACE, "flags");
630 
631     private static final PortletDataHandlerBoolean _tags =
632         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
633 
634     private static Log _log =
635         LogFactory.getLog(MBPortletDataHandlerImpl.class);
636 
637 }