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