001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.messageboards.lar;
016    
017    import com.liferay.portal.kernel.lar.BasePortletDataHandler;
018    import com.liferay.portal.kernel.lar.PortletDataContext;
019    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
020    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.CharPool;
024    import com.liferay.portal.kernel.util.MapUtil;
025    import com.liferay.portal.kernel.util.ObjectValuePair;
026    import com.liferay.portal.kernel.util.StreamUtil;
027    import com.liferay.portal.kernel.util.StringBundler;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
030    import com.liferay.portal.kernel.workflow.WorkflowConstants;
031    import com.liferay.portal.kernel.xml.Document;
032    import com.liferay.portal.kernel.xml.Element;
033    import com.liferay.portal.kernel.xml.SAXReaderUtil;
034    import com.liferay.portal.model.CompanyConstants;
035    import com.liferay.portal.model.User;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portal.service.persistence.UserUtil;
038    import com.liferay.portal.util.PortletKeys;
039    import com.liferay.portal.util.PropsValues;
040    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
041    import com.liferay.portlet.messageboards.model.MBBan;
042    import com.liferay.portlet.messageboards.model.MBCategory;
043    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
044    import com.liferay.portlet.messageboards.model.MBMessage;
045    import com.liferay.portlet.messageboards.model.MBThread;
046    import com.liferay.portlet.messageboards.model.MBThreadFlag;
047    import com.liferay.portlet.messageboards.service.MBBanLocalServiceUtil;
048    import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
049    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
050    import com.liferay.portlet.messageboards.service.MBThreadFlagLocalServiceUtil;
051    import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
052    import com.liferay.portlet.messageboards.service.persistence.MBBanUtil;
053    import com.liferay.portlet.messageboards.service.persistence.MBCategoryUtil;
054    import com.liferay.portlet.messageboards.service.persistence.MBMessageUtil;
055    import com.liferay.portlet.messageboards.service.persistence.MBThreadFlagUtil;
056    import com.liferay.portlet.messageboards.service.persistence.MBThreadUtil;
057    
058    import java.io.InputStream;
059    
060    import java.util.ArrayList;
061    import java.util.Collections;
062    import java.util.Iterator;
063    import java.util.List;
064    import java.util.Map;
065    
066    import javax.portlet.PortletPreferences;
067    
068    /**
069     * @author Bruno Farache
070     * @author Raymond Augé
071     */
072    public class MBPortletDataHandlerImpl extends BasePortletDataHandler {
073    
074            @Override
075            public PortletDataHandlerControl[] getExportControls() {
076                    return new PortletDataHandlerControl[] {
077                            _categoriesAndMessages, _attachments, _threadFlags, _userBans,
078                            _ratings, _tags
079                    };
080            }
081    
082            @Override
083            public PortletDataHandlerControl[] getImportControls() {
084                    return new PortletDataHandlerControl[] {
085                            _categoriesAndMessages, _attachments, _threadFlags, _userBans,
086                            _ratings, _tags
087                    };
088            }
089    
090            @Override
091            public boolean isAlwaysExportable() {
092                    return _ALWAYS_EXPORTABLE;
093            }
094    
095            @Override
096            public boolean isPublishToLiveByDefault() {
097                    return PropsValues.MESSAGE_BOARDS_PUBLISH_TO_LIVE_BY_DEFAULT;
098            }
099    
100            @Override
101            protected PortletPreferences doDeleteData(
102                            PortletDataContext portletDataContext, String portletId,
103                            PortletPreferences portletPreferences)
104                    throws Exception {
105    
106                    if (!portletDataContext.addPrimaryKey(
107                                    MBPortletDataHandlerImpl.class, "deleteData")) {
108    
109                            MBCategoryLocalServiceUtil.deleteCategories(
110                                    portletDataContext.getScopeGroupId());
111    
112                            MBThreadLocalServiceUtil.deleteThreads(
113                                    portletDataContext.getScopeGroupId(),
114                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
115                    }
116    
117                    return null;
118            }
119    
120            @Override
121            protected String doExportData(
122                            PortletDataContext portletDataContext, String portletId,
123                            PortletPreferences portletPreferences)
124                    throws Exception {
125    
126                    portletDataContext.addPermissions(
127                            "com.liferay.portlet.messageboards",
128                            portletDataContext.getScopeGroupId());
129    
130                    Document document = SAXReaderUtil.createDocument();
131    
132                    Element rootElement = document.addElement("message-boards-data");
133    
134                    rootElement.addAttribute(
135                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
136    
137                    Element categoriesElement = rootElement.addElement("categories");
138                    Element messagesElement = rootElement.addElement("messages");
139                    Element threadFlagsElement = rootElement.addElement("thread-flags");
140                    Element userBansElement = rootElement.addElement("user-bans");
141    
142                    List<MBCategory> categories = MBCategoryUtil.findByGroupId(
143                            portletDataContext.getScopeGroupId());
144    
145                    for (MBCategory category : categories) {
146                            exportCategory(
147                                    portletDataContext, categoriesElement, messagesElement,
148                                    threadFlagsElement, category);
149                    }
150    
151                    List<MBMessage> messages = MBMessageUtil.findByG_C(
152                            portletDataContext.getScopeGroupId(),
153                            MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID);
154    
155                    for (MBMessage message : messages) {
156                            exportMessage(
157                                    portletDataContext, categoriesElement, messagesElement,
158                                    threadFlagsElement, message);
159                    }
160    
161                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "user-bans")) {
162                            List<MBBan> bans = MBBanUtil.findByGroupId(
163                                    portletDataContext.getScopeGroupId());
164    
165                            for (MBBan ban : bans) {
166                                    exportBan(portletDataContext, userBansElement, ban);
167                            }
168                    }
169    
170                    return document.formattedString();
171            }
172    
173            @Override
174            protected PortletPreferences doImportData(
175                            PortletDataContext portletDataContext, String portletId,
176                            PortletPreferences portletPreferences, String data)
177                    throws Exception {
178    
179                    portletDataContext.importPermissions(
180                            "com.liferay.portlet.messageboards",
181                            portletDataContext.getSourceGroupId(),
182                            portletDataContext.getScopeGroupId());
183    
184                    Document document = SAXReaderUtil.read(data);
185    
186                    Element rootElement = document.getRootElement();
187    
188                    Element categoriesElement = rootElement.element("categories");
189    
190                    for (Element categoryElement : categoriesElement.elements("category")) {
191                            String path = categoryElement.attributeValue("path");
192    
193                            if (!portletDataContext.isPathNotProcessed(path)) {
194                                    continue;
195                            }
196    
197                            MBCategory category =
198                                    (MBCategory)portletDataContext.getZipEntryAsObject(path);
199    
200                            importCategory(portletDataContext, path, category);
201                    }
202    
203                    Element messagesElement = rootElement.element("messages");
204    
205                    for (Element messageElement : messagesElement.elements("message")) {
206                            String path = messageElement.attributeValue("path");
207    
208                            if (!portletDataContext.isPathNotProcessed(path)) {
209                                    continue;
210                            }
211    
212                            MBMessage message =
213                                    (MBMessage)portletDataContext.getZipEntryAsObject(path);
214    
215                            importMessage(portletDataContext, messageElement, message);
216                    }
217    
218                    if (portletDataContext.getBooleanParameter(
219                                    _NAMESPACE, "thread-flags")) {
220    
221                            Element threadFlagsElement = rootElement.element("thread-flags");
222    
223                            for (Element threadFlagElement :
224                                            threadFlagsElement.elements("thread-flag")) {
225    
226                                    String path = threadFlagElement.attributeValue("path");
227    
228                                    if (!portletDataContext.isPathNotProcessed(path)) {
229                                            continue;
230                                    }
231    
232                                    MBThreadFlag threadFlag =
233                                            (MBThreadFlag)portletDataContext.getZipEntryAsObject(path);
234    
235                                    importThreadFlag(portletDataContext, threadFlag);
236                            }
237                    }
238    
239                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "user-bans")) {
240                            Element userBansElement = rootElement.element("user-bans");
241    
242                            for (Element userBanElement :
243                                            userBansElement.elements("user-ban")) {
244    
245                                    String path = userBanElement.attributeValue("path");
246    
247                                    if (!portletDataContext.isPathNotProcessed(path)) {
248                                            continue;
249                                    }
250    
251                                    MBBan ban = (MBBan)portletDataContext.getZipEntryAsObject(path);
252    
253                                    importBan(portletDataContext, userBanElement, ban);
254                            }
255                    }
256    
257                    return null;
258            }
259    
260            protected void exportBan(
261                            PortletDataContext portletDataContext, Element userBansElement,
262                            MBBan ban)
263                    throws Exception {
264    
265                    if (!portletDataContext.isWithinDateRange(ban.getModifiedDate())) {
266                            return;
267                    }
268    
269                    String path = getUserBanPath(portletDataContext, ban);
270    
271                    if (!portletDataContext.isPathNotProcessed(path)) {
272                            return;
273                    }
274    
275                    Element userBanElement = userBansElement.addElement("user-ban");
276    
277                    ban.setBanUserUuid(ban.getBanUserUuid());
278    
279                    portletDataContext.addClassedModel(
280                            userBanElement, path, ban, _NAMESPACE);
281            }
282    
283            protected void exportCategory(
284                            PortletDataContext portletDataContext, Element categoriesElement,
285                            Element messagesElement, Element threadFlagsElement,
286                            MBCategory category)
287                    throws Exception {
288    
289                    if (portletDataContext.isWithinDateRange(category.getModifiedDate())) {
290                            exportParentCategory(
291                                    portletDataContext, categoriesElement,
292                                    category.getParentCategoryId());
293    
294                            String path = getCategoryPath(portletDataContext, category);
295    
296                            if (portletDataContext.isPathNotProcessed(path)) {
297                                    Element categoryElement = categoriesElement.addElement(
298                                            "category");
299    
300                                    portletDataContext.addClassedModel(
301                                            categoryElement, path, category, _NAMESPACE);
302                            }
303                    }
304    
305                    List<MBMessage> messages = MBMessageUtil.findByG_C(
306                            category.getGroupId(), category.getCategoryId());
307    
308                    for (MBMessage message : messages) {
309                            exportMessage(
310                                    portletDataContext, categoriesElement, messagesElement,
311                                    threadFlagsElement, message);
312                    }
313            }
314    
315            protected void exportMessage(
316                            PortletDataContext portletDataContext, Element categoriesElement,
317                            Element messagesElement, Element threadFlagsElement,
318                            MBMessage message)
319                    throws Exception {
320    
321                    if (!portletDataContext.isWithinDateRange(message.getModifiedDate())) {
322                            return;
323                    }
324    
325                    if (message.getStatus() != WorkflowConstants.STATUS_APPROVED) {
326                            return;
327                    }
328    
329                    exportParentCategory(
330                            portletDataContext, categoriesElement, message.getCategoryId());
331    
332                    String path = getMessagePath(portletDataContext, message);
333    
334                    if (!portletDataContext.isPathNotProcessed(path)) {
335                            return;
336                    }
337    
338                    Element messageElement = messagesElement.addElement("message");
339    
340                    message.setPriority(message.getPriority());
341    
342                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "attachments") &&
343                            message.isAttachments()) {
344    
345                            for (String attachment : message.getAttachmentsFiles()) {
346                                    int pos = attachment.lastIndexOf(CharPool.FORWARD_SLASH);
347    
348                                    String name = attachment.substring(pos + 1);
349                                    String binPath = getMessageAttachementBinPath(
350                                            portletDataContext, message, name);
351    
352                                    Element attachmentElement = messageElement.addElement(
353                                            "attachment");
354    
355                                    attachmentElement.addAttribute("name", name);
356                                    attachmentElement.addAttribute("bin-path", binPath);
357    
358                                    byte[] bytes = DLStoreUtil.getFileAsBytes(
359                                            portletDataContext.getCompanyId(), CompanyConstants.SYSTEM,
360                                            attachment);
361    
362                                    portletDataContext.addZipEntry(binPath, bytes);
363                            }
364    
365                            message.setAttachmentsDir(message.getAttachmentsDir());
366                    }
367    
368                    if (portletDataContext.getBooleanParameter(
369                                    _NAMESPACE, "thread-flags")) {
370    
371                            List<MBThreadFlag> threadFlags = MBThreadFlagUtil.findByThreadId(
372                                    message.getThreadId());
373    
374                            for (MBThreadFlag threadFlag : threadFlags) {
375                                    exportThreadFlag(
376                                            portletDataContext, threadFlagsElement, threadFlag);
377                            }
378                    }
379    
380                    portletDataContext.addClassedModel(
381                            messageElement, path, message, _NAMESPACE);
382            }
383    
384            protected void exportParentCategory(
385                            PortletDataContext portletDataContext, Element categoriesElement,
386                            long categoryId)
387                    throws Exception {
388    
389                    if ((!portletDataContext.hasDateRange()) ||
390                            (categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
391                            (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
392    
393                            return;
394                    }
395    
396                    MBCategory category = MBCategoryUtil.findByPrimaryKey(categoryId);
397    
398                    exportParentCategory(
399                            portletDataContext, categoriesElement,
400                            category.getParentCategoryId());
401    
402                    String path = getCategoryPath(portletDataContext, category);
403    
404                    if (portletDataContext.isPathNotProcessed(path)) {
405                            Element categoryElement = categoriesElement.addElement("category");
406    
407                            portletDataContext.addClassedModel(
408                                    categoryElement, path, category, _NAMESPACE);
409                    }
410            }
411    
412            protected void exportThreadFlag(
413                            PortletDataContext portletDataContext, Element threadFlagsElement,
414                            MBThreadFlag threadFlag)
415                    throws Exception {
416    
417                    String path = getThreadFlagPath(portletDataContext, threadFlag);
418    
419                    if (!portletDataContext.isPathNotProcessed(path)) {
420                            return;
421                    }
422    
423                    Element threadFlagElement = threadFlagsElement.addElement(
424                            "thread-flag");
425    
426                    portletDataContext.addClassedModel(
427                            threadFlagElement, path, threadFlag, _NAMESPACE);
428            }
429    
430            protected List<ObjectValuePair<String, InputStream>> getAttachments(
431                    PortletDataContext portletDataContext, Element messageElement,
432                    MBMessage message) {
433    
434                    if (!message.isAttachments() &&
435                            portletDataContext.getBooleanParameter(_NAMESPACE, "attachments")) {
436    
437                            return Collections.emptyList();
438                    }
439    
440                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
441                            new ArrayList<ObjectValuePair<String, InputStream>>();
442    
443                    List<Element> attachmentElements = messageElement.elements(
444                            "attachment");
445    
446                    for (Element attachmentElement : attachmentElements) {
447                            String name = attachmentElement.attributeValue("name");
448                            String binPath = attachmentElement.attributeValue(
449                                    "bin-path");
450    
451                            InputStream inputStream =
452                                    portletDataContext.getZipEntryAsInputStream(binPath);
453    
454                            ObjectValuePair<String, InputStream> inputStreamOVP =
455                                    new ObjectValuePair<String, InputStream>(name, inputStream);
456    
457                            inputStreamOVPs.add(inputStreamOVP);
458                    }
459    
460                    if (inputStreamOVPs.isEmpty()) {
461                            _log.error(
462                                    "Could not find attachments for message " +
463                                            message.getMessageId());
464                    }
465    
466                    return inputStreamOVPs;
467            }
468    
469            protected long getCategoryId(
470                            PortletDataContext portletDataContext, MBMessage message,
471                            Map<Long, Long> categoryPKs, long categoryId)
472                    throws Exception {
473    
474                    if ((categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
475                            (categoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID) &&
476                            (categoryId == message.getCategoryId())) {
477    
478                            String path = getImportCategoryPath(
479                                    portletDataContext, categoryId);
480    
481                            MBCategory category =
482                                    (MBCategory)portletDataContext.getZipEntryAsObject(path);
483    
484                            importCategory(portletDataContext, path, category);
485    
486                            categoryId = MapUtil.getLong(
487                                    categoryPKs, message.getCategoryId(), message.getCategoryId());
488                    }
489    
490                    return categoryId;
491            }
492    
493            protected String getCategoryPath(
494                    PortletDataContext portletDataContext, MBCategory category) {
495    
496                    StringBundler sb = new StringBundler(4);
497    
498                    sb.append(
499                            portletDataContext.getPortletPath(PortletKeys.MESSAGE_BOARDS));
500                    sb.append("/categories/");
501                    sb.append(category.getCategoryId());
502                    sb.append(".xml");
503    
504                    return sb.toString();
505            }
506    
507            protected String getImportCategoryPath(
508                    PortletDataContext portletDataContext, long categoryId) {
509    
510                    StringBundler sb = new StringBundler(4);
511    
512                    sb.append(
513                            portletDataContext.getSourcePortletPath(
514                                    PortletKeys.MESSAGE_BOARDS));
515                    sb.append("/categories/");
516                    sb.append(categoryId);
517                    sb.append(".xml");
518    
519                    return sb.toString();
520            }
521    
522            protected String getMessageAttachementBinPath(
523                    PortletDataContext portletDataContext, MBMessage message,
524                    String attachment) {
525    
526                    StringBundler sb = new StringBundler(5);
527    
528                    sb.append(
529                            portletDataContext.getPortletPath(PortletKeys.MESSAGE_BOARDS));
530                    sb.append("/bin/");
531                    sb.append(message.getMessageId());
532                    sb.append(StringPool.SLASH);
533                    sb.append(PortalUUIDUtil.generate());
534    
535                    return sb.toString();
536            }
537    
538            protected String getMessagePath(
539                    PortletDataContext portletDataContext, MBMessage message) {
540    
541                    StringBundler sb = new StringBundler(4);
542    
543                    sb.append(
544                            portletDataContext.getPortletPath(PortletKeys.MESSAGE_BOARDS));
545                    sb.append("/messages/");
546                    sb.append(message.getMessageId());
547                    sb.append(".xml");
548    
549                    return sb.toString();
550            }
551    
552            protected String getThreadFlagPath(
553                    PortletDataContext portletDataContext, MBThreadFlag threadFlag) {
554    
555                    StringBundler sb = new StringBundler(4);
556    
557                    sb.append(
558                            portletDataContext.getPortletPath(PortletKeys.MESSAGE_BOARDS));
559                    sb.append("/thread-flags/");
560                    sb.append(threadFlag.getThreadFlagId());
561                    sb.append(".xml");
562    
563                    return sb.toString();
564            }
565    
566            protected String getUserBanPath(
567                    PortletDataContext portletDataContext, MBBan ban) {
568    
569                    StringBundler sb = new StringBundler(4);
570    
571                    sb.append(
572                            portletDataContext.getPortletPath(PortletKeys.MESSAGE_BOARDS));
573                    sb.append("/user-bans/");
574                    sb.append(ban.getBanId());
575                    sb.append(".xml");
576    
577                    return sb.toString();
578            }
579    
580            protected void importBan(
581                            PortletDataContext portletDataContext, Element userBanElement,
582                            MBBan ban)
583                    throws Exception {
584    
585                    long userId = portletDataContext.getUserId(ban.getUserUuid());
586    
587                    ServiceContext serviceContext = portletDataContext.createServiceContext(
588                            userBanElement, ban, _NAMESPACE);
589    
590                    List<User> users = UserUtil.findByUuid(ban.getBanUserUuid());
591    
592                    Iterator<User> itr = users.iterator();
593    
594                    if (itr.hasNext()) {
595                            User user = itr.next();
596    
597                            MBBanLocalServiceUtil.addBan(
598                                    userId, user.getUserId(), serviceContext);
599                    }
600                    else {
601                            _log.error(
602                                    "Could not find banned user with uuid " + ban.getBanUserUuid());
603                    }
604            }
605    
606            protected void importCategory(
607                            PortletDataContext portletDataContext, String categoryPath,
608                            MBCategory category)
609                    throws Exception {
610    
611                    long userId = portletDataContext.getUserId(category.getUserUuid());
612    
613                    Map<Long, Long> categoryPKs =
614                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
615                                    MBCategory.class);
616    
617                    long parentCategoryId = MapUtil.getLong(
618                            categoryPKs, category.getParentCategoryId(),
619                            category.getParentCategoryId());
620    
621                    String emailAddress = null;
622                    String inProtocol = null;
623                    String inServerName = null;
624                    int inServerPort = 0;
625                    boolean inUseSSL = false;
626                    String inUserName = null;
627                    String inPassword = null;
628                    int inReadInterval = 0;
629                    String outEmailAddress = null;
630                    boolean outCustom = false;
631                    String outServerName = null;
632                    int outServerPort = 0;
633                    boolean outUseSSL = false;
634                    String outUserName = null;
635                    String outPassword = null;
636                    boolean allowAnonymous = false;
637                    boolean mailingListActive = false;
638    
639                    ServiceContext serviceContext = portletDataContext.createServiceContext(
640                            categoryPath, category, _NAMESPACE);
641    
642                    if ((parentCategoryId !=
643                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
644                            (parentCategoryId != MBCategoryConstants.DISCUSSION_CATEGORY_ID) &&
645                            (parentCategoryId == category.getParentCategoryId())) {
646    
647                            String path = getImportCategoryPath(
648                                    portletDataContext, parentCategoryId);
649    
650                            MBCategory parentCategory =
651                                    (MBCategory)portletDataContext.getZipEntryAsObject(path);
652    
653                            importCategory(portletDataContext, path, parentCategory);
654    
655                            parentCategoryId = MapUtil.getLong(
656                                    categoryPKs, category.getParentCategoryId(),
657                                    category.getParentCategoryId());
658                    }
659    
660                    MBCategory importedCategory = null;
661    
662                    if (portletDataContext.isDataStrategyMirror()) {
663                            MBCategory existingCategory = MBCategoryUtil.fetchByUUID_G(
664                                    category.getUuid(), portletDataContext.getScopeGroupId());
665    
666                            if (existingCategory == null) {
667                                    serviceContext.setUuid(category.getUuid());
668    
669                                    importedCategory = MBCategoryLocalServiceUtil.addCategory(
670                                            userId, parentCategoryId, category.getName(),
671                                            category.getDescription(), category.getDisplayStyle(),
672                                            emailAddress, inProtocol, inServerName, inServerPort,
673                                            inUseSSL, inUserName, inPassword, inReadInterval,
674                                            outEmailAddress, outCustom, outServerName, outServerPort,
675                                            outUseSSL, outUserName, outPassword, allowAnonymous,
676                                            mailingListActive, serviceContext);
677                            }
678                            else {
679                                    importedCategory = MBCategoryLocalServiceUtil.updateCategory(
680                                            existingCategory.getCategoryId(), parentCategoryId,
681                                            category.getName(), category.getDescription(),
682                                            category.getDisplayStyle(), emailAddress, inProtocol,
683                                            inServerName, inServerPort, inUseSSL, inUserName,
684                                            inPassword, inReadInterval, outEmailAddress, outCustom,
685                                            outServerName, outServerPort, outUseSSL, outUserName,
686                                            outPassword, allowAnonymous, mailingListActive, false,
687                                            serviceContext);
688                            }
689                    }
690                    else {
691                            importedCategory = MBCategoryLocalServiceUtil.addCategory(
692                                    userId, parentCategoryId, category.getName(),
693                                    category.getDescription(), category.getDisplayStyle(),
694                                    emailAddress, inProtocol, inServerName, inServerPort, inUseSSL,
695                                    inUserName, inPassword, inReadInterval, outEmailAddress,
696                                    outCustom, outServerName, outServerPort, outUseSSL, outUserName,
697                                    outPassword, allowAnonymous, mailingListActive, serviceContext);
698                    }
699    
700                    portletDataContext.importClassedModel(
701                            category, importedCategory, _NAMESPACE);
702            }
703    
704            protected void importMessage(
705                            PortletDataContext portletDataContext, Element messageElement,
706                            MBMessage message)
707                    throws Exception {
708    
709                    long userId = portletDataContext.getUserId(message.getUserUuid());
710                    String userName = message.getUserName();
711    
712                    Map<Long, Long> categoryPKs =
713                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
714                                    MBCategory.class);
715    
716                    long categoryId = MapUtil.getLong(
717                            categoryPKs, message.getCategoryId(), message.getCategoryId());
718    
719                    Map<Long, Long> threadPKs =
720                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
721                                    MBThread.class);
722    
723                    long threadId = MapUtil.getLong(threadPKs, message.getThreadId(), 0);
724    
725                    Map<Long, Long> messagePKs =
726                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
727                                    MBMessage.class);
728    
729                    long parentMessageId = MapUtil.getLong(
730                            messagePKs, message.getParentMessageId(),
731                            message.getParentMessageId());
732    
733                    List<String> existingFiles = new ArrayList<String>();
734    
735                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
736                            getAttachments(portletDataContext, messageElement, message);
737    
738                    try {
739                            ServiceContext serviceContext =
740                                    portletDataContext.createServiceContext(
741                                            messageElement, message, _NAMESPACE);
742    
743                            if (message.getStatus() != WorkflowConstants.STATUS_APPROVED) {
744                                    serviceContext.setWorkflowAction(
745                                            WorkflowConstants.ACTION_SAVE_DRAFT);
746                            }
747    
748                            categoryId = getCategoryId(
749                                    portletDataContext, message, categoryPKs, categoryId);
750    
751                            MBMessage importedMessage = null;
752    
753                            if (portletDataContext.isDataStrategyMirror()) {
754                                    MBMessage existingMessage = MBMessageUtil.fetchByUUID_G(
755                                            message.getUuid(), portletDataContext.getScopeGroupId());
756    
757                                    if (existingMessage == null) {
758                                            serviceContext.setUuid(message.getUuid());
759    
760                                            importedMessage = MBMessageLocalServiceUtil.addMessage(
761                                                    userId, userName, portletDataContext.getScopeGroupId(),
762                                                    categoryId, threadId, parentMessageId,
763                                                    message.getSubject(), message.getBody(),
764                                                    message.getFormat(), inputStreamOVPs,
765                                                    message.getAnonymous(), message.getPriority(),
766                                                    message.getAllowPingbacks(), serviceContext);
767                                    }
768                                    else {
769                                            importedMessage = MBMessageLocalServiceUtil.updateMessage(
770                                                    userId, existingMessage.getMessageId(),
771                                                    message.getSubject(), message.getBody(),
772                                                    inputStreamOVPs, existingFiles, message.getPriority(),
773                                                    message.getAllowPingbacks(), serviceContext);
774                                    }
775                            }
776                            else {
777                                    importedMessage = MBMessageLocalServiceUtil.addMessage(
778                                            userId, userName, portletDataContext.getScopeGroupId(),
779                                            categoryId, threadId, parentMessageId, message.getSubject(),
780                                            message.getBody(), message.getFormat(), inputStreamOVPs,
781                                            message.getAnonymous(), message.getPriority(),
782                                            message.getAllowPingbacks(), serviceContext);
783                            }
784    
785                            threadPKs.put(message.getThreadId(), importedMessage.getThreadId());
786    
787                            portletDataContext.importClassedModel(
788                                    message, importedMessage, _NAMESPACE);
789                    }
790                    finally {
791                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
792                                            inputStreamOVPs) {
793    
794                                    InputStream inputStream = inputStreamOVP.getValue();
795    
796                                    StreamUtil.cleanUp(inputStream);
797                            }
798                    }
799            }
800    
801            protected void importThreadFlag(
802                            PortletDataContext portletDataContext, MBThreadFlag threadFlag)
803                    throws Exception {
804    
805                    long userId = portletDataContext.getUserId(threadFlag.getUserUuid());
806    
807                    Map<Long, Long> messagePKs =
808                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
809                                    MBMessage.class);
810    
811                    long threadId = MapUtil.getLong(
812                            messagePKs, threadFlag.getThreadId(), threadFlag.getThreadId());
813    
814                    MBThread thread = MBThreadUtil.findByPrimaryKey(threadId);
815    
816                    MBThreadFlagLocalServiceUtil.addThreadFlag(userId, thread);
817            }
818    
819            private static final boolean _ALWAYS_EXPORTABLE = true;
820    
821            private static final String _NAMESPACE = "message_board";
822    
823            private static Log _log = LogFactoryUtil.getLog(
824                    MBPortletDataHandlerImpl.class);
825    
826            private static PortletDataHandlerBoolean _attachments =
827                    new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
828    
829            private static PortletDataHandlerBoolean _categoriesAndMessages =
830                    new PortletDataHandlerBoolean(
831                            _NAMESPACE, "categories-and-messages", true, true);
832    
833            private static PortletDataHandlerBoolean _ratings =
834                    new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
835    
836            private static PortletDataHandlerBoolean _tags =
837                    new PortletDataHandlerBoolean(_NAMESPACE, "tags");
838    
839            private static PortletDataHandlerBoolean _threadFlags =
840                    new PortletDataHandlerBoolean(_NAMESPACE, "thread-flags");
841    
842            private static PortletDataHandlerBoolean _userBans =
843                    new PortletDataHandlerBoolean(_NAMESPACE, "user-bans");
844    
845    }