protected void updateKBArticleAttachments(
      KBArticle kbArticle, int oldVersion, String dirName, ServiceContext serviceContext)
      throws PortalException, SystemException {

    if (kbArticle.getVersion() > oldVersion) {
      String oldDirName = KBArticleConstants.DIR_NAME_PREFIX + kbArticle.getResourcePrimKey();

      if (Validator.isNull(dirName)) {
        addKBArticleAttachments(kbArticle, oldDirName, serviceContext);
      } else {
        addKBArticleAttachments(kbArticle, dirName, serviceContext);
      }
    } else if (Validator.isNotNull(dirName)) {
      deleteKBArticleAttachments(kbArticle, kbArticle.getClassPK());

      addKBArticleAttachments(kbArticle, dirName, serviceContext);
    }
  }
  protected Map<String, String> getEmailKBArticleDiffs(KBArticle kbArticle) {
    Map<String, String> emailKBArticleDiffs = new HashMap<String, String>();

    for (String param : new String[] {"content", "title"}) {
      String value = BeanPropertiesUtil.getString(kbArticle, param);

      try {
        value =
            AdminUtil.getKBArticleDiff(
                kbArticle.getResourcePrimKey(),
                kbArticle.getVersion() - 1,
                kbArticle.getVersion(),
                param);
      } catch (Exception e) {
        _log.error(e, e);
      }

      emailKBArticleDiffs.put(param, value);
    }

    return emailKBArticleDiffs;
  }
  public KBArticle updateStatus(
      long userId, long resourcePrimKey, int status, ServiceContext serviceContext)
      throws PortalException, SystemException {

    // KB article

    User user = userPersistence.findByPrimaryKey(userId);
    boolean main = false;
    Date now = new Date();

    if (status == WorkflowConstants.STATUS_APPROVED) {
      main = true;
    }

    KBArticle kbArticle = getLatestKBArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);

    kbArticle.setModifiedDate(serviceContext.getModifiedDate(now));
    kbArticle.setMain(main);
    kbArticle.setStatus(status);
    kbArticle.setStatusByUserId(user.getUserId());
    kbArticle.setStatusByUserName(user.getFullName());
    kbArticle.setStatusDate(serviceContext.getModifiedDate(now));

    kbArticlePersistence.update(kbArticle, false);

    if (status != WorkflowConstants.STATUS_APPROVED) {
      return kbArticle;
    }

    if (!kbArticle.isFirstVersion()) {
      KBArticle oldKBArticle =
          kbArticlePersistence.findByR_V(resourcePrimKey, kbArticle.getVersion() - 1);

      oldKBArticle.setMain(false);

      kbArticlePersistence.update(oldKBArticle, false);
    }

    // Asset

    AssetEntry assetEntry =
        assetEntryLocalService.getEntry(KBArticle.class.getName(), kbArticle.getKbArticleId());

    updateKBArticleAsset(userId, kbArticle, assetEntry.getCategoryIds(), assetEntry.getTagNames());

    assetEntryLocalService.deleteEntry(KBArticle.class.getName(), kbArticle.getKbArticleId());

    assetEntryLocalService.updateVisible(
        KBArticle.class.getName(), kbArticle.getResourcePrimKey(), true);

    // Social

    if (!kbArticle.isFirstVersion()) {
      socialActivityLocalService.addActivity(
          userId,
          kbArticle.getGroupId(),
          KBArticle.class.getName(),
          resourcePrimKey,
          AdminActivityKeys.UPDATE_KB_ARTICLE,
          StringPool.BLANK,
          0);
    } else {
      socialActivityLocalService.addActivity(
          userId,
          kbArticle.getGroupId(),
          KBArticle.class.getName(),
          resourcePrimKey,
          AdminActivityKeys.ADD_KB_ARTICLE,
          StringPool.BLANK,
          0);
    }

    // Indexer

    Indexer indexer = IndexerRegistryUtil.getIndexer(KBArticle.class);

    indexer.reindex(kbArticle);

    // Attachments

    if (!kbArticle.isFirstVersion()) {
      deleteKBArticleAttachments(kbArticle, resourcePrimKey);
    }

    String dirName = KBArticleConstants.DIR_NAME_PREFIX + kbArticle.getKbArticleId();

    addKBArticleAttachments(kbArticle, dirName, serviceContext);

    deleteKBArticleAttachments(kbArticle, kbArticle.getKbArticleId());

    // Subscriptions

    notifySubscribers(kbArticle, serviceContext);

    return kbArticle;
  }
  public KBArticle updateKBArticle(
      long userId,
      long resourcePrimKey,
      String title,
      String content,
      String description,
      String[] sections,
      String dirName,
      ServiceContext serviceContext)
      throws PortalException, SystemException {

    // KB article

    User user = userPersistence.findByPrimaryKey(userId);
    int version = KBArticleConstants.DEFAULT_VERSION;
    int status = WorkflowConstants.STATUS_DRAFT;

    validate(title, content);

    KBArticle oldKBArticle = getLatestKBArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);

    long oldResourcePrimKey = oldKBArticle.getResourcePrimKey();
    long oldGroupId = oldKBArticle.getGroupId();
    Date oldCreateDate = oldKBArticle.getCreateDate();
    long oldRootResourcePrimKey = oldKBArticle.getRootResourcePrimKey();
    long oldParentResourcePrimKey = oldKBArticle.getParentResourcePrimKey();
    int oldVersion = oldKBArticle.getVersion();
    double oldPriority = oldKBArticle.getPriority();
    int oldViewCount = oldKBArticle.getViewCount();
    int oldStatus = oldKBArticle.getStatus();

    KBArticle kbArticle = null;

    if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
      long kbArticleId = counterLocalService.increment();

      kbArticle = kbArticlePersistence.create(kbArticleId);
      version = oldVersion + 1;
    } else {
      kbArticle = oldKBArticle;
      version = oldVersion;
    }

    if (oldStatus == WorkflowConstants.STATUS_PENDING) {
      status = WorkflowConstants.STATUS_PENDING;
    }

    kbArticle.setResourcePrimKey(oldResourcePrimKey);
    kbArticle.setGroupId(oldGroupId);
    kbArticle.setCompanyId(user.getCompanyId());
    kbArticle.setUserId(user.getUserId());
    kbArticle.setUserName(user.getFullName());
    kbArticle.setCreateDate(oldCreateDate);
    kbArticle.setModifiedDate(serviceContext.getModifiedDate(null));
    kbArticle.setRootResourcePrimKey(oldRootResourcePrimKey);
    kbArticle.setParentResourcePrimKey(oldParentResourcePrimKey);
    kbArticle.setVersion(version);
    kbArticle.setTitle(title);
    kbArticle.setContent(content);
    kbArticle.setDescription(description);
    kbArticle.setPriority(oldPriority);
    kbArticle.setSections(StringUtil.merge(AdminUtil.escapeSections(sections)));
    kbArticle.setViewCount(oldViewCount);
    kbArticle.setLatest(true);
    kbArticle.setMain(false);
    kbArticle.setStatus(status);

    kbArticlePersistence.update(kbArticle, false);

    if (oldVersion < version) {
      oldKBArticle.setLatest(false);

      kbArticlePersistence.update(oldKBArticle, false);
    }

    // Resources

    if ((serviceContext.getGroupPermissions() != null)
        || (serviceContext.getGuestPermissions() != null)) {

      updateKBArticleResources(
          kbArticle, serviceContext.getGroupPermissions(), serviceContext.getGuestPermissions());
    }

    // Asset

    updateKBArticleAsset(
        userId, kbArticle, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames());

    // Attachments

    updateKBArticleAttachments(kbArticle, oldVersion, dirName, serviceContext);

    // Workflow

    WorkflowHandlerRegistryUtil.startWorkflowInstance(
        user.getCompanyId(),
        kbArticle.getGroupId(),
        userId,
        KBArticle.class.getName(),
        resourcePrimKey,
        kbArticle,
        serviceContext);

    return kbArticle;
  }
  @Override
  protected void doImportStagedModel(PortletDataContext portletDataContext, KBArticle kbArticle)
      throws Exception {

    long userId = portletDataContext.getUserId(kbArticle.getUserUuid());

    if (kbArticle.getParentResourcePrimKey() != KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

      if (kbArticle.getClassNameId() == kbArticle.getParentResourceClassNameId()) {

        StagedModelDataHandlerUtil.importReferenceStagedModels(
            portletDataContext, kbArticle, KBArticle.class);
      } else {
        StagedModelDataHandlerUtil.importReferenceStagedModels(
            portletDataContext, kbArticle, KBFolder.class);
      }
    }

    Map<Long, Long> kbArticleResourcePrimKeys =
        (Map<Long, Long>) portletDataContext.getNewPrimaryKeysMap(KBArticle.class);

    long parentResourcePrimKey =
        MapUtil.getLong(
            kbArticleResourcePrimKeys,
            kbArticle.getParentResourcePrimKey(),
            KBFolderConstants.DEFAULT_PARENT_FOLDER_ID);

    long resourcePrimaryKey =
        MapUtil.getLong(kbArticleResourcePrimKeys, kbArticle.getResourcePrimKey(), 0);

    if (parentResourcePrimKey == KBFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

      Map<Long, Long> kbFolderResourcePrimKeys =
          (Map<Long, Long>) portletDataContext.getNewPrimaryKeysMap(KBFolder.class);

      parentResourcePrimKey =
          MapUtil.getLong(
              kbFolderResourcePrimKeys,
              kbArticle.getParentResourcePrimKey(),
              KBFolderConstants.DEFAULT_PARENT_FOLDER_ID);
    }

    String[] sections = AdminUtil.unescapeSections(kbArticle.getSections());

    ServiceContext serviceContext = portletDataContext.createServiceContext(kbArticle);

    KBArticle importedKBArticle = null;

    if (portletDataContext.isDataStrategyMirror()) {
      KBArticle existingKBArticle =
          KBArticleUtil.fetchByR_V(resourcePrimaryKey, kbArticle.getVersion());

      if (existingKBArticle == null) {
        existingKBArticle =
            fetchStagedModelByUuidAndGroupId(
                kbArticle.getUuid(), portletDataContext.getScopeGroupId());
      }

      if (existingKBArticle == null) {
        serviceContext.setUuid(kbArticle.getUuid());

        existingKBArticle =
            KBArticleLocalServiceUtil.fetchLatestKBArticle(
                resourcePrimaryKey, WorkflowConstants.STATUS_ANY);

        if (existingKBArticle == null) {
          importedKBArticle =
              KBArticleLocalServiceUtil.addKBArticle(
                  userId,
                  kbArticle.getParentResourceClassNameId(),
                  parentResourcePrimKey,
                  kbArticle.getTitle(),
                  kbArticle.getUrlTitle(),
                  kbArticle.getContent(),
                  kbArticle.getDescription(),
                  kbArticle.getSourceURL(),
                  sections,
                  null,
                  serviceContext);

          KBArticleLocalServiceUtil.updatePriority(
              importedKBArticle.getResourcePrimKey(), kbArticle.getPriority());
        } else {
          KBArticleLocalServiceUtil.updateKBArticle(
              userId,
              existingKBArticle.getResourcePrimKey(),
              kbArticle.getTitle(),
              kbArticle.getContent(),
              kbArticle.getDescription(),
              kbArticle.getSourceURL(),
              sections,
              null,
              null,
              serviceContext);

          KBArticleLocalServiceUtil.moveKBArticle(
              userId,
              existingKBArticle.getResourcePrimKey(),
              existingKBArticle.getParentResourceClassNameId(),
              parentResourcePrimKey,
              kbArticle.getPriority());

          importedKBArticle =
              KBArticleLocalServiceUtil.getLatestKBArticle(
                  existingKBArticle.getResourcePrimKey(), WorkflowConstants.STATUS_APPROVED);
        }
      } else {
        importedKBArticle = existingKBArticle;
      }
    } else {
      importedKBArticle =
          KBArticleLocalServiceUtil.addKBArticle(
              userId,
              kbArticle.getParentResourceClassNameId(),
              parentResourcePrimKey,
              kbArticle.getTitle(),
              kbArticle.getUrlTitle(),
              kbArticle.getContent(),
              kbArticle.getDescription(),
              kbArticle.getSourceURL(),
              sections,
              null,
              serviceContext);

      KBArticleLocalServiceUtil.updatePriority(
          importedKBArticle.getResourcePrimKey(), kbArticle.getPriority());
    }

    importKBArticleAttachments(portletDataContext, kbArticle, importedKBArticle);

    portletDataContext.importClassedModel(kbArticle, importedKBArticle);

    if (!kbArticle.isMain()) {
      kbArticleResourcePrimKeys.put(
          kbArticle.getResourcePrimKey(), importedKBArticle.getResourcePrimKey());
    }
  }