package net.sf.minuteProject.handler.property; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.apache.commons.lang.StringUtils; public class PropertyStack { Properties properties; class Prop { String name, value; } abstract class Chunk { Chunk(String value) { this.value = value; } String value; public abstract String getValue(); public abstract int getLength(); } class AbsoluteChunk extends Chunk { AbsoluteChunk(String value) { super(value); } @Override public String getValue() { return value; } @Override public int getLength() { return getValue().length(); } } class RelativeChunk extends Chunk { RelativeChunk(String value) { super(value); } @Override public String getValue() { return getProperties().getProperty(value); } @Override public int getLength() { return value.length()+3; // 3 for ${ and } } } PropertyStack() { } public Properties getProperties() { if (properties == null) properties = new Properties(); return properties; } public void setProperties(Properties properties) { this.properties = properties; } public void addProperty(String name, String value) { getProperties().setProperty(name, resolvePropertyValue(value)); } public String resolvePropertyValue (String value) { List<Chunk> props = parseValue(value); return resolvePropertyValue (props); } private String resolvePropertyValue (List<Chunk> chunks) { StringBuffer stringBuffer = new StringBuffer(); for (Chunk chunk : chunks) { stringBuffer.append(chunk.getValue()); } return stringBuffer.toString(); } /** * parse the input string into Substring called chunks. * Each chunk is of where absolute (containing no reference) or relative (containing reference) * a reference is between ${ and } token * @param value * @return */ List<Chunk> parseValue (String value) { // search for ${ // take string before : if not null => absolutechunk // search for } // if no => abolutechunk // if yes => relative chunk // to do until string completely parsed List<Chunk> result = new ArrayList<Chunk>(); int length = value.length(); int posix = 0; while (posix < length) { Chunk chunk = searchNextChunk(StringUtils.substring(value, posix, length)); if (chunk.getLength()!=0) { result.add(chunk); } posix = posix + chunk.getLength(); } return result; } private Chunk searchNextChunk (String rawString) { Chunk chunk; String beforeRelativeSeparator = StringUtils.substringBefore(rawString, "${"); if (beforeRelativeSeparator!=null && !beforeRelativeSeparator.equals("")) chunk = new AbsoluteChunk(beforeRelativeSeparator); else {// we found a "${" token => search the end "}" rawString = StringUtils.substringAfter(rawString, "${"); // to position after separator String betweenRelativeSeparator = StringUtils.substringBefore(rawString, "}"); if (rawString.length() == betweenRelativeSeparator.length()) // no ending token !! chunk = new AbsoluteChunk(betweenRelativeSeparator); else chunk = new RelativeChunk(betweenRelativeSeparator); } return chunk; } }