/* * #%L * gitools-utils * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * 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 3 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, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package org.gitools.utils.textpattern; import java.util.ArrayList; import java.util.List; public class TextPattern { public List<Token> getTokens() { return tokens; } public List<VariableToken> getVariableTokens() { List<VariableToken> variableTokens = new ArrayList<>(); for (Token t : tokens) { if (t instanceof VariableToken) { variableTokens.add((VariableToken) t); } } return variableTokens; } private final List<Token> tokens; public TextPattern(String pattern) { this.tokens = internalCompile(pattern); } private static List<Token> internalCompile(String pattern) { List<Token> tokens = new ArrayList<>(); if (pattern == null) { return tokens; } final StringBuilder buff = new StringBuilder(); final StringBuilder varBuff = new StringBuilder(); char state = 'C'; int pos = 0; while (pos < pattern.length()) { char ch = pattern.charAt(pos++); switch (state) { case 'C': // copying normal characters if (ch == '$') { state = '$'; } else { buff.append(ch); } break; case '$': // start of variable if (ch == '{') { state = 'V'; tokens.add(new TextToken(buff.toString())); buff.setLength(0); } else { buff.append('$').append(ch); state = 'C'; } break; case 'V': // reading name of variable if (ch == '}') { state = 'X'; } else { varBuff.append(ch); } break; case 'X': // expand variable tokens.add(new VariableToken(varBuff.toString())); varBuff.setLength(0); pos--; state = 'C'; break; } } switch (state) { case '$': buff.append('$'); break; case 'V': buff.append("${").append(varBuff); break; case 'X': tokens.add(new VariableToken(varBuff.toString())); varBuff.setLength(0); break; } if (buff.length() > 0) { tokens.add(new TextToken(buff.toString())); } return tokens; } public String generate(VariableValueResolver resolver) { StringBuilder sb = new StringBuilder(); for (Token token : tokens) token.generate(resolver, sb); return sb.toString(); } public static interface VariableValueResolver { String resolveValue(String variableName); } public static interface Token { void generate(VariableValueResolver resolver, StringBuilder sb); } public static class TextToken implements Token { private final String text; public TextToken(String text) { this.text = text; } @Override public void generate(VariableValueResolver resolver, StringBuilder sb) { sb.append(text); } @Override public String toString() { return text; } } public static class VariableToken implements Token { private final String variableName; public VariableToken(String variableName) { this.variableName = variableName; } public String getVariableName() { return variableName; } @Override public void generate(VariableValueResolver resolver, StringBuilder sb) { sb.append(resolver.resolveValue(variableName)); } @Override public String toString() { return variableName; } } }