package org.rzo.yajsw.tools;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JCLParser
{
List<String> _classpath = new ArrayList<String>();
List<String> _vmOptions = new ArrayList<String>();
List<String> _args = new ArrayList<String>();
String _java = null;
String _mainClass = null;
String _jar = null;
private JCLParser(String commandLine)
{
parseInternal(commandLine);
}
public static JCLParser parse(String commandLine)
{
JCLParser result = null;
result = new JCLParser(commandLine);
return result;
}
// TODO this should cover most cases but is not complete
private void parseInternal(String commandLine)
{
Matcher mr;
Pattern p;
// last position of _java in commandLine
int posJ = 0;
// last position of _classpath in commandLine
int posCp = 0;
// last position of __vmOptions in commandLine
int posOpts = 0;
// last position of _mainClass
int posclp = 0;
// last position of _jar
int posJar = 0;
// parse java
p = Pattern.compile("\\A(\"[^\"]+\")|(\\S+) ");
mr = p.matcher(commandLine);
if (mr.find())
{
_java = mr.group();
_java = _java.replaceAll("\"", "");
_java = _java.trim();
posJ = mr.end() - 1;
}
else
throw new RuntimeException("could not parse command line " + commandLine);
// parse jar
p = Pattern.compile(" -jar +((\"[^\"]+\")|(\\S+)) ");
mr = p.matcher(commandLine);
if (mr.find(posJ))
{
_jar = mr.group(1);
_jar = _jar.replaceAll("\"", "");
_jar = _jar.trim();
posJar = mr.end() - 1;
}
// parse classpath
p = Pattern.compile("(( -cp)|( -classpath)|( \"-classpath\")) +((\"[^\"]+\")|(\\S+)) ");
mr = p.matcher(commandLine);
if (mr.find(posJ))
{
String cp = mr.group().trim();
posCp = mr.end() - 1;
cp = cp.substring(cp.indexOf(' '));
String[] cpArr = cp.split(File.pathSeparator);
for (String cc : cpArr)
{
cc = cc.replaceAll("\"", "");
_classpath.add(cc.trim());
}
}
// parse main class
if (_jar == null)
{
p = Pattern.compile(" ([^- ])+( |$)");
mr = p.matcher(commandLine);
int max = Math.max(posJ, posCp);
if (mr.find(max))
{
_mainClass = mr.group();
_mainClass = _mainClass.replaceAll("\"", "");
_mainClass = _mainClass.trim();
posclp = mr.end() - 1;
}
}
// parse JVM options
p = Pattern.compile("(( -\\S+)|( -\"[^\"]+\")|( \"-[^\"]+\")) ");
mr = p.matcher(commandLine);
int max = Math.max(posJar, posclp);
while (mr.find())
{
String opt = mr.group().trim();
opt = opt.replaceAll("\"", "");
if (!opt.startsWith("-jar") && !opt.startsWith("-cp") && !opt.startsWith("-classpath") && mr.end() < max)
{
_vmOptions.add(opt);
posOpts = mr.end();
}
}
// parse args
p = Pattern.compile(" ((\"[^\"]+\")|(\\S+))( |$)");
mr = p.matcher(commandLine);
max = Math.max(posclp, posJar);
max = Math.max(max, posOpts);
if (mr.find(max))
{
String arg = mr.group();
arg = arg.replaceAll("\"", "");
_args.add(arg.trim());
max = mr.end() - 1;
while (mr.find(max))
{
arg = mr.group();
arg = arg.replaceAll("\"", "");
_args.add(arg.trim());
max = mr.end() - 1;
}
}
if (_java == null || "".equals(_java) || ((_mainClass == null || "".equals(_mainClass)) && ((_jar == null || "".equals(_jar)))))
throw new RuntimeException("error parsing java command line ");
}
public List<String> getClasspath()
{
return _classpath;
}
public List<String> getVmOptions()
{
return _vmOptions;
}
public List<String> getArgs()
{
return _args;
}
public String getJava()
{
return _java;
}
public String getMainClass()
{
return _mainClass;
}
public String getJar()
{
return _jar;
}
public static void main(String[] args)
{
String cmd = "\"java\" -cp \"C:\\Program Files\\yajsw-alpha-9.5\\bat\\/../wrapper.jar\" test.HelloWorld";
cmd = "java -Xrs -jar \"Z:\\dev\\yajsw\\bat\\/..\\wrapper.jar\" -c conf/wrapper.conf ";
cmd = "java -cp wrapper.jar -Xrs x.Test -c conf/wrapper.conf ";
cmd = "\"java\" -cp \"C:\\Program Files\\yajsw-alpha-9.5\\bat\\/../wrapper.jar\" test.HelloWorld";
cmd = "\"java\" test.HelloWorld";
JCLParser p = JCLParser.parse(cmd);
System.out.println(p.getJar());
System.out.println(p.getJava());
System.out.println(p.getMainClass());
System.out.println(p.getArgs());
System.out.println(p.getClasspath());
System.out.println(p.getVmOptions());
}
}