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