/* * JBoss, Home of Professional Open Source * Copyright 2013, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.richfaces.shrinkwrap.descriptor; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <p> * Formats using simplified MessageFormat syntax: {} are used as placeholders in order of arguments; {number} are placeholders * with given argument number. * </p> * * <p> * When filling the placeholders by given arguments are compelete, rest of the numbered placeholders are decreased by number of * arguments in previous format action. * </p> * * @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a> * @version $Revision$ */ final class SimplifiedFormat { private static final int MAXIMUM = 64; private static final int SIXTEEN = 16; private static final Pattern PATTERN = Pattern.compile("\\{([0-9]+)\\}"); private SimplifiedFormat() { } /** * Parametrize given string with arguments, using {} or {number} (e.g. {0}, {1}, ...) as placeholders. * * @param message message to format * @param args used to formatting given format string * @return string formatted using given arguments */ public static String format(String message, Object... args) { String result = message; for (int i = 0; i < args.length; i++) { String arg = args[i].toString(); arg = increaseByDelta(arg, args.length); arg = replace(arg, "{}", "{-1}"); result = replaceOnce(result, "{}", arg); result = replace(result, "{" + i + "}", arg); } result = decreaseByDelta(result, args.length); result = replace(result, "{-1}", "{}"); return result; } private static String decreaseByDelta(String message, int delta) { return increaseByDelta(message, 0 - delta); } private static String increaseByDelta(String message, int delta) { String result = message; Matcher matcher = PATTERN.matcher(result); List<Integer> found = new LinkedList<Integer>(); while (matcher.find()) { int value = Integer.valueOf(matcher.group(1)); found.add(value); } Collections.sort(found); for (int value : found) { int replacement = value + delta; result = replaceOnce(result, "{" + value + "}", "{" + replacement + "}"); } return result; } private static String replace(String text, String searchString, String replacement) { return replace(text, searchString, replacement, -1); } private static String replaceOnce(String text, String searchString, String replacement) { return replace(text, searchString, replacement, 1); } private static String replace(String text, String searchString, String replacement, int max) { int m = max; int start = 0; int end = text.indexOf(searchString, start); if (end == -1) { return text; } int replLength = searchString.length(); int increase = replacement.length() - replLength; increase = increase < 0 ? 0 : increase; increase *= m < 0 ? SIXTEEN : (m > MAXIMUM ? MAXIMUM : m); StringBuffer buf = new StringBuffer(text.length() + increase); while (end != -1) { buf.append(text.substring(start, end)).append(replacement); start = end + replLength; if (--m == 0) { break; } end = text.indexOf(searchString, start); } buf.append(text.substring(start)); return buf.toString(); } }