package bluej;

import java.io.File;
import java.net.MalformedURLException;
import java.util.Properties;


| Handling of property value parsing - substitution of variable values etc. | | <p>Variable substitution is performed for ${}ariableName} and $variableName - | the variable name is terminated by any non-name character, but in either case a | '$' escapes the next character. In the first form anything after the variable | name is ignored (up to the closing '}'). | | <p>The double dollar sign '$$' is an escaped '$'. If a variable name begins with | a dollar sign, the variable must be written as '${}$name}' where name is the part | of the name after the initial dollar sign. | | <p>The following functions are also supported: | | <ul> | <li>${}ilepath x y} - concatenates file paths x and y to form a complete path | <li>${}ileUrl x} - returns the given file path x as a file:// URL. | </ul> | | <p>Function arguments can contain variable/function substitutions. | | @author Davin McCall | public class PropParser {
| The maximum depth of recursion when substituting variables | private final static int MAX_DEPTH = 10;
| Process variable/function substitution on a property value. | @param value The property value to process | @param subvars The collection of variable-to-value mappings | @return The value after substitution | public static String parsePropString(String value, Properties subvars) { StringBuffer outBuffer = new StringBuffer(); parsePropString(value, outBuffer, subvars, 0); return outBuffer.toString(); } private static void parsePropString(String value, StringBuffer outBuffer, Properties subvars, int depth) { if (depth > MAX_DEPTH) { outBuffer.append(value); return; } StringIter iter = new StringIter(value); while (iter.hasNext()){ char cc = iter.next(); if (cc == '$') { if (iter.hasNext()) { cc = iter.next(); if (cc == '$') { outBuffer.append('$'); } else if (cc == '{') { processVar(iter, outBuffer, subvars, depth); while (iter.hasNext()){ cc = iter.next(); if (cc == '}') { break; } } } else if (isNameChar(cc)) { iter.backup(); processVar(iter, outBuffer, subvars, depth); } else { outBuffer.append('$'); outBuffer.append(cc); } } else { outBuffer.append('$'); } } else { outBuffer.append(cc); } } }
| Check whether the given character is likely to be part of a property | name. (Most punctuation marks are excluded). | private static boolean isNameChar(char cc) { if (Character.isWhitespace(cc)) { return false; } if (cc == '/' || cc == '\\' || cc == '{' || cc == '}' || cc == '\"' || cc == '$' || cc == '(' || cc == ')' || cc == ' ' || cc == ':') { return false; } if (cc == ',') { return false; } return true; } private static void processVar(StringIter iter, StringBuffer outBuffer, Properties subvars, int depth) { StringBuffer varNameBuf = new StringBuffer(); while (iter.hasNext()){ char cc = iter.next(); if (isNameChar(cc)) { varNameBuf.append(cc); } else if (cc == '$' && iter.hasNext()) { cc = iter.next(); varNameBuf.append(cc); } else { iter.backup(); break; } } String varName = varNameBuf.toString(); if (varName.equals("filePath")) { String arg = processStringArg(iter, subvars, depth); if (arg != null) { File f = new File(arg); do { arg = processStringArg(iter, subvars, depth); if (arg != null) { f = new File(f, arg); } } while (arg != null){; outBuffer.append(f.getAbsolutePath()); } } } else if (varName.equals("fileUrl")) { String arg = processStringArg(iter, subvars, depth); if (arg != null) { File f = new File(arg); try { String fileUrl = f.toURI().toURL().toString(); outBuffer.append(fileUrl); } catch (MalformedURLException mfue) { } } } else { String nval = subvars.getProperty(varName); if (nval != null) { parsePropString(nval, outBuffer, subvars, depth + 1); } } }
| Process a string argument to a substitution function. Any initial leading whitespace | is skipped. | | String arguments can include double-quote-enclosed literal strings, as well as | unquoted characters, $-marked variable substitutions, and $-quoted special characters. | They are terminated by (unquoted) whitespace or the (unquoted) '}' character. | | Return is null if no argument is present ('}' is first non-whitespace character). | | @param iter | @return | private static String processStringArg(StringIter iter, Properties subvars, int depth) { char cc; do { if (! iter.hasNext()) { return null; } cc = iter.next(); } while (Character.isWhitespace(cc)){; if (cc == '}') { return null; } } if (cc == '\"') { StringBuffer result = new StringBuffer(); while (iter.hasNext()){ cc = iter.next(); if (cc == '\"') { break; } result.append(cc); } return result.toString(); } else { StringBuffer outBuffer = new StringBuffer(); iter.backup(); do { cc = iter.next(); if (cc == '$' && iter.hasNext()) { cc = iter.next(); if (Character.isWhitespace(cc) || cc == '}' || cc == '\"') { outBuffer.append(cc); } else if (cc == '{') { processVar(iter, outBuffer, subvars, depth); while (iter.hasNext()){ cc = iter.next(); if (cc == '}') { break; } } } else { iter.backup(); processVar(iter, outBuffer, subvars, depth); } } else { if (Character.isWhitespace(cc) || cc == '}') { iter.backup(); break; } else if (cc == '\"') { while (iter.hasNext()){ cc = iter.next(); if (cc == '\"') { break; } outBuffer.append(cc); } } else { outBuffer.append(cc); } } } while (iter.hasNext()){; return outBuffer.toString(); } } }
| A class for iterating through a string | | @author Davin McCall | private static class StringIter { private String string; private int curpos; private int limit; StringIter(String string) { this.string = string; limit = string.length(); } public boolean hasNext() { return curpos < limit; } public char next() { return string.charAt(curpos++); } public void backup() { curpos--; } } }
top, use, map, class PropParser

.   parsePropString
.   parsePropString
.   isNameChar
.   processVar
.   processStringArg

top, use, map, class StringIter

.   hasNext
.   next
.   backup




354 neLoCode + 32 LoComm