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