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