Package ru.org.linux.comment

Source Code of ru.org.linux.comment.CommentService$CommentAndDepth

/*
* Copyright 1998-2014 Linux.org.ru
*    Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*        http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*/

package ru.org.linux.comment;

import com.google.common.base.Preconditions;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.xbill.DNS.TextParseException;
import ru.org.linux.auth.CaptchaService;
import ru.org.linux.auth.FloodProtector;
import ru.org.linux.auth.IPBlockDao;
import ru.org.linux.auth.IPBlockInfo;
import ru.org.linux.csrf.CSRFProtectionService;
import ru.org.linux.edithistory.EditHistoryDto;
import ru.org.linux.edithistory.EditHistoryObjectTypeEnum;
import ru.org.linux.edithistory.EditHistoryService;
import ru.org.linux.site.MessageNotFoundException;
import ru.org.linux.site.ScriptErrorException;
import ru.org.linux.site.Template;
import ru.org.linux.spring.dao.DeleteInfoDao;
import ru.org.linux.spring.dao.MessageText;
import ru.org.linux.spring.dao.MsgbaseDao;
import ru.org.linux.topic.Topic;
import ru.org.linux.topic.TopicDao;
import ru.org.linux.topic.TopicPermissionService;
import ru.org.linux.topic.TopicService;
import ru.org.linux.user.*;
import ru.org.linux.util.ExceptionBindingErrorProcessor;
import ru.org.linux.util.StringUtil;
import ru.org.linux.util.bbcode.LorCodeService;
import ru.org.linux.util.formatter.ToLorCodeFormatter;
import ru.org.linux.util.formatter.ToLorCodeTexFormatter;

import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyEditorSupport;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;

@Service
public class CommentService {
  private static final Logger logger = LoggerFactory.getLogger(CommentService.class);

  @Autowired
  private CommentDao commentDao;

  @Autowired
  private TopicDao messageDao;

  @Autowired
  private TopicService topicService;

  @Autowired
  private UserDao userDao;

  @Autowired
  private ToLorCodeFormatter toLorCodeFormatter;

  @Autowired
  private ToLorCodeTexFormatter toLorCodeTexFormatter;

  @Autowired
  private CaptchaService captcha;

  @Autowired
  private CommentPrepareService commentPrepareService;

  @Autowired
  private FloodProtector floodProtector;

  @Autowired
  private LorCodeService lorCodeService;

  @Autowired
  private UserEventService userEventService;

  @Autowired
  private MsgbaseDao msgbaseDao;

  @Autowired
  private IgnoreListDao ignoreListDao;

  @Autowired
  private EditHistoryService editHistoryService;

  @Autowired
  private TopicDao topicDao;

  @Autowired
  private DeleteInfoDao deleteInfoDao;

  @Autowired
  private TopicPermissionService permissionService;

  private final Cache<Integer, CommentList> cache =
          CacheBuilder.newBuilder()
          .maximumSize(10000)
          .build();

  public void requestValidator(WebDataBinder binder) {
    binder.setValidator(new CommentRequestValidator(lorCodeService));
    binder.setBindingErrorProcessor(new ExceptionBindingErrorProcessor());
  }

  public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Topic.class, new PropertyEditorSupport() {
      @Override
      public void setAsText(String text) throws IllegalArgumentException {
        try {
          setValue(messageDao.getById(Integer.parseInt(text.split(",")[0])));
        } catch (MessageNotFoundException e) {
          throw new IllegalArgumentException(e);
        }
      }
    });

    binder.registerCustomEditor(Comment.class, new PropertyEditorSupport() {
      @Override
      public void setAsText(String text) throws IllegalArgumentException {
        if (text.isEmpty() || "0".equals(text)) {
          setValue(null);
          return;
        }

        try {
          setValue(commentDao.getById(Integer.parseInt(text)));
        } catch (MessageNotFoundException e) {
          throw new IllegalArgumentException(e);
        }
      }
    });

    binder.registerCustomEditor(User.class, new UserPropertyEditor(userDao));
  }

  /**
   * Проверка валидности данных запроса.
   *
   * @param commentRequest  WEB-форма, содержащая данные
   * @param user            пользователь, добавляющий или изменяющий комментарий
   * @param ipBlockInfo     информация о банах
   * @param request         данные запроса от web-клиента
   * @param errors          обработчик ошибок ввода для формы
   * @throws UnknownHostException
   * @throws TextParseException
   */
  public void checkPostData(
    CommentRequest commentRequest,
    User user,
    IPBlockInfo ipBlockInfo,
    HttpServletRequest request,
    Errors errors
  ) throws
    UnknownHostException,
    TextParseException {
    if (commentRequest.getMsg() == null) {
      errors.rejectValue("msg", null, "комментарий не задан");
      commentRequest.setMsg("");
    }

    Template tmpl = Template.getTemplate(request);

    if (commentRequest.getMode() == null) {
      commentRequest.setMode(tmpl.getFormatMode());
    }

    if (!commentRequest.isPreviewMode() &&
      (!tmpl.isSessionAuthorized() || ipBlockInfo.isCaptchaRequired())) {
      captcha.checkCaptcha(request, errors);
    }

    if (!commentRequest.isPreviewMode() && !errors.hasErrors()) {
      CSRFProtectionService.checkCSRF(request, errors);
    }

    user.checkBlocked(errors);

    IPBlockDao.checkBlockIP(ipBlockInfo, errors, user);

    if (!commentRequest.isPreviewMode() && !errors.hasErrors()) {
      floodProtector.checkDuplication(FloodProtector.Action.ADD_COMMENT, request.getRemoteAddr(), user.getScore() >= 100, errors);
    }
  }

  /**
   * Получить текст комментария.
   *
   * @param commentRequest  WEB-форма, содержащая данные
   * @param user            пользователь, добавляющий или изменяющий комментарий
   * @param errors          обработчик ошибок ввода для формы
   * @return текст комментария
   */
  public String getCommentBody(
    CommentRequest commentRequest,
    User user,
    Errors errors
  ) {
    String commentBody = processMessage(commentRequest.getMsg(), commentRequest.getMode());
    if (user.isAnonymous()) {
      if (commentBody.length() > 4096) {
        errors.rejectValue("msg", null, "Слишком большое сообщение");
      }
    } else {
      if (commentBody.length() > 8192) {
        errors.rejectValue("msg", null, "Слишком большое сообщение");
      }
    }
    return commentBody;
  }

  /**
   * Получить объект комментария из WEB-запроса.
   *
   * @param commentRequest  WEB-форма, содержащая данные
   * @param user            пользователь, добавляющий или изменяющий комментарий
   * @param request         данные запроса от web-клиента
   * @return объект комментария из WEB-запроса
   */
  public Comment getComment(
    CommentRequest commentRequest,
    User user,
    HttpServletRequest request
  ) {
    Comment comment = null;

    if (commentRequest.getTopic() != null) {

      String title = commentRequest.getTitle();

      if (title == null) {
        title = "";
      }

      Integer replyto = commentRequest.getReplyto() != null ? commentRequest.getReplyto().getId() : null;

      int commentId = commentRequest.getOriginal() == null
        ? 0
        : commentRequest.getOriginal().getId();

      comment = new Comment(
        replyto,
        StringUtil.escapeHtml(title),
        commentRequest.getTopic().getId(),
        commentId,
        user.getId(),
        request.getRemoteAddr()
      );
    }
    return comment;
  }

  /**
   * Получить объект пользователя, добавляющего или изменяющего комментарий
   *
   * @param commentRequest  WEB-форма, содержащая данные
   * @param request         данные запроса от web-клиента
   * @param errors          обработчик ошибок ввода для формы
   * @return объект пользователя
   */
  @Nonnull
  public User getCommentUser(
    CommentRequest commentRequest,
    HttpServletRequest request,
    Errors errors
  ) {
    Template tmpl = Template.getTemplate(request);

    User currentUser = tmpl.getCurrentUser();

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

    if (commentRequest.getNick() != null) {
      if (commentRequest.getPassword() == null) {
        errors.reject(null, "Требуется авторизация");
      }

      return commentRequest.getNick();
    } else {
      return userDao.getAnonymous();
    }
  }

  public void prepareReplyto(
    CommentRequest add,
    Map<String, Object> formParams,
    HttpServletRequest request
  ) throws UserNotFoundException {
    if (add.getReplyto() != null) {
      formParams.put("onComment", commentPrepareService.prepareCommentForReplayto(add.getReplyto(), request.isSecure()));
    }
  }

  /**
   * Создание нового комментария.
   *
   *
   * @param comment        объект комментария
   * @param commentBody    текст комментария
   * @param remoteAddress  IP-адрес, с которого был добавлен комментарий
   * @param xForwardedFor  IP-адрес через шлюз, с которого был добавлен комментарий
   * @param userAgent      заголовок User-Agent запроса
   * @return идентификационный номер нового комментария
   * @throws MessageNotFoundException
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  public int create(
          @Nonnull User author,
          @Nonnull Comment comment,
          String commentBody,
          String remoteAddress,
          String xForwardedFor,
          String userAgent) throws MessageNotFoundException {
    Preconditions.checkArgument(comment.getUserid() == author.getId());

    int commentId = commentDao.saveNewMessage(comment, userAgent);
    msgbaseDao.saveNewMessage(commentBody, commentId);

    /* кастование пользователей */
    if (permissionService.isUserCastAllowed(author)) {
      Set<User> userRefs = lorCodeService.getReplierFromMessage(commentBody);
      userEventService.addUserRefEvent(userRefs, comment.getTopicId(), commentId);
    }

    /* оповещение об ответе на коммент */
    if (comment.getReplyTo() != 0) {
      Comment parentComment = commentDao.getById(comment.getReplyTo());

      if (parentComment.getUserid() != comment.getUserid()) {
        User parentAuthor = userDao.getUserCached(parentComment.getUserid());

        if (!parentAuthor.isAnonymous()) {
          Set<Integer> ignoreList = ignoreListDao.get(parentAuthor);

          if (!ignoreList.contains(comment.getUserid())) {
            userEventService.addReplyEvent(
                    parentAuthor,
                    comment.getTopicId(),
                    commentId
            );
          }
        }
      }
    }

    String logMessage = makeLogString("Написан комментарий " + commentId, remoteAddress, xForwardedFor);
    logger.info(logMessage);

    return commentId;
  }

  /**
   * Редактирование комментария.
   *
   * @param oldComment     данные старого комментария
   * @param newComment     данные нового комментария
   * @param commentBody    текст нового комментария
   * @param remoteAddress  IP-адрес, с которого был добавлен комментарий
   * @param xForwardedFor  IP-адрес через шлюз, с которого был добавлен комментарий
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  public void edit(
    Comment oldComment,
    Comment newComment,
    String commentBody,
    String remoteAddress,
    String xForwardedFor,
    @Nonnull User editor,
    String originalMessageText
  ) {
    commentDao.changeTitle(oldComment, newComment.getTitle());
    msgbaseDao.updateMessage(oldComment.getId(), commentBody);

    /* кастование пользователей */
    Set<User> newUserRefs = lorCodeService.getReplierFromMessage(commentBody);

    MessageText messageText = msgbaseDao.getMessageText(oldComment.getId());
    Set<User> oldUserRefs = lorCodeService.getReplierFromMessage(messageText.getText());
    Set<User> userRefs = new HashSet<>();
    /* кастовать только тех, кто добавился. Существующие ранее не кастуются */
    for (User user : newUserRefs) {
      if (!oldUserRefs.contains(user)) {
        userRefs.add(user);
      }
    }

    if (permissionService.isUserCastAllowed(editor)) {
      userEventService.addUserRefEvent(userRefs, oldComment.getTopicId(), oldComment.getId());
    }

    /* Обновление времени последнего изменения топика для того, чтобы данные в кеше автоматически обновились  */
    topicDao.updateLastmod(oldComment.getTopicId(), false);

    addEditHistoryItem(editor, oldComment, originalMessageText, newComment, commentBody);

    updateLatestEditorInfo(editor, oldComment, newComment);

    String logMessage = makeLogString("Изменён комментарий " + oldComment.getId(), remoteAddress, xForwardedFor);
    logger.info(logMessage);
  }

  /**
   * Проверка, имеет ли указанный комментарий ответы.
   *
   * @param comment  объект комментария
   * @return true если есть ответы, иначе false
   */
  public boolean isHaveAnswers(@Nonnull Comment comment) {
    return commentDao.getReplaysCount(comment.getId())>0;
  }

  /**
   * Получить объект комментария по идентификационному номеру
   *
   * @param id идентификационный номер комментария
   * @return объект комментария
   * @throws MessageNotFoundException если комментарий не найден
   */
  public Comment getById(int id) throws MessageNotFoundException {
    return commentDao.getById(id);
  }

  /**
   * Добавить элемент истории для комментария.
   *
   * @param editor              пользователь, изменивший комментарий
   * @param original            оригинал (старый комментарий)
   * @param originalMessageText старое содержимое комментария
   * @param comment             изменённый комментарий
   * @param messageText         новое содержимое комментария
   */
  private void addEditHistoryItem(User editor, Comment original, String originalMessageText, Comment comment, String messageText) {
    EditHistoryDto editHistoryDto = new EditHistoryDto();
    editHistoryDto.setMsgid(original.getId());
    editHistoryDto.setObjectType(EditHistoryObjectTypeEnum.COMMENT);
    editHistoryDto.setEditor(editor.getId());

    boolean modified = false;
    if (!original.getTitle().equals(comment.getTitle())) {
      editHistoryDto.setOldtitle(original.getTitle());
      modified = true;
    }

    if (!originalMessageText.equals(messageText)) {
      editHistoryDto.setOldmessage(originalMessageText);
      modified = true;
    }

    if (modified) {
      editHistoryService.insert(editHistoryDto);
    }

  }

  /**
   * Обновление информации о последнем изменении коммента.
   *
   * @param editor   пользователь, изменивший комментарий
   * @param original оригинал (старый комментарий)
   * @param comment  изменённый комментарий
   */
  private void updateLatestEditorInfo(User editor, Comment original, Comment comment) {
    int editCount = editHistoryService.editCount(original.getId(), EditHistoryObjectTypeEnum.COMMENT);

    commentDao.updateLatestEditorInfo(
      original.getId(),
      editor.getId(),
      comment.getPostdate(),
      editCount
    );
  }

  /**
   * Удаляем коментарий, если на комментарий есть ответы - генерируем исключение
   *
   * @param msgid      id удаляемого сообщения
   * @param reason     причина удаления
   * @param user       модератор который удаляет
   * @throws ScriptErrorException генерируем исключение если на комментарий есть ответы
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  public boolean deleteComment(int msgid, String reason, User user) throws ScriptErrorException {
    if (commentDao.getReplaysCount(msgid) != 0) {
      throw new ScriptErrorException("Нельзя удалить комментарий с ответами");
    }

    boolean deleted = doDeleteComment(msgid, reason, user);

    if (deleted) {
      commentDao.updateStatsAfterDelete(msgid, 1);
      userEventService.processCommentsDeleted(ImmutableList.of(msgid));
    }

    return deleted;
  }

  /**
   * Удалить комментарий.
   *
   * @param msgid      идентификационнай номер комментария
   * @param reason     причина удаления
   * @param user       пользователь, удаляющий комментарий
   * @return true если комментарий был удалён, иначе false
   */
  private boolean doDeleteComment(int msgid, String reason, User user) {
    boolean deleted = commentDao.deleteComment(msgid, reason, user);

    if (deleted) {
      deleteInfoDao.insert(msgid, user, reason, 0);
    }

    return deleted;
  }

  /**
   * Удалить комментарий.
   *
   * @param comment    удаляемый комментарий
   * @param reason     причина удаления
   * @param user       пользователь, удаляющий комментарий
   * @param scoreBonus сколько снять скора у автора комментария
   * @return true если комментарий был удалён, иначе false
   */
  private boolean deleteComment(Comment comment, String reason, User user, int scoreBonus) {
    Preconditions.checkArgument(scoreBonus<=0, "Score bonus on delete must be non-positive");

    boolean del = commentDao.deleteComment(comment.getId(), reason, user);

    if (del && scoreBonus!=0) {
      userDao.changeScore(comment.getUserid(), scoreBonus);
    }

    return del;
  }

  /**
   * Список комментариев топика.
   *
   * @param topic       топик
   * @param showDeleted вместе с удаленными
   * @return список комментариев топика
   */
  @Nonnull
  public CommentList getCommentList(@Nonnull Topic topic, boolean showDeleted) {
    if (showDeleted) {
      return new CommentList(commentDao.getCommentList(topic.getId(), true), topic.getLastModified().getTime());
    } else {
      CommentList commentList = cache.getIfPresent(topic.getId());

      if (commentList == null || commentList.getLastmod() < topic.getLastModified().getTime()) {
        commentList = new CommentList(commentDao.getCommentList(topic.getId(), false), topic.getLastModified().getTime());
        cache.put(topic.getId(), commentList);
      }

      return commentList;
    }
  }

  /**
   * Удаление ответов на комментарии.
   *
   * @param comment удаляемый комментарий
   * @param user   пользователь, удаляющий комментарий
   * @param scoreBonus  сколько снять скора у автора комментария
   * @return список идентификационных номеров удалённых комментариев
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  public List<Integer> deleteWithReplys(Topic topic, Comment comment, String reason, User user, int scoreBonus) {
    CommentList commentList = getCommentList(topic, false);

    CommentNode node = commentList.getNode(comment.getId());

    List<CommentAndDepth> replys = getAllReplys(node, 0);

    List<Integer> deleted = deleteReplys(comment, reason, replys, user, -scoreBonus);

    userEventService.processCommentsDeleted(deleted);

    return deleted;
  }

  /**
     * Удалить рекурсивно ответы на комментарий
     *
     * @param replys список ответов
     * @param user  пользователь, удаляющий комментарий
     * @param rootBonus сколько снять скора у автора корневого комментария
     * @return список идентификационных номеров удалённых комментариев
     */
  private List<Integer> deleteReplys(Comment root, String rootReason, List<CommentAndDepth> replys, User user, int rootBonus) {
    boolean score = rootBonus < -2;

    List<Integer> deleted = new ArrayList<>(replys.size());
    List<DeleteInfoDao.InsertDeleteInfo> deleteInfos = new ArrayList<>(replys.size());

    for (CommentAndDepth cur : replys) {
      Comment child = cur.getComment();

      DeleteInfoDao.InsertDeleteInfo info = cur.deleteInfo(score, user);

      boolean del = deleteComment(child, info.getReason(), user, info.getBonus());

      if (del) {
        deleteInfos.add(info);
        deleted.add(child.getId());
      }
    }

    boolean deletedMain = deleteComment(root, rootReason, user, rootBonus);

    if (deletedMain) {
      deleteInfos.add(new DeleteInfoDao.InsertDeleteInfo(root.getId(), rootReason, rootBonus, user.getId()));
      deleted.add(root.getId());
    }

    deleteInfoDao.insert(deleteInfos);

    if (!deleted.isEmpty()) {
      commentDao.updateStatsAfterDelete(root.getId(), deleted.size());
    }

    return deleted;
  }

  /**
   * Удаление топиков, сообщений по ip и за определнный период времени, те комментарии на которые существуют ответы пропускаем
   *
   * @param ip        ip для которых удаляем сообщения (не проверяется на корректность)
   * @param timeDelta врменной промежуток удаления (не проверяется на корректность)
   * @param moderator экзекутор-можератор
   * @param reason    причина удаления, которая будет вписана для удаляемых топиков
   * @return список id удаленных сообщений
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  public DeleteCommentResult deleteCommentsByIPAddress(
    String ip,
    Timestamp timeDelta,
    final User moderator,
    final String reason)
  {
    List<Integer> deletedTopics = topicService.deleteByIPAddress(ip, timeDelta, moderator, reason);

    Map<Integer, String> deleteInfo = new HashMap<>();

    for (int msgid : deletedTopics) {
      deleteInfo.put(msgid, "Топик " + msgid + " удален");
    }

    // Удаляем комментарии если на них нет ответа
    List<Integer> commentIds = commentDao.getCommentsByIPAddressForUpdate(ip, timeDelta);

    List<Integer> deletedCommentIds = new ArrayList<>();

    for (int msgid : commentIds) {
      if (commentDao.getReplaysCount(msgid) == 0) {
        if (doDeleteComment(msgid, reason, moderator)) {
          deletedCommentIds.add(msgid);
          deleteInfo.put(msgid, "Комментарий " + msgid + " удален");
        } else {
          deleteInfo.put(msgid, "Комментарий " + msgid + " уже был удален");
        }
      } else {
        deleteInfo.put(msgid, "Комментарий " + msgid + " пропущен");
      }
    }

    for (int msgid : deletedCommentIds) {
      commentDao.updateStatsAfterDelete(msgid, 1);
    }

    userEventService.processCommentsDeleted(deletedCommentIds);

    return new DeleteCommentResult(deletedTopics, deletedCommentIds, deleteInfo);
  }

  /**
   * Получить список последних удалённых комментариев пользователя.
   *
   * @param user  объект пользователя
   * @return список удалённых комментариев пользователя
   */
  public List<CommentDao.DeletedListItem> getDeletedComments(User user) {
    return commentDao.getDeletedComments(user.getId());
  }

  /**
   * Блокировка и массивное удаление всех топиков и комментариев пользователя со всеми ответами на комментарии
   *
   * @param user      пользователь для экзекуции
   * @param moderator экзекутор-модератор
   * @param reason    прична блокировки
   * @return список удаленных комментариев
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  public DeleteCommentResult deleteAllCommentsAndBlock(User user, final User moderator, String reason) {
    userDao.block(user, moderator, reason);

    List<Integer> deletedTopicIds = topicService.deleteAllByUser(user, moderator);

    List<Integer> deletedCommentIds = deleteAllCommentsByUser(user, moderator);

    return new DeleteCommentResult(deletedTopicIds, deletedCommentIds, null);
  }

  /**
     * Массовое удаление комментариев пользователя со всеми ответами на комментарии.
     *
     * @param user      пользователь для экзекуции
     * @param moderator экзекутор-модератор
     * @return список удаленных комментариев
     */
  private List<Integer> deleteAllCommentsByUser(User user, final User moderator) {
    final List<Integer> deletedCommentIds = new ArrayList<>();

    // Удаляем все комментарии
    List<Integer> commentIds = commentDao.getAllByUserForUpdate(user);

    for (int msgid : commentIds) {
      if (commentDao.getReplaysCount(msgid) == 0) {
        doDeleteComment(msgid, "Блокировка пользователя с удалением сообщений", moderator);
        commentDao.updateStatsAfterDelete(msgid, 1);
        deletedCommentIds.add(msgid);
      }
    }

    userEventService.processCommentsDeleted(deletedCommentIds);

    return deletedCommentIds;
  }

  /**
   * Формирование строки в лог-файл.
   *
   * @param message        сообщение
   * @param remoteAddress  IP-адрес, с которого был добавлен комментарий
   * @param xForwardedFor  IP-адрес через шлюз, с которого был добавлен комментарий
   * @return строка, готовая для добавления в лог-файл
   */
  private static String makeLogString(String message, String remoteAddress, String xForwardedFor) {
    StringBuilder logMessage = new StringBuilder();

    logMessage
      .append(message)
      .append("; ip: ")
      .append(remoteAddress);

    if (xForwardedFor != null) {
      logMessage
        .append(" XFF:")
        .append(xForwardedFor);
    }

    return logMessage.toString();
  }

  /**
   * Обработать тект комментария посредством парсеров (LorCode или Tex).
   *
   * @param msg   текст комментария
   * @param mode  режим обработки
   * @return обработанная строка
   */
  private String processMessage(String msg, String mode) {
    if ("ntobr".equals(mode)) {
      return toLorCodeFormatter.format(msg, true);
    } else {
      return toLorCodeTexFormatter.format(msg);
    }
  }

  @Nonnull
  public Set<Integer> makeHideSet(
          CommentList comments,
          int filterChain,
          @Nonnull Set<Integer> ignoreList
  ) throws SQLException, UserNotFoundException {
    if (filterChain == CommentFilter.FILTER_NONE) {
      return ImmutableSet.of();
    }

    Set<Integer> hideSet = new HashSet<>();

    /* hide anonymous */
    if ((filterChain & CommentFilter.FILTER_ANONYMOUS) > 0) {
      comments.getRoot().hideAnonymous(userDao, hideSet);
    }

    /* hide ignored */
    if ((filterChain & CommentFilter.FILTER_IGNORED) > 0) {
      if (!ignoreList.isEmpty()) {
        comments.getRoot().hideIgnored(hideSet, ignoreList);
      }
    }

    return hideSet;
  }

  private static List<CommentAndDepth> getAllReplys(CommentNode node, int depth) {
    List<CommentAndDepth> replys = new LinkedList<>();

    for (CommentNode r : node.childs()) {
      replys.addAll(getAllReplys(r, depth + 1));
      replys.add(new CommentAndDepth(r.getComment(), depth));
    }

    return replys;
  }

  private static class CommentAndDepth {
    private final Comment comment;
    private final int depth;

    private CommentAndDepth(Comment comment, int depth) {
      this.comment = comment;
      this.depth = depth;
    }

    public Comment getComment() {
      return comment;
    }

    private DeleteInfoDao.InsertDeleteInfo deleteInfo(boolean score, User user) {
      int bonus;
      String reason;

      if (score) {
        switch (depth) {
          case 0:
            reason = "7.1 Ответ на некорректное сообщение (авто, уровень 0)";
            bonus = -2;
            break;
          case 1:
            reason = "7.1 Ответ на некорректное сообщение (авто, уровень 1)";
            bonus = -1;
            break;
          default:
            reason = "7.1 Ответ на некорректное сообщение (авто, уровень >1)";
            bonus = 0;
            break;
        }
      } else {
        reason = "7.1 Ответ на некорректное сообщение (авто)";
        bonus = 0;
      }

      return new DeleteInfoDao.InsertDeleteInfo(comment.getId(), reason, bonus, user.getId());
    }
  }
}
TOP

Related Classes of ru.org.linux.comment.CommentService$CommentAndDepth

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.