In script file, the command format is:
command param1 "param 2" "param3 has double quotes \" and single quote '" ...
All all those 3 parameters are valid.
The white space is the separator among command and parameters.
when there are spaces in parameter, it should be included in double quotes, e.g. "param 2".
when there are double quotes in parameter, should use backslash ('\') to escape. e.g. "param \" 3"
when line start with sharp mark ('#'), it is comment and should be ignored.
source:
import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* ScriptFileParser handles loading from simple .text based scripts.
*
* @author: barret
*/
public class ScriptFileParser {
// CHECKSTYLE:OFF
private static final String ERROR_MESSAGE = "The format is invalid for script line: %s";
private static final String REGX_FOR_GROUP = "\"((?:\\\\\"|[^\"])*)\"";
private static final String REGX_FOR_PARAMETER = REGX_FOR_GROUP + "|([^\"\\s]+)";
// CHECKSTYLE:ON
/** The logging instance for this class. */
private static final Log LOG = LogFactory.getLog(ScriptFileParser.class);
/**
* Read the string lines from given script steam.
* Filter the byte order mark when necessary.
*
* @param scriptStream of script file.
* @return the read lines.
* @throws IOException thrown if the stream cannot be read.
*/
public List<String> readLines(final InputStream scriptStream) throws IOException {
List<String> lineList;
BOMInputStream bomIn = new BOMInputStream(scriptStream, ByteOrderMark.UTF_8,
ByteOrderMark.UTF_16LE,
ByteOrderMark.UTF_16BE);
if (bomIn.hasBOM()) {
String encoding = bomIn.getBOMCharsetName();
lineList = IOUtils.readLines(bomIn, encoding);
} else {
lineList = IOUtils.readLines(bomIn);
}
return lineList;
}
/**
* Parse the given script row.
*
* @param row of script file.
* @param lineNumber the line number where this line was found.
* @return Builded script category.
* @throws ScriptLoaderException if parse action failed.
*/
private IScriptPrototypeLine parseScriptRow(final String row, final int lineNumber) {
if (row.trim().length() == 0 || row.trim().startsWith("#")) {
return new ScriptComment(row, lineNumber);
}
checkFormat(row);
List<String> params = parseParameters(row);
if (params.size() < 1) {
String message = String.format(ERROR_MESSAGE, row);
throw new ScriptParseException(message);
}
String command = params.get(0);
params.remove(command);
return new ScriptCommandPrototype(command, params, lineNumber);
}
/**
* Parse the parameters from given script row.
*
* @param row of script file.
* @return Parsed parameters.
*/
private List<String> parseParameters(final String row) {
List<String> params = new ArrayList<String>();
Pattern pattern = Pattern.compile(REGX_FOR_PARAMETER);
Matcher matcher = pattern.matcher(row);
while (matcher.find()) {
String parsed = matcher.group(1) != null ? matcher.group(1) : matcher.group();
String param = parsed.replace("\\\"", "\"");
params.add(param);
}
return params;
}
/**
* Check the format of given script row.
*
* @param row of script file.
* @throws ScriptLoaderException if format is invalid.
*/
private void checkFormat(final String row) {
String replaced = row.replaceAll(REGX_FOR_GROUP, "\"");
String invalidFormatReg = "\"\\S|\\S\"";
Pattern pattern = Pattern.compile(invalidFormatReg);
Matcher matcher = pattern.matcher(replaced);
while (matcher.find()) {
String message = String.format(ERROR_MESSAGE, row);
throw new ScriptParseException(message);
}
}
}
No comments:
Post a Comment