1   /**
2    * Copyright (c) 2000-2010 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   *
12   *
13   */
14  
15  package com.liferay.portlet.messageboards.lar;
16  
17  import com.liferay.documentlibrary.service.DLServiceUtil;
18  import com.liferay.portal.PortalException;
19  import com.liferay.portal.SystemException;
20  import com.liferay.portal.kernel.log.Log;
21  import com.liferay.portal.kernel.log.LogFactoryUtil;
22  import com.liferay.portal.kernel.util.CharPool;
23  import com.liferay.portal.kernel.util.MapUtil;
24  import com.liferay.portal.kernel.util.ObjectValuePair;
25  import com.liferay.portal.kernel.util.StringBundler;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
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.lar.PortletDataHandlerKeys;
37  import com.liferay.portal.model.CompanyConstants;
38  import com.liferay.portal.model.User;
39  import com.liferay.portal.service.ServiceContext;
40  import com.liferay.portal.service.persistence.UserUtil;
41  import com.liferay.portal.util.PortletKeys;
42  import com.liferay.portlet.messageboards.NoSuchCategoryException;
43  import com.liferay.portlet.messageboards.NoSuchMessageException;
44  import com.liferay.portlet.messageboards.NoSuchThreadException;
45  import com.liferay.portlet.messageboards.model.MBBan;
46  import com.liferay.portlet.messageboards.model.MBCategory;
47  import com.liferay.portlet.messageboards.model.MBMessage;
48  import com.liferay.portlet.messageboards.model.MBMessageFlag;
49  import com.liferay.portlet.messageboards.model.MBThread;
50  import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
51  import com.liferay.portlet.messageboards.model.impl.MBMessageImpl;
52  import com.liferay.portlet.messageboards.service.MBBanLocalServiceUtil;
53  import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
54  import com.liferay.portlet.messageboards.service.MBMessageFlagLocalServiceUtil;
55  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
56  import com.liferay.portlet.messageboards.service.persistence.MBBanUtil;
57  import com.liferay.portlet.messageboards.service.persistence.MBCategoryUtil;
58  import com.liferay.portlet.messageboards.service.persistence.MBMessageFlagUtil;
59  import com.liferay.portlet.messageboards.service.persistence.MBMessageUtil;
60  import com.liferay.portlet.messageboards.service.persistence.MBThreadUtil;
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  /**
70   * <a href="MBPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
71   *
72   * @author Bruno Farache
73   * @author Raymond Augé
74   */
75  public class MBPortletDataHandlerImpl extends BasePortletDataHandler {
76  
77      public PortletPreferences deleteData(
78              PortletDataContext context, String portletId,
79              PortletPreferences preferences)
80          throws PortletDataException {
81  
82          try {
83              if (!context.addPrimaryKey(
84                      MBPortletDataHandlerImpl.class, "deleteData")) {
85  
86                  MBCategoryLocalServiceUtil.deleteCategories(
87                      context.getScopeGroupId());
88              }
89  
90              return null;
91          }
92          catch (Exception e) {
93              throw new PortletDataException(e);
94          }
95      }
96  
97      public String exportData(
98              PortletDataContext context, String portletId,
99              PortletPreferences preferences)
100         throws PortletDataException {
101 
102         try {
103             context.addPermissions(
104                 "com.liferay.portlet.messageboards", context.getScopeGroupId());
105 
106             Document doc = SAXReaderUtil.createDocument();
107 
108             Element root = doc.addElement("message-boards-data");
109 
110             root.addAttribute(
111                 "group-id", String.valueOf(context.getScopeGroupId()));
112 
113             Element categoriesEl = root.addElement("categories");
114             Element messagesEl = root.addElement("messages");
115             Element messageFlagsEl = root.addElement("message-flags");
116             Element userBansEl = root.addElement("user-bans");
117 
118             List<MBCategory> categories = MBCategoryUtil.findByGroupId(
119                 context.getScopeGroupId());
120 
121             for (MBCategory category : categories) {
122                 exportCategory(
123                     context, categoriesEl, messagesEl, messageFlagsEl,
124                     category);
125             }
126 
127             if (context.getBooleanParameter(_NAMESPACE, "user-bans")) {
128                 List<MBBan> bans = MBBanUtil.findByGroupId(
129                     context.getScopeGroupId());
130 
131                 for (MBBan ban : bans) {
132                     exportUserBan(context, userBansEl, ban);
133                 }
134             }
135 
136             return doc.formattedString();
137         }
138         catch (Exception e) {
139             throw new PortletDataException(e);
140         }
141     }
142 
143     public PortletDataHandlerControl[] getExportControls() {
144         return new PortletDataHandlerControl[] {
145             _categoriesAndMessages, _attachments, _userBans, _flags, _ratings,
146             _tags
147         };
148     }
149 
150     public PortletDataHandlerControl[] getImportControls() {
151         return new PortletDataHandlerControl[] {
152             _categoriesAndMessages, _attachments, _userBans, _flags, _ratings,
153             _tags
154         };
155     }
156 
157     public PortletPreferences importData(
158             PortletDataContext context, String portletId,
159             PortletPreferences preferences, String data)
160         throws PortletDataException {
161 
162         try {
163             context.importPermissions(
164                 "com.liferay.portlet.messageboards", context.getSourceGroupId(),
165                 context.getScopeGroupId());
166 
167             Document doc = SAXReaderUtil.read(data);
168 
169             Element root = doc.getRootElement();
170 
171             List<Element> categoryEls = root.element("categories").elements(
172                 "category");
173 
174             Map<Long, Long> categoryPKs =
175                 (Map<Long, Long>)context.getNewPrimaryKeysMap(MBCategory.class);
176 
177             for (Element categoryEl : categoryEls) {
178                 String path = categoryEl.attributeValue("path");
179 
180                 if (!context.isPathNotProcessed(path)) {
181                     continue;
182                 }
183 
184                 MBCategory category = (MBCategory)context.getZipEntryAsObject(
185                     path);
186 
187                 importCategory(context, categoryPKs, category);
188             }
189 
190             List<Element> messageEls = root.element("messages").elements(
191                 "message");
192 
193             Map<Long, Long> threadPKs =
194                 (Map<Long, Long>)context.getNewPrimaryKeysMap(MBThread.class);
195             Map<Long, Long> messagePKs =
196                 (Map<Long, Long>)context.getNewPrimaryKeysMap(MBMessage.class);
197 
198             for (Element messageEl : messageEls) {
199                 String path = messageEl.attributeValue("path");
200 
201                 if (!context.isPathNotProcessed(path)) {
202                     continue;
203                 }
204 
205                 MBMessage message = (MBMessage)context.getZipEntryAsObject(
206                     path);
207 
208                 importMessage(
209                     context, categoryPKs, threadPKs, messagePKs, messageEl,
210                     message);
211             }
212 
213             if (context.getBooleanParameter(_NAMESPACE, "flags")) {
214                 List<Element> flagEls = root.element("message-flags").elements(
215                     "flag");
216 
217                 for (Element flagEl : flagEls) {
218                     String path = flagEl.attributeValue("path");
219 
220                     if (!context.isPathNotProcessed(path)) {
221                         continue;
222                     }
223 
224                     MBMessageFlag flag =
225                         (MBMessageFlag)context.getZipEntryAsObject(path);
226 
227                     importFlag(context, messagePKs, flag);
228                 }
229             }
230 
231             if (context.getBooleanParameter(_NAMESPACE, "user-bans")) {
232                 List<Element> banEls = root.element("user-bans").elements(
233                     "user-ban");
234 
235                 for (Element banEl : banEls) {
236                     String path = banEl.attributeValue("path");
237 
238                     if (!context.isPathNotProcessed(path)) {
239                         continue;
240                     }
241 
242                     MBBan ban = (MBBan)context.getZipEntryAsObject(path);
243 
244                     importBan(context, ban);
245                 }
246             }
247 
248             return null;
249         }
250         catch (Exception e) {
251             throw new PortletDataException(e);
252         }
253     }
254 
255     protected void exportCategory(
256             PortletDataContext context, Element categoriesEl,
257             Element messagesEl, Element messageFlagsEl, MBCategory category)
258         throws PortalException, SystemException {
259 
260         if (context.isWithinDateRange(category.getModifiedDate())) {
261             exportParentCategory(
262                 context, categoriesEl, category.getParentCategoryId());
263 
264             String path = getCategoryPath(context, category);
265 
266             if (context.isPathNotProcessed(path)) {
267                 Element categoryEl = categoriesEl.addElement("category");
268 
269                 categoryEl.addAttribute("path", path);
270 
271                 category.setUserUuid(category.getUserUuid());
272 
273                 context.addPermissions(
274                     MBCategory.class, category.getCategoryId());
275 
276                 context.addZipEntry(path, category);
277             }
278         }
279 
280         List<MBMessage> messages = MBMessageUtil.findByCategoryId(
281             category.getCategoryId());
282 
283         for (MBMessage message : messages) {
284             exportMessage(
285                 context, categoriesEl, messagesEl, messageFlagsEl, message);
286         }
287     }
288 
289     protected void exportMessage(
290             PortletDataContext context, Element categoriesEl,
291             Element messagesEl, Element messageFlagsEl, MBMessage message)
292         throws PortalException, SystemException {
293 
294         if (!context.isWithinDateRange(message.getModifiedDate())) {
295             return;
296         }
297 
298         exportParentCategory(context, categoriesEl, message.getCategoryId());
299 
300         String path = getMessagePath(context, message);
301 
302         if (context.isPathNotProcessed(path)) {
303             Element messageEl = messagesEl.addElement("message");
304 
305             messageEl.addAttribute("path", path);
306 
307             message.setUserUuid(message.getUserUuid());
308             message.setPriority(message.getPriority());
309 
310             context.addPermissions(MBMessage.class, message.getMessageId());
311 
312             if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
313                 context.addRatingsEntries(
314                     MBMessage.class, message.getMessageId());
315             }
316 
317             if (context.getBooleanParameter(_NAMESPACE, "tags")) {
318                 context.addTagsEntries(
319                     MBMessage.class, message.getMessageId());
320             }
321 
322             if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
323                 message.isAttachments()) {
324 
325                 for (String attachment : message.getAttachmentsFiles()) {
326                     int pos = attachment.lastIndexOf(CharPool.FORWARD_SLASH);
327 
328                     String name = attachment.substring(pos + 1);
329                     String binPath = getMessageAttachementBinPath(
330                         context, message, name);
331 
332                     Element attachmentEl = messageEl.addElement("attachment");
333 
334                     attachmentEl.addAttribute("name", name);
335                     attachmentEl.addAttribute("bin-path", binPath);
336 
337                     byte[] bytes = DLServiceUtil.getFile(
338                         context.getCompanyId(), CompanyConstants.SYSTEM,
339                         attachment);
340 
341                     context.addZipEntry(binPath, bytes);
342                 }
343 
344                 message.setAttachmentsDir(message.getAttachmentsDir());
345             }
346 
347             if (context.getBooleanParameter(_NAMESPACE, "flags")) {
348                 List<MBMessageFlag> messageFlags =
349                     MBMessageFlagUtil.findByMessageId(
350                         message.getMessageId());
351 
352                 for (MBMessageFlag messageFlag : messageFlags) {
353                     exportMessageFlag(context, messageFlagsEl, messageFlag);
354                 }
355             }
356 
357             context.addZipEntry(path, message);
358         }
359     }
360 
361     protected void exportMessageFlag(
362             PortletDataContext context, Element messageFlagsEl,
363             MBMessageFlag messageFlag)
364         throws SystemException {
365 
366         String path = getMessageFlagPath(context, messageFlag);
367 
368         if (!context.isPathNotProcessed(path)) {
369             return;
370         }
371 
372         Element messageFlagEl = messageFlagsEl.addElement("message-flag");
373 
374         messageFlagEl.addAttribute("path", path);
375 
376         messageFlag.setUserUuid(messageFlag.getUserUuid());
377 
378         context.addZipEntry(path, messageFlag);
379     }
380 
381     protected void exportParentCategory(
382             PortletDataContext context, Element categoriesEl, long categoryId)
383         throws PortalException, SystemException {
384 
385         if ((!context.hasDateRange()) ||
386             (categoryId == MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID)) {
387 
388             return;
389         }
390 
391         MBCategory category = MBCategoryUtil.findByPrimaryKey(categoryId);
392 
393         exportParentCategory(
394             context, categoriesEl, category.getParentCategoryId());
395 
396         String path = getCategoryPath(context, category);
397 
398         if (context.isPathNotProcessed(path)) {
399             Element categoryEl = categoriesEl.addElement("category");
400 
401             categoryEl.addAttribute("path", path);
402 
403             category.setUserUuid(category.getUserUuid());
404 
405             context.addPermissions(MBCategory.class, category.getCategoryId());
406 
407             context.addZipEntry(path, category);
408         }
409     }
410 
411     protected void exportUserBan(
412             PortletDataContext context, Element userBansEl, MBBan ban)
413         throws SystemException {
414 
415         if (!context.isWithinDateRange(ban.getModifiedDate())) {
416             return;
417         }
418 
419         String path = getUserBanPath(context, ban);
420 
421         if (!context.isPathNotProcessed(path)) {
422             return;
423         }
424 
425         Element userBanEl = userBansEl.addElement("user-ban");
426 
427         userBanEl.addAttribute("path", path);
428 
429         ban.setBanUserUuid(ban.getBanUserUuid());
430         ban.setUserUuid(ban.getUserUuid());
431 
432         context.addZipEntry(path, ban);
433     }
434 
435     protected void importBan(PortletDataContext context, MBBan ban)
436         throws Exception {
437 
438         long userId = context.getUserId(ban.getUserUuid());
439 
440         ServiceContext serviceContext = new ServiceContext();
441 
442         serviceContext.setScopeGroupId(context.getScopeGroupId());
443 
444         List<User> users = UserUtil.findByUuid(ban.getBanUserUuid());
445 
446         Iterator<User> itr = users.iterator();
447 
448         if (itr.hasNext()) {
449             User user = itr.next();
450 
451             MBBanLocalServiceUtil.addBan(
452                 userId, user.getUserId(), serviceContext);
453         }
454         else {
455             _log.error(
456                 "Could not find banned user with uuid " + ban.getBanUserUuid());
457         }
458     }
459 
460     protected void importCategory(
461             PortletDataContext context, Map<Long, Long> categoryPKs,
462             MBCategory category)
463         throws Exception {
464 
465         long userId = context.getUserId(category.getUserUuid());
466         long parentCategoryId = MapUtil.getLong(
467             categoryPKs, category.getParentCategoryId(),
468             category.getParentCategoryId());
469 
470         String emailAddress = null;
471         String inProtocol = null;
472         String inServerName = null;
473         int inServerPort = 0;
474         boolean inUseSSL = false;
475         String inUserName = null;
476         String inPassword = null;
477         int inReadInterval = 0;
478         String outEmailAddress = null;
479         boolean outCustom = false;
480         String outServerName = null;
481         int outServerPort = 0;
482         boolean outUseSSL = false;
483         String outUserName = null;
484         String outPassword = null;
485         boolean mailingListActive = false;
486 
487         ServiceContext serviceContext = new ServiceContext();
488 
489         serviceContext.setAddCommunityPermissions(true);
490         serviceContext.setAddGuestPermissions(true);
491         serviceContext.setScopeGroupId(context.getScopeGroupId());
492 
493         if ((parentCategoryId != MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) &&
494             (parentCategoryId == category.getParentCategoryId())) {
495 
496             String path = getImportCategoryPath(context, parentCategoryId);
497 
498             MBCategory parentCategory =
499                 (MBCategory)context.getZipEntryAsObject(path);
500 
501             importCategory(context, categoryPKs, parentCategory);
502 
503             parentCategoryId = MapUtil.getLong(
504                 categoryPKs, category.getParentCategoryId(),
505                 category.getParentCategoryId());
506         }
507 
508         MBCategory existingCategory = null;
509 
510         try {
511             if (parentCategoryId != MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) {
512                 MBCategoryUtil.findByPrimaryKey(parentCategoryId);
513             }
514 
515             if (context.getDataStrategy().equals(
516                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
517 
518                 existingCategory = MBCategoryUtil.fetchByUUID_G(
519                     category.getUuid(), context.getScopeGroupId());
520 
521                 if (existingCategory == null) {
522                     existingCategory = MBCategoryLocalServiceUtil.addCategory(
523                         category.getUuid(), userId, parentCategoryId,
524                         category.getName(), category.getDescription(),
525                         emailAddress, inProtocol, inServerName, inServerPort,
526                         inUseSSL, inUserName, inPassword, inReadInterval,
527                         outEmailAddress, outCustom, outServerName,
528                         outServerPort, outUseSSL, outUserName, outPassword,
529                         mailingListActive, serviceContext);
530                 }
531                 else {
532                     existingCategory =
533                         MBCategoryLocalServiceUtil.updateCategory(
534                             existingCategory.getCategoryId(), parentCategoryId,
535                             category.getName(), category.getDescription(),
536                             emailAddress, inProtocol, inServerName,
537                             inServerPort, inUseSSL, inUserName, inPassword,
538                             inReadInterval, outEmailAddress, outCustom,
539                             outServerName, outServerPort, outUseSSL,
540                             outUserName, outPassword, mailingListActive, false);
541                 }
542             }
543             else {
544                 existingCategory = MBCategoryLocalServiceUtil.addCategory(
545                     userId, parentCategoryId, category.getName(),
546                     category.getDescription(), emailAddress, inProtocol,
547                     inServerName, inServerPort, inUseSSL, inUserName,
548                     inPassword, inReadInterval, outEmailAddress, outCustom,
549                     outServerName, outServerPort, outUseSSL, outUserName,
550                     outPassword, mailingListActive, serviceContext);
551             }
552 
553             categoryPKs.put(
554                 category.getCategoryId(), existingCategory.getCategoryId());
555 
556             context.importPermissions(
557                 MBCategory.class, category.getCategoryId(),
558                 existingCategory.getCategoryId());
559         }
560         catch (NoSuchCategoryException nsce) {
561             _log.error(
562                 "Could not find the parent category for category " +
563                     category.getCategoryId());
564         }
565     }
566 
567     protected void importFlag(
568             PortletDataContext context, Map<Long, Long> messagePKs,
569             MBMessageFlag flag)
570         throws Exception {
571 
572         long userId = context.getUserId(flag.getUserUuid());
573         long messageId = MapUtil.getLong(
574             messagePKs, flag.getMessageId(), flag.getMessageId());
575 
576         try {
577             MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
578 
579             MBThread thread = message.getThread();
580 
581             MBMessageFlagLocalServiceUtil.addReadFlags(userId, thread);
582         }
583         catch (NoSuchMessageException nsme) {
584             _log.error(
585                 "Could not find the message for flag " +
586                     flag.getMessageFlagId());
587         }
588     }
589 
590     protected void importMessage(
591             PortletDataContext context, Map<Long, Long> categoryPKs,
592             Map<Long, Long> threadPKs, Map<Long, Long> messagePKs,
593             Element messageEl, MBMessage message)
594         throws Exception {
595 
596         long userId = context.getUserId(message.getUserUuid());
597         String userName = message.getUserName();
598         long categoryId = MapUtil.getLong(
599             categoryPKs, message.getCategoryId(), message.getCategoryId());
600         long threadId = MapUtil.getLong(
601             threadPKs, message.getThreadId(), message.getThreadId());
602         long parentMessageId = MapUtil.getLong(
603             messagePKs, message.getParentMessageId(),
604             message.getParentMessageId());
605 
606         List<ObjectValuePair<String, byte[]>> files =
607             new ArrayList<ObjectValuePair<String, byte[]>>();
608         List<String> existingFiles = new ArrayList<String>();
609 
610         if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
611             message.isAttachments()) {
612 
613             List<Element> attachmentEls = messageEl.elements("attachment");
614 
615             for (Element attachmentEl : attachmentEls) {
616                 String name = attachmentEl.attributeValue("name");
617                 String binPath = attachmentEl.attributeValue("bin-path");
618 
619                 byte[] bytes = context.getZipEntryAsByteArray(binPath);
620 
621                 files.add(new ObjectValuePair<String, byte[]>(name, bytes));
622             }
623 
624             if (files.size() <= 0) {
625                 _log.error(
626                     "Could not find attachments for message " +
627                         message.getMessageId());
628             }
629         }
630 
631         String[] tagsEntries = null;
632 
633         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
634             tagsEntries = context.getTagsEntries(
635                 MBMessage.class, message.getMessageId());
636         }
637 
638         ServiceContext serviceContext = new ServiceContext();
639 
640         serviceContext.setAddCommunityPermissions(true);
641         serviceContext.setAddGuestPermissions(true);
642         serviceContext.setScopeGroupId(context.getScopeGroupId());
643         serviceContext.setTagsEntries(tagsEntries);
644 
645         if ((categoryId != MBCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) &&
646             (categoryId == message.getCategoryId())) {
647 
648             String path = getImportCategoryPath(context, categoryId);
649 
650             MBCategory category = (MBCategory)context.getZipEntryAsObject(path);
651 
652             importCategory(context, categoryPKs, category);
653 
654             categoryId = MapUtil.getLong(
655                 categoryPKs, message.getCategoryId(), message.getCategoryId());
656         }
657 
658         MBMessage existingMessage = null;
659 
660         try {
661             MBCategoryUtil.findByPrimaryKey(categoryId);
662 
663             if (parentMessageId != MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID) {
664                 MBMessageUtil.findByPrimaryKey(parentMessageId);
665                 MBThreadUtil.findByPrimaryKey(threadId);
666             }
667 
668             if (context.getDataStrategy().equals(
669                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
670 
671                 try {
672                     existingMessage = MBMessageUtil.findByUUID_G(
673                         message.getUuid(), context.getScopeGroupId());
674 
675                     existingMessage = MBMessageLocalServiceUtil.updateMessage(
676                         userId, existingMessage.getMessageId(),
677                         message.getSubject(), message.getBody(), files,
678                         existingFiles, message.getPriority(), serviceContext);
679                 }
680                 catch (NoSuchMessageException nsme) {
681                     existingMessage = MBMessageLocalServiceUtil.addMessage(
682                         message.getUuid(), userId, userName, categoryId,
683                         threadId, parentMessageId, message.getSubject(),
684                         message.getBody(), files, message.getAnonymous(),
685                         message.getPriority(), serviceContext);
686                 }
687             }
688             else {
689                 existingMessage = MBMessageLocalServiceUtil.addMessage(
690                     userId, userName, categoryId, threadId, parentMessageId,
691                     message.getSubject(), message.getBody(), files,
692                     message.getAnonymous(), message.getPriority(),
693                     serviceContext);
694             }
695 
696             threadPKs.put(message.getThreadId(), existingMessage.getThreadId());
697             messagePKs.put(
698                 message.getMessageId(), existingMessage.getMessageId());
699 
700             context.importPermissions(
701                 MBMessage.class, message.getMessageId(),
702                 existingMessage.getMessageId());
703 
704             if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
705                 context.importRatingsEntries(
706                     MBMessage.class, message.getMessageId(),
707                     existingMessage.getMessageId());
708             }
709         }
710         catch (NoSuchCategoryException nsce) {
711             _log.error(
712                 "Could not find the parent category for message " +
713                     message.getMessageId());
714         }
715         catch (NoSuchMessageException nsme) {
716             _log.error(
717                 "Could not find the parent message for message " +
718                     message.getMessageId());
719         }
720         catch (NoSuchThreadException nste) {
721             _log.error(
722                 "Could not find the thread for message " +
723                     message.getMessageId());
724         }
725     }
726 
727     protected String getCategoryPath(
728         PortletDataContext context, MBCategory category) {
729 
730         StringBundler sb = new StringBundler(4);
731 
732         sb.append(context.getPortletPath(PortletKeys.MESSAGE_BOARDS));
733         sb.append("/categories/");
734         sb.append(category.getCategoryId());
735         sb.append(".xml");
736 
737         return sb.toString();
738     }
739 
740     protected String getImportCategoryPath(
741         PortletDataContext context, long categoryId) {
742 
743         StringBundler sb = new StringBundler(4);
744 
745         sb.append(context.getSourcePortletPath(PortletKeys.MESSAGE_BOARDS));
746         sb.append("/categories/");
747         sb.append(categoryId);
748         sb.append(".xml");
749 
750         return sb.toString();
751     }
752 
753     protected String getMessageAttachementBinPath(
754         PortletDataContext context, MBMessage message, String attachment) {
755 
756         StringBundler sb = new StringBundler(5);
757 
758         sb.append(context.getPortletPath(PortletKeys.MESSAGE_BOARDS));
759         sb.append("/bin/");
760         sb.append(message.getMessageId());
761         sb.append(StringPool.SLASH);
762         sb.append(PortalUUIDUtil.generate());
763 
764         return sb.toString();
765     }
766 
767     protected String getMessageFlagPath(
768         PortletDataContext context, MBMessageFlag messageFlag) {
769 
770         StringBundler sb = new StringBundler(4);
771 
772         sb.append(context.getPortletPath(PortletKeys.MESSAGE_BOARDS));
773         sb.append("/message-flags/");
774         sb.append(messageFlag.getMessageFlagId());
775         sb.append(".xml");
776 
777         return sb.toString();
778     }
779 
780     protected String getMessagePath(
781         PortletDataContext context, MBMessage message) {
782 
783         StringBundler sb = new StringBundler(4);
784 
785         sb.append(context.getPortletPath(PortletKeys.MESSAGE_BOARDS));
786         sb.append("/messages/");
787         sb.append(message.getMessageId());
788         sb.append(".xml");
789 
790         return sb.toString();
791     }
792 
793     protected String getUserBanPath(PortletDataContext context, MBBan ban) {
794         StringBundler sb = new StringBundler(4);
795 
796         sb.append(context.getPortletPath(PortletKeys.MESSAGE_BOARDS));
797         sb.append("/user-bans/");
798         sb.append(ban.getBanId());
799         sb.append(".xml");
800 
801         return sb.toString();
802     }
803 
804     private static final String _NAMESPACE = "message_board";
805 
806     private static final PortletDataHandlerBoolean _categoriesAndMessages =
807         new PortletDataHandlerBoolean(
808             _NAMESPACE, "categories-and-messages", true, true);
809 
810     private static final PortletDataHandlerBoolean _attachments =
811         new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
812 
813     private static final PortletDataHandlerBoolean _userBans =
814         new PortletDataHandlerBoolean(_NAMESPACE, "user-bans");
815 
816     private static final PortletDataHandlerBoolean _flags =
817         new PortletDataHandlerBoolean(_NAMESPACE, "flags");
818 
819     private static final PortletDataHandlerBoolean _ratings =
820         new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
821 
822     private static final PortletDataHandlerBoolean _tags =
823         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
824 
825     private static Log _log = LogFactoryUtil.getLog(
826         MBPortletDataHandlerImpl.class);
827 
828 }