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