# QuestionRegexpComparator.java

    /*
     * Copyright (C) 2000 - 2024 Silverpeas
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU Affero General Public License as
     * published by the Free Software Foundation, either version 3 of the
     * License, or (at your option) any later version.
     *
     * As a special exception to the terms and conditions of version 3.0 of
     * the GPL, you may redistribute this Program in connection with Free/Libre
     * Open Source Software ("FLOSS") applications as described in Silverpeas's
     * FLOSS exception. You should have received a copy of the text describing
     * the FLOSS exception, and it is also available here:
     * "http://www.silverpeas.org/docs/core/legal/floss_exception.html"
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU Affero General Public License for more details.
     *
     * You should have received a copy of the GNU Affero General Public License
     * along with this program. If not, see <https://www.gnu.org/licenses/>.
     */

    /*
     * To change this template, choose Tools | Templates
     * and wait the template in the editor.
     */
    package org.silverpeas.components.questionreply.service;

    import org.silverpeas.components.questionreply.model.Question;

    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    /**
     * @author ehugonnet
     */
    public class QuestionRegexpComparator implements Comparator<Question> {

      private static QuestionRegexpComparator instance;
      private final Pattern pattern = Pattern.compile("([0-9.]*)\\s?-\\s?.*");
      private final Pattern numberPattern = Pattern.compile("\\d+");

      private QuestionRegexpComparator() {
      }

      public static QuestionRegexpComparator getInstance() {
        synchronized (QuestionRegexpComparator.class) {
          if (instance == null) {
            instance = new QuestionRegexpComparator();
          }
          return instance;
        }
      }

      @Override
      public int compare(Question question1, Question question2) {
        int result;
        if (question1 == question2) {
          result = 0;
        } else {
          if (question1 == null || question1.getTitle() == null) {
            result = -1;
          } else if (question2 == null || question2.getTitle() == null) {
            result = 1;
          } else {
            List<Integer> numbersQuestion1 = extractNumber(question1.getTitle());
            List<Integer> numbersQuestion2 = extractNumber(question2.getTitle());
            if (numbersQuestion1.isEmpty() || numbersQuestion2.isEmpty()) {
              result = question1.getTitle().compareTo(question2.getTitle());
            } else {
              if (numbersQuestion1.size() > numbersQuestion2.size()) {
                result = compareNumbers(numbersQuestion1, numbersQuestion2);
              } else {
                result = -1 * compareNumbers(numbersQuestion2, numbersQuestion1);
              }
            }
          }
        }
        return result;
      }

      protected List<Integer> extractNumber(final String label) {
        Matcher matcher = pattern.matcher(label);
        List<Integer> result = new ArrayList<>();
        String prefix = null;
        if (matcher.matches()) {
          prefix = matcher.group(1);
        }
        if (prefix != null) {
          matcher = numberPattern.matcher(prefix);
          while (matcher.find()) {
            String number = prefix.substring(matcher.start(), matcher.end());
            result.add(Integer.valueOf(number));
          }
        }
        return result;
      }

      protected int compareNumbers(List<Integer> bigList, List<Integer> smallList) {
        for (int i = 0; i < smallList.size(); i++) {
          int value1 = bigList.get(i);
          int value2 = smallList.get(i);
          if (value1 != value2) {
            return value1 - value2;
          }
        }
        return bigList.size() - smallList.size();
      }
    }