/* * Copyright (C) 2009-2017 Slava Semushin <slava.semushin@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package ru.mystamps.web.util; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; /** * Helpers for dealing with stamps catalog numbers. **/ public final class CatalogUtils { private static final int ONE_ELEMENT_SIZE = 1; private static final int TWO_ELEMENTS_SIZE = 2; private static final Comparator<String> STR_AFTER_INT = new Comparator<String>() { @Override public int compare(String lhs, String rhs) { try { Integer left = Integer.valueOf(lhs); Integer right = Integer.valueOf(rhs); return left.compareTo(right); } catch (NumberFormatException ex) { return 1; } } }; private CatalogUtils() { } /** * Converts set of catalog numbers to comma-delimited string with range of numbers. **/ public static String toShortForm(List<String> catalogNumbers) { Validate.isTrue(catalogNumbers != null, "Catalog numbers must be non null"); if (catalogNumbers.isEmpty()) { return ""; } Set<String> numbers = new TreeSet<>(STR_AFTER_INT); numbers.addAll(catalogNumbers); List<String> groups = new ArrayList<>(); List<String> currentBuffer = new ArrayList<>(); for (String currentString : numbers) { // for first element if (currentBuffer.isEmpty()) { currentBuffer.add(currentString); continue; } // in range Integer current = Integer.valueOf(currentString); Integer previous = Integer.valueOf(currentBuffer.get(currentBuffer.size() - 1)); if (previous + 1 == current) { currentBuffer.add(currentString); continue; } addBufferToGroups(currentBuffer, groups); currentBuffer.clear(); // start new group currentBuffer.add(currentString); } addBufferToGroups(currentBuffer, groups); return String.join(", ", groups); } /** * Parses comma-delimited string and converts catalog numbers to set of strings. **/ public static Set<String> parseCatalogNumbers(String catalogNumbers) { if (StringUtils.isEmpty(catalogNumbers)) { return Collections.emptySet(); } Set<String> result = new LinkedHashSet<>(); for (String number : catalogNumbers.split(",")) { Validate.validState(!number.trim().isEmpty(), "Catalog number must be non empty"); // TODO: parse range of numbers result.add(number); } return result; } private static void addBufferToGroups(List<String> buffer, List<String> groups) { Validate.isTrue(!buffer.isEmpty(), "Buffer must be non-empty"); String firstElement = buffer.get(0); String lastElement = buffer.get(buffer.size() - 1); if (buffer.size() == ONE_ELEMENT_SIZE) { groups.add(firstElement); } else if (buffer.size() == TWO_ELEMENTS_SIZE) { groups.add(firstElement); groups.add(lastElement); // save sequence as range } else { groups.add(firstElement + "-" + lastElement); } } }