protected long importMBMessage(
      MBMessage mbMessage, long threadId, long calendarBookingId, Map<Long, Long> mbMessageIds)
      throws PortalException, SystemException {

    Long messageId = mbMessageIds.get(mbMessage.getMessageId());

    if (messageId != null) {
      return messageId;
    }

    messageId = counterLocalService.increment();

    addMBMessage(
        PortalUUIDUtil.generate(),
        messageId,
        mbMessage.getGroupId(),
        mbMessage.getCompanyId(),
        mbMessage.getUserId(),
        mbMessage.getUserName(),
        mbMessage.getCreateDate(),
        mbMessage.getModifiedDate(),
        classNameLocalService.getClassNameId(CalendarBooking.class.getName()),
        calendarBookingId,
        mbMessage.getCategoryId(),
        threadId,
        mbMessage.getRootMessageId(),
        mbMessage.getParentMessageId(),
        mbMessage.getSubject(),
        mbMessage.getBody(),
        mbMessage.getFormat(),
        mbMessage.isAnonymous(),
        mbMessage.getPriority(),
        mbMessage.getAllowPingbacks(),
        mbMessage.isAnswer(),
        mbMessage.getStatus(),
        mbMessage.getStatusByUserId(),
        mbMessage.getStatusByUserName(),
        mbMessage.getStatusDate(),
        mbMessageIds);

    long mbDiscussionClassNameId =
        classNameLocalService.getClassNameId(MBDiscussion.class.getName());

    importRatings(
        mbDiscussionClassNameId, mbMessage.getMessageId(), mbDiscussionClassNameId, messageId);

    mbMessageIds.put(mbMessage.getMessageId(), messageId);

    return messageId;
  }
  public static JSONObject toJSONObject(MBMessage model) {
    JSONObject jsonObj = new JSONObject();

    JSONUtil.put(jsonObj, "uuid", model.getUuid());
    JSONUtil.put(jsonObj, "messageId", model.getMessageId());
    JSONUtil.put(jsonObj, "companyId", model.getCompanyId());
    JSONUtil.put(jsonObj, "userId", model.getUserId());
    JSONUtil.put(jsonObj, "userName", model.getUserName());
    JSONUtil.put(jsonObj, "createDate", model.getCreateDate());
    JSONUtil.put(jsonObj, "modifiedDate", model.getModifiedDate());
    JSONUtil.put(jsonObj, "categoryId", model.getCategoryId());
    JSONUtil.put(jsonObj, "threadId", model.getThreadId());
    JSONUtil.put(jsonObj, "parentMessageId", model.getParentMessageId());
    JSONUtil.put(jsonObj, "subject", model.getSubject());
    JSONUtil.put(jsonObj, "body", model.getBody());
    JSONUtil.put(jsonObj, "attachments", model.getAttachments());
    JSONUtil.put(jsonObj, "anonymous", model.getAnonymous());

    return jsonObj;
  }
  public int compareTo(MBMessage mbMessage) {
    int value = 0;

    value = DateUtil.compareTo(getCreateDate(), mbMessage.getCreateDate());

    if (value != 0) {
      return value;
    }

    if (getMessageId() < mbMessage.getMessageId()) {
      value = -1;
    } else if (getMessageId() > mbMessage.getMessageId()) {
      value = 1;
    } else {
      value = 0;
    }

    if (value != 0) {
      return value;
    }

    return 0;
  }
  @Override
  public MBThread addThread(long categoryId, MBMessage message, ServiceContext serviceContext)
      throws PortalException, SystemException {

    // Thread

    Date now = new Date();

    long threadId = message.getThreadId();

    if (!message.isRoot() || (threadId <= 0)) {
      threadId = counterLocalService.increment();
    }

    MBThread thread = mbThreadPersistence.create(threadId);

    thread.setUuid(serviceContext.getUuid());
    thread.setGroupId(message.getGroupId());
    thread.setCompanyId(message.getCompanyId());
    thread.setUserId(message.getUserId());
    thread.setUserName(message.getUserName());
    thread.setCreateDate(serviceContext.getCreateDate(now));
    thread.setModifiedDate(serviceContext.getModifiedDate(now));
    thread.setCategoryId(categoryId);
    thread.setRootMessageId(message.getMessageId());
    thread.setRootMessageUserId(message.getUserId());

    if (message.isAnonymous()) {
      thread.setLastPostByUserId(0);
    } else {
      thread.setLastPostByUserId(message.getUserId());
    }

    thread.setLastPostDate(message.getCreateDate());

    if (message.getPriority() != MBThreadConstants.PRIORITY_NOT_GIVEN) {
      thread.setPriority(message.getPriority());
    }

    thread.setStatus(message.getStatus());
    thread.setStatusByUserId(message.getStatusByUserId());
    thread.setStatusByUserName(message.getStatusByUserName());
    thread.setStatusDate(message.getStatusDate());

    mbThreadPersistence.update(thread);

    // Asset

    if (categoryId >= 0) {
      assetEntryLocalService.updateEntry(
          message.getUserId(),
          message.getGroupId(),
          thread.getStatusDate(),
          thread.getLastPostDate(),
          MBThread.class.getName(),
          thread.getThreadId(),
          thread.getUuid(),
          0,
          new long[0],
          new String[0],
          false,
          null,
          null,
          null,
          null,
          String.valueOf(thread.getRootMessageId()),
          null,
          null,
          null,
          null,
          0,
          0,
          null,
          false);
    }

    return thread;
  }
  protected void sendEmail(long mbMessageId, ThemeDisplay themeDisplay) throws Exception {

    MBMessage mbMessage = MBMessageLocalServiceUtil.getMBMessage(mbMessageId);

    User sender = UserLocalServiceUtil.getUser(mbMessage.getUserId());

    Company company = CompanyLocalServiceUtil.getCompany(sender.getCompanyId());

    InternetAddress from = new InternetAddress(company.getEmailAddress());

    String subject =
        StringUtil.read(
            PrivateMessagingPortlet.class.getResourceAsStream(
                "dependencies/notification_message_subject.tmpl"));

    subject =
        StringUtil.replace(
            subject,
            new String[] {"[$COMPANY_NAME$]", "[$FROM_NAME$]"},
            new String[] {company.getName(), sender.getFullName()});

    String body =
        StringUtil.read(
            PrivateMessagingPortlet.class.getResourceAsStream(
                "dependencies/notification_message_body.tmpl"));

    long portraitId = sender.getPortraitId();
    String tokenId = WebServerServletTokenUtil.getToken(sender.getPortraitId());
    String portraitURL =
        themeDisplay.getPortalURL()
            + themeDisplay.getPathImage()
            + "/user_"
            + (sender.isFemale() ? "female" : "male")
            + "_portrait?img_id="
            + portraitId
            + "&t="
            + tokenId;

    body =
        StringUtil.replace(
            body,
            new String[] {
              "[$BODY$]", "[$COMPANY_NAME$]", "[$FROM_AVATAR$]",
              "[$FROM_NAME$]", "[$FROM_PROFILE_URL$]", "[$SUBJECT$]"
            },
            new String[] {
              mbMessage.getBody(),
              company.getName(),
              portraitURL,
              sender.getFullName(),
              sender.getDisplayURL(themeDisplay),
              mbMessage.getSubject()
            });

    List<UserThread> userThreads =
        UserThreadLocalServiceUtil.getMBThreadUserThreads(mbMessage.getThreadId());

    for (UserThread userThread : userThreads) {
      if ((userThread.getUserId() == mbMessage.getUserId())
          && UserNotificationManagerUtil.isDeliver(
              userThread.getUserId(),
              PortletKeys.PRIVATE_MESSAGING,
              PrivateMessagingConstants.NEW_MESSAGE,
              0,
              UserNotificationDeliveryConstants.TYPE_EMAIL)) {

        continue;
      }

      User recipient = UserLocalServiceUtil.getUser(userThread.getUserId());

      String threadURL = getThreadURL(recipient, mbMessage.getThreadId(), themeDisplay);

      if (Validator.isNull(threadURL)) {
        continue;
      }

      InternetAddress to = new InternetAddress(recipient.getEmailAddress());

      Format dateFormatDateTime =
          FastDateFormatFactoryUtil.getDateTime(
              FastDateFormatConstants.LONG,
              FastDateFormatConstants.SHORT,
              recipient.getLocale(),
              recipient.getTimeZone());

      String userThreadBody =
          StringUtil.replace(
              body,
              new String[] {"[$SENT_DATE$]", "[$THREAD_URL$]"},
              new String[] {dateFormatDateTime.format(mbMessage.getCreateDate()), threadURL});

      MailMessage mailMessage = new MailMessage(from, to, subject, userThreadBody, true);

      MailServiceUtil.sendEmail(mailMessage);
    }
  }
  protected String exportToRSS(
      String name,
      String description,
      String type,
      double version,
      String displayStyle,
      String feedURL,
      String entryURL,
      List<MBMessage> messages,
      ThemeDisplay themeDisplay)
      throws SystemException {

    SyndFeed syndFeed = new SyndFeedImpl();

    syndFeed.setDescription(description);

    List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();

    syndFeed.setEntries(syndEntries);

    for (MBMessage message : messages) {
      SyndEntry syndEntry = new SyndEntryImpl();

      if (!message.isAnonymous()) {
        String author = PortalUtil.getUserName(message);

        syndEntry.setAuthor(author);
      }

      SyndContent syndContent = new SyndContentImpl();

      syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);

      String value = null;

      if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
        value =
            StringUtil.shorten(
                HtmlUtil.extractText(message.getBody()),
                PropsValues.MESSAGE_BOARDS_RSS_ABSTRACT_LENGTH,
                StringPool.BLANK);
      } else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
        value = StringPool.BLANK;
      } else if (message.isFormatBBCode()) {
        value = BBCodeTranslatorUtil.getHTML(message.getBody());

        value = MBUtil.replaceMessageBodyPaths(themeDisplay, value);
      } else {
        value = message.getBody();
      }

      syndContent.setValue(value);

      syndEntry.setDescription(syndContent);

      syndEntry.setLink(entryURL + "&messageId=" + message.getMessageId());
      syndEntry.setPublishedDate(message.getCreateDate());
      syndEntry.setTitle(message.getSubject());
      syndEntry.setUpdatedDate(message.getModifiedDate());
      syndEntry.setUri(syndEntry.getLink());

      syndEntries.add(syndEntry);
    }

    syndFeed.setFeedType(RSSUtil.getFeedType(type, version));

    List<SyndLink> syndLinks = new ArrayList<SyndLink>();

    syndFeed.setLinks(syndLinks);

    SyndLink selfSyndLink = new SyndLinkImpl();

    syndLinks.add(selfSyndLink);

    selfSyndLink.setHref(feedURL);
    selfSyndLink.setRel("self");

    syndFeed.setPublishedDate(new Date());
    syndFeed.setTitle(name);
    syndFeed.setUri(feedURL);

    try {
      return RSSUtil.export(syndFeed);
    } catch (FeedException fe) {
      throw new SystemException(fe);
    }
  }
  public void importComments(Class<?> clazz, long classPK, long newClassPK, long groupId)
      throws PortalException, SystemException {

    Map<Long, Long> messagePKs = new HashMap<Long, Long>();
    Map<Long, Long> threadPKs = new HashMap<Long, Long>();

    List<MBMessage> messages = _commentsMap.get(getPrimaryKeyString(clazz, classPK));

    if (messages == null) {
      return;
    }

    MBDiscussion discussion = null;

    try {
      discussion = MBDiscussionLocalServiceUtil.getDiscussion(clazz.getName(), newClassPK);
    } catch (NoSuchDiscussionException nsde) {
    }

    for (MBMessage message : messages) {
      long userId = getUserId(message.getUserUuid());
      long parentMessageId =
          MapUtil.getLong(messagePKs, message.getParentMessageId(), message.getParentMessageId());
      long threadId = MapUtil.getLong(threadPKs, message.getThreadId(), message.getThreadId());

      if ((message.getParentMessageId() == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID)
          && (discussion != null)) {

        MBThread thread = MBThreadLocalServiceUtil.getThread(discussion.getThreadId());

        long rootMessageId = thread.getRootMessageId();

        messagePKs.put(message.getMessageId(), rootMessageId);
        threadPKs.put(message.getThreadId(), thread.getThreadId());
      } else {
        ServiceContext serviceContext = new ServiceContext();

        serviceContext.setCreateDate(message.getCreateDate());
        serviceContext.setModifiedDate(message.getModifiedDate());
        serviceContext.setScopeGroupId(groupId);

        MBMessage importedMessage = null;

        if (_dataStrategy.equals(PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)
            || _dataStrategy.equals(PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE)) {

          MBMessage existingMessage = MBMessageUtil.fetchByUUID_G(message.getUuid(), groupId);

          if (existingMessage == null) {
            serviceContext.setUuid(message.getUuid());

            importedMessage =
                MBMessageLocalServiceUtil.addDiscussionMessage(
                    userId,
                    message.getUserName(),
                    groupId,
                    clazz.getName(),
                    newClassPK,
                    threadId,
                    parentMessageId,
                    message.getSubject(),
                    message.getBody(),
                    serviceContext);
          } else {
            serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH);

            importedMessage =
                MBMessageLocalServiceUtil.updateDiscussionMessage(
                    userId,
                    existingMessage.getMessageId(),
                    clazz.getName(),
                    newClassPK,
                    message.getSubject(),
                    message.getBody(),
                    serviceContext);
          }
        } else {
          importedMessage =
              MBMessageLocalServiceUtil.addDiscussionMessage(
                  userId,
                  message.getUserName(),
                  groupId,
                  clazz.getName(),
                  newClassPK,
                  threadId,
                  parentMessageId,
                  message.getSubject(),
                  message.getBody(),
                  serviceContext);
        }

        messagePKs.put(message.getMessageId(), importedMessage.getMessageId());
        threadPKs.put(message.getThreadId(), importedMessage.getThreadId());
      }

      importRatingsEntries(
          MBDiscussion.class, message.getPrimaryKey(), messagePKs.get(message.getPrimaryKey()));
    }
  }
  @Test
  public void testUpdateExisting() throws Exception {
    long pk = RandomTestUtil.nextLong();

    MBMessage newMBMessage = _persistence.create(pk);

    newMBMessage.setUuid(RandomTestUtil.randomString());

    newMBMessage.setGroupId(RandomTestUtil.nextLong());

    newMBMessage.setCompanyId(RandomTestUtil.nextLong());

    newMBMessage.setUserId(RandomTestUtil.nextLong());

    newMBMessage.setUserName(RandomTestUtil.randomString());

    newMBMessage.setCreateDate(RandomTestUtil.nextDate());

    newMBMessage.setModifiedDate(RandomTestUtil.nextDate());

    newMBMessage.setClassNameId(RandomTestUtil.nextLong());

    newMBMessage.setClassPK(RandomTestUtil.nextLong());

    newMBMessage.setCategoryId(RandomTestUtil.nextLong());

    newMBMessage.setThreadId(RandomTestUtil.nextLong());

    newMBMessage.setRootMessageId(RandomTestUtil.nextLong());

    newMBMessage.setParentMessageId(RandomTestUtil.nextLong());

    newMBMessage.setSubject(RandomTestUtil.randomString());

    newMBMessage.setBody(RandomTestUtil.randomString());

    newMBMessage.setFormat(RandomTestUtil.randomString());

    newMBMessage.setAnonymous(RandomTestUtil.randomBoolean());

    newMBMessage.setPriority(RandomTestUtil.nextDouble());

    newMBMessage.setAllowPingbacks(RandomTestUtil.randomBoolean());

    newMBMessage.setAnswer(RandomTestUtil.randomBoolean());

    newMBMessage.setStatus(RandomTestUtil.nextInt());

    newMBMessage.setStatusByUserId(RandomTestUtil.nextLong());

    newMBMessage.setStatusByUserName(RandomTestUtil.randomString());

    newMBMessage.setStatusDate(RandomTestUtil.nextDate());

    _mbMessages.add(_persistence.update(newMBMessage));

    MBMessage existingMBMessage = _persistence.findByPrimaryKey(newMBMessage.getPrimaryKey());

    Assert.assertEquals(existingMBMessage.getUuid(), newMBMessage.getUuid());
    Assert.assertEquals(existingMBMessage.getMessageId(), newMBMessage.getMessageId());
    Assert.assertEquals(existingMBMessage.getGroupId(), newMBMessage.getGroupId());
    Assert.assertEquals(existingMBMessage.getCompanyId(), newMBMessage.getCompanyId());
    Assert.assertEquals(existingMBMessage.getUserId(), newMBMessage.getUserId());
    Assert.assertEquals(existingMBMessage.getUserName(), newMBMessage.getUserName());
    Assert.assertEquals(
        Time.getShortTimestamp(existingMBMessage.getCreateDate()),
        Time.getShortTimestamp(newMBMessage.getCreateDate()));
    Assert.assertEquals(
        Time.getShortTimestamp(existingMBMessage.getModifiedDate()),
        Time.getShortTimestamp(newMBMessage.getModifiedDate()));
    Assert.assertEquals(existingMBMessage.getClassNameId(), newMBMessage.getClassNameId());
    Assert.assertEquals(existingMBMessage.getClassPK(), newMBMessage.getClassPK());
    Assert.assertEquals(existingMBMessage.getCategoryId(), newMBMessage.getCategoryId());
    Assert.assertEquals(existingMBMessage.getThreadId(), newMBMessage.getThreadId());
    Assert.assertEquals(existingMBMessage.getRootMessageId(), newMBMessage.getRootMessageId());
    Assert.assertEquals(existingMBMessage.getParentMessageId(), newMBMessage.getParentMessageId());
    Assert.assertEquals(existingMBMessage.getSubject(), newMBMessage.getSubject());
    Assert.assertEquals(existingMBMessage.getBody(), newMBMessage.getBody());
    Assert.assertEquals(existingMBMessage.getFormat(), newMBMessage.getFormat());
    Assert.assertEquals(existingMBMessage.getAnonymous(), newMBMessage.getAnonymous());
    AssertUtils.assertEquals(existingMBMessage.getPriority(), newMBMessage.getPriority());
    Assert.assertEquals(existingMBMessage.getAllowPingbacks(), newMBMessage.getAllowPingbacks());
    Assert.assertEquals(existingMBMessage.getAnswer(), newMBMessage.getAnswer());
    Assert.assertEquals(existingMBMessage.getStatus(), newMBMessage.getStatus());
    Assert.assertEquals(existingMBMessage.getStatusByUserId(), newMBMessage.getStatusByUserId());
    Assert.assertEquals(
        existingMBMessage.getStatusByUserName(), newMBMessage.getStatusByUserName());
    Assert.assertEquals(
        Time.getShortTimestamp(existingMBMessage.getStatusDate()),
        Time.getShortTimestamp(newMBMessage.getStatusDate()));
  }