package org.ovirt.engine.core.bll.common; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.lang.StringUtils; public class NumericSuffixNormalizer { private static final Pattern NUMERIC_SUFFIX_PATTERN = Pattern.compile("^(.*?)(\\d+)$"); /** * Left pads with zeroes the numeric suffixes, so they will have same length and would be properly comparable as * strings. A string with no numeric suffix would remain unchanged. */ public List<String> normalize(String... strings) { final List<TextWithNumericSuffix> inputAsTextWithNumericSuffix = Arrays.stream(strings) .map(this::decompose) .collect(Collectors.toList()); final int maxNumericSuffixLength = findMaxNumericSuffixLength(inputAsTextWithNumericSuffix); return inputAsTextWithNumericSuffix.stream() .map(e -> e.compose(maxNumericSuffixLength)) .collect(Collectors.toList()); } private int findMaxNumericSuffixLength(List<TextWithNumericSuffix> inputAsTextWithNumericSuffix) { return inputAsTextWithNumericSuffix .stream() .map(TextWithNumericSuffix::getSuffix) .filter(Objects::nonNull) .collect(Collectors.summarizingInt(String::length)) .getMax(); } private TextWithNumericSuffix decompose(String str) { if (str == null) { return new TextWithNumericSuffix(null); } else { final Matcher matcher = NUMERIC_SUFFIX_PATTERN.matcher(str); if (matcher.matches()) { final String prefix = matcher.group(1); final String numericSuffix = matcher.group(2); return new TextWithNumericSuffix(prefix, numericSuffix); } else { return new TextWithNumericSuffix(str); } } } private static class TextWithNumericSuffix { private final String text; private final String suffix; TextWithNumericSuffix(String text) { this(text, null); } TextWithNumericSuffix(String text, String numericSuffix) { this.text = text; this.suffix = numericSuffix; } private String compose(int maxNumericSuffixLength) { if (getSuffix() == null) { return getText(); } else { return getText() + StringUtils.leftPad(getSuffix(), maxNumericSuffixLength, '0'); } } String getText() { return text; } String getSuffix() { return suffix; } } }