protected void sendNotificationEvent(
      final MicroblogsEntry microblogsEntry, ServiceContext serviceContext) throws PortalException {

    final JSONObject notificationEventJSONObject = JSONFactoryUtil.createJSONObject();

    notificationEventJSONObject.put("className", MicroblogsEntry.class.getName());
    notificationEventJSONObject.put("classPK", microblogsEntry.getMicroblogsEntryId());
    notificationEventJSONObject.put(
        "entryTitle",
        MicroblogsUtil.getProcessedContent(
            StringUtil.shorten(microblogsEntry.getContent(), 50), serviceContext));

    AssetRendererFactory<MicroblogsEntry> assetRendererFactory =
        AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClass(MicroblogsEntry.class);

    AssetRenderer<MicroblogsEntry> assetRenderer =
        assetRendererFactory.getAssetRenderer(microblogsEntry.getMicroblogsEntryId());

    String entryURL = StringPool.BLANK;

    try {
      entryURL =
          assetRenderer.getURLViewInContext(
              serviceContext.getLiferayPortletRequest(),
              serviceContext.getLiferayPortletResponse(),
              null);
    } catch (Exception e) {
      if (_log.isDebugEnabled()) {
        _log.debug(e, e);
      }
    }

    notificationEventJSONObject.put("entryURL", entryURL);
    notificationEventJSONObject.put("userId", microblogsEntry.getUserId());

    final List<Long> receiverUserIds = MicroblogsUtil.getSubscriberUserIds(microblogsEntry);

    Callable<Void> callable =
        new Callable<Void>() {

          @Override
          public Void call() throws Exception {
            MessageBusUtil.sendMessage(
                DestinationNames.ASYNC_SERVICE,
                new NotificationProcessCallable(
                    receiverUserIds, microblogsEntry, notificationEventJSONObject));

            return null;
          }
        };

    TransactionCommitCallbackUtil.registerCallback(callable);
  }
  public void updateAsset(
      MicroblogsEntry microblogsEntry, long[] assetCategoryIds, String[] assetTagNames)
      throws PortalException, SystemException {

    Group group = GroupLocalServiceUtil.getCompanyGroup(microblogsEntry.getCompanyId());

    AssetEntryLocalServiceUtil.updateEntry(
        microblogsEntry.getUserId(),
        group.getGroupId(),
        MicroblogsEntry.class.getName(),
        microblogsEntry.getMicroblogsEntryId(),
        assetCategoryIds,
        assetTagNames);
  }
  /**
   * Adds the microblogs entry to the database. Also notifies the appropriate model listeners.
   *
   * @param microblogsEntry the microblogs entry
   * @return the microblogs entry that was added
   * @throws SystemException if a system exception occurred
   */
  @Indexable(type = IndexableType.REINDEX)
  public MicroblogsEntry addMicroblogsEntry(MicroblogsEntry microblogsEntry)
      throws SystemException {
    microblogsEntry.setNew(true);

    return microblogsEntryPersistence.update(microblogsEntry);
  }
  /**
   * Adds the microblogs entry to the database. Also notifies the appropriate model listeners.
   *
   * @param microblogsEntry the microblogs entry
   * @return the microblogs entry that was added
   */
  @Indexable(type = IndexableType.REINDEX)
  @Override
  public MicroblogsEntry addMicroblogsEntry(MicroblogsEntry microblogsEntry) {
    microblogsEntry.setNew(true);

    return microblogsEntryPersistence.update(microblogsEntry);
  }
  protected void validate(int type, long parentMicroblogsEntryId) throws PortalException {

    if (parentMicroblogsEntryId == 0) {
      return;
    }

    MicroblogsEntry microblogsEntry =
        microblogsEntryPersistence.findByPrimaryKey(parentMicroblogsEntryId);

    if (microblogsEntry.getSocialRelationType() == MicroblogsEntryConstants.TYPE_EVERYONE) {

      return;
    }

    if (type == MicroblogsEntryConstants.TYPE_REPOST) {
      throw new UnsupportedMicroblogsEntryException();
    }
  }
  public static boolean contains(
      PermissionChecker permissionChecker, MicroblogsEntry microblogsEntry, String actionId) {

    if (actionId.equals(ActionKeys.DELETE) || actionId.equals(ActionKeys.UPDATE)) {

      if (permissionChecker.hasOwnerPermission(
          microblogsEntry.getCompanyId(),
          MicroblogsEntry.class.getName(),
          microblogsEntry.getMicroblogsEntryId(),
          microblogsEntry.getUserId(),
          actionId)) {

        return true;
      }

      return false;
    }

    if (permissionChecker.hasOwnerPermission(
        microblogsEntry.getCompanyId(),
        MicroblogsEntry.class.getName(),
        microblogsEntry.getMicroblogsEntryId(),
        microblogsEntry.getUserId(),
        actionId)) {

      return true;
    }

    if (microblogsEntry.getSocialRelationType() == 0) {
      return true;
    }

    if ((microblogsEntry.getUserId() != permissionChecker.getUserId())
        && SocialRelationLocalServiceUtil.hasRelation(
            permissionChecker.getUserId(),
            microblogsEntry.getUserId(),
            microblogsEntry.getSocialRelationType())) {

      return true;
    }

    return false;
  }
  protected long getSubscriptionId(long userId, MicroblogsEntry microblogsEntry) {

    try {
      Subscription subscription =
          subscriptionLocalService.getSubscription(
              microblogsEntry.getCompanyId(),
              userId,
              MicroblogsEntry.class.getName(),
              microblogsEntry.getParentMicroblogsEntryId());

      return subscription.getSubscriptionId();
    } catch (PortalException pe) {
      if (_log.isDebugEnabled()) {
        _log.debug(pe, pe);
      }
    }

    return 0;
  }
  @Override
  public MicroblogsEntry deleteMicroblogsEntry(MicroblogsEntry microblogsEntry)
      throws PortalException {

    // Microblogs entry

    microblogsEntryPersistence.remove(microblogsEntry);

    // Asset

    assetEntryLocalService.deleteEntry(
        MicroblogsEntry.class.getName(), microblogsEntry.getMicroblogsEntryId());

    // Social

    socialActivityLocalService.deleteActivities(
        MicroblogsEntry.class.getName(), microblogsEntry.getMicroblogsEntryId());

    return microblogsEntry;
  }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }

    if (!(obj instanceof MicroblogsEntry)) {
      return false;
    }

    MicroblogsEntry microblogsEntry = (MicroblogsEntry) obj;

    long primaryKey = microblogsEntry.getPrimaryKey();

    if (getPrimaryKey() == primaryKey) {
      return true;
    } else {
      return false;
    }
  }
  protected void sendNotificationEvent(MicroblogsEntry microblogsEntry)
      throws PortalException, SystemException {

    JSONObject notificationEventJSONObject = JSONFactoryUtil.createJSONObject();

    notificationEventJSONObject.put("body", microblogsEntry.getContent());
    notificationEventJSONObject.put("entryId", microblogsEntry.getMicroblogsEntryId());
    notificationEventJSONObject.put("entryKeyName", "receiverMicroblogsEntryId");
    notificationEventJSONObject.put("mvcPath", "/microblogs/view.jsp");
    notificationEventJSONObject.put("portletId", "1_WAR_microblogsportlet");
    notificationEventJSONObject.put("title", "x-commented-on-your-post");
    notificationEventJSONObject.put("userId", microblogsEntry.getUserId());

    NotificationEvent notificationEvent =
        NotificationEventFactoryUtil.createNotificationEvent(
            System.currentTimeMillis(), "6_WAR_soportlet", notificationEventJSONObject);

    notificationEvent.setDeliveryRequired(0);

    ChannelHubManagerUtil.sendNotificationEvent(
        microblogsEntry.getCompanyId(), microblogsEntry.getReceiverUserId(), notificationEvent);
  }
  public MicroblogsEntry updateMicroblogsEntry(
      long microblogsEntryId, String content, int socialRelationType, ServiceContext serviceContext)
      throws PortalException, SystemException {

    // Microblogs entry

    MicroblogsEntry microblogsEntry =
        microblogsEntryPersistence.findByPrimaryKey(microblogsEntryId);

    microblogsEntry.setModifiedDate(new Date());
    microblogsEntry.setContent(content);
    microblogsEntry.setSocialRelationType(socialRelationType);

    microblogsEntryPersistence.update(microblogsEntry);

    // Asset

    updateAsset(
        microblogsEntry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames());

    return microblogsEntry;
  }
  @Override
  protected String getTitle(
      JSONObject jsonObject, AssetRenderer<?> assetRenderer, ServiceContext serviceContext) {

    MicroblogsEntry microblogsEntry =
        _microblogsEntryLocalService.fetchMicroblogsEntry(assetRenderer.getClassPK());

    String title = StringPool.BLANK;

    String userFullName =
        HtmlUtil.escape(PortalUtil.getUserName(microblogsEntry.getUserId(), StringPool.BLANK));

    int notificationType = jsonObject.getInt("notificationType");

    if (notificationType == MicroblogsEntryConstants.NOTIFICATION_TYPE_REPLY) {

      title = serviceContext.translate("x-commented-on-your-post", userFullName);
    } else if (notificationType == MicroblogsEntryConstants.NOTIFICATION_TYPE_REPLY_TO_REPLIED) {

      long parentMicroblogsEntryUserId = microblogsEntry.fetchParentMicroblogsEntryUserId();

      User user = _userLocalService.fetchUser(parentMicroblogsEntryUserId);

      if (user != null) {
        title =
            serviceContext.translate(
                "x-also-commented-on-x's-post", userFullName, user.getFullName());
      }
    } else if (notificationType == MicroblogsEntryConstants.NOTIFICATION_TYPE_REPLY_TO_TAGGED) {

      title = serviceContext.translate("x-commented-on-a-post-you-are-tagged-in", userFullName);
    } else if (notificationType == MicroblogsEntryConstants.NOTIFICATION_TYPE_TAG) {

      title = serviceContext.translate("x-tagged-you-in-a-post", userFullName);
    }

    return title;
  }
  @Override
  public int compareTo(MicroblogsEntry microblogsEntry) {
    int value = 0;

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

    value = value * -1;

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

    return 0;
  }
  protected void subscribeUsers(MicroblogsEntry microblogsEntry, ServiceContext serviceContext)
      throws PortalException {

    long rootMicroblogsEntryId = MicroblogsUtil.getRootMicroblogsEntryId(microblogsEntry);

    subscriptionLocalService.addSubscription(
        microblogsEntry.getUserId(),
        serviceContext.getScopeGroupId(),
        MicroblogsEntry.class.getName(),
        rootMicroblogsEntryId);

    List<String> screenNames = MicroblogsUtil.getScreenNames(microblogsEntry.getContent());

    for (String screenName : screenNames) {
      long userId =
          userLocalService.getUserIdByScreenName(serviceContext.getCompanyId(), screenName);

      subscriptionLocalService.addSubscription(
          userId,
          serviceContext.getScopeGroupId(),
          MicroblogsEntry.class.getName(),
          rootMicroblogsEntryId);
    }
  }
  /**
   * Converts the soap model instance into a normal model instance.
   *
   * @param soapModel the soap model instance to convert
   * @return the normal model instance
   */
  public static MicroblogsEntry toModel(MicroblogsEntrySoap soapModel) {
    if (soapModel == null) {
      return null;
    }

    MicroblogsEntry model = new MicroblogsEntryImpl();

    model.setMicroblogsEntryId(soapModel.getMicroblogsEntryId());
    model.setCompanyId(soapModel.getCompanyId());
    model.setUserId(soapModel.getUserId());
    model.setUserName(soapModel.getUserName());
    model.setCreateDate(soapModel.getCreateDate());
    model.setModifiedDate(soapModel.getModifiedDate());
    model.setContent(soapModel.getContent());
    model.setType(soapModel.getType());
    model.setReceiverUserId(soapModel.getReceiverUserId());
    model.setReceiverMicroblogsEntryId(soapModel.getReceiverMicroblogsEntryId());
    model.setSocialRelationType(soapModel.getSocialRelationType());

    return model;
  }
  @Override
  public MicroblogsEntry addMicroblogsEntry(
      long userId,
      long creatorClassNameId,
      long creatorClassPK,
      String content,
      int type,
      long parentMicroblogsEntryId,
      int socialRelationType,
      ServiceContext serviceContext)
      throws PortalException {

    // Microblogs entry

    User user = userPersistence.findByPrimaryKey(userId);

    Date now = new Date();

    validate(type, parentMicroblogsEntryId);

    long microblogsEntryId = counterLocalService.increment();

    if (parentMicroblogsEntryId == 0) {
      parentMicroblogsEntryId = microblogsEntryId;
    }

    MicroblogsEntry microblogsEntry = microblogsEntryPersistence.create(microblogsEntryId);

    microblogsEntry.setCompanyId(user.getCompanyId());
    microblogsEntry.setUserId(user.getUserId());
    microblogsEntry.setUserName(user.getFullName());
    microblogsEntry.setCreateDate(now);
    microblogsEntry.setModifiedDate(now);
    microblogsEntry.setCreatorClassNameId(creatorClassNameId);
    microblogsEntry.setCreatorClassPK(creatorClassPK);
    microblogsEntry.setContent(content);
    microblogsEntry.setType(type);
    microblogsEntry.setParentMicroblogsEntryId(parentMicroblogsEntryId);
    microblogsEntry.setSocialRelationType(socialRelationType);

    microblogsEntryPersistence.update(microblogsEntry);

    // Resources

    resourceLocalService.addModelResources(microblogsEntry, serviceContext);

    // Asset

    updateAsset(
        microblogsEntry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames());

    return microblogsEntry;
  }
  @Override
  public MicroblogsEntry addMicroblogsEntry(
      long userId,
      String content,
      int type,
      long parentMicroblogsEntryId,
      int socialRelationType,
      ServiceContext serviceContext)
      throws PortalException {

    // Microblogs entry

    User user = userPersistence.findByPrimaryKey(userId);

    Date now = new Date();

    validate(type, parentMicroblogsEntryId);

    long microblogsEntryId = counterLocalService.increment();

    if (parentMicroblogsEntryId == 0) {
      parentMicroblogsEntryId = microblogsEntryId;
    }

    MicroblogsEntry microblogsEntry = microblogsEntryPersistence.create(microblogsEntryId);

    microblogsEntry.setCompanyId(user.getCompanyId());
    microblogsEntry.setUserId(user.getUserId());
    microblogsEntry.setUserName(user.getFullName());
    microblogsEntry.setCreateDate(now);
    microblogsEntry.setModifiedDate(now);
    microblogsEntry.setCreatorClassNameId(classNameLocalService.getClassNameId(User.class));
    microblogsEntry.setCreatorClassPK(user.getUserId());
    microblogsEntry.setContent(content);
    microblogsEntry.setType(type);
    microblogsEntry.setParentMicroblogsEntryId(parentMicroblogsEntryId);
    microblogsEntry.setSocialRelationType(socialRelationType);

    microblogsEntryPersistence.update(microblogsEntry);

    // Resources

    resourceLocalService.addModelResources(microblogsEntry, serviceContext);

    // Asset

    updateAsset(
        microblogsEntry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames());

    // Social

    int activityKey = MicroblogsActivityKeys.ADD_ENTRY;

    if (type == MicroblogsEntryConstants.TYPE_REPLY) {
      activityKey = MicroblogsActivityKeys.REPLY_ENTRY;
    } else if (type == MicroblogsEntryConstants.TYPE_REPOST) {
      activityKey = MicroblogsActivityKeys.REPOST_ENTRY;
    }

    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();

    extraDataJSONObject.put("content", microblogsEntry.getContent());
    extraDataJSONObject.put("parentMicroblogsEntryId", parentMicroblogsEntryId);

    socialActivityLocalService.addActivity(
        userId,
        0,
        MicroblogsEntry.class.getName(),
        microblogsEntryId,
        activityKey,
        extraDataJSONObject.toString(),
        microblogsEntry.getParentMicroblogsEntryUserId());

    // Notification

    subscribeUsers(microblogsEntry, serviceContext);

    sendNotificationEvent(microblogsEntry, serviceContext);

    return microblogsEntry;
  }