358 lines
12 KiB
Java
358 lines
12 KiB
Java
|
package de.hsadmin.cliClientConnector;
|
||
|
|
||
|
import java.lang.reflect.Method;
|
||
|
import java.text.DateFormat;
|
||
|
import java.text.SimpleDateFormat;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.Date;
|
||
|
import java.util.Enumeration;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Hashtable;
|
||
|
import java.util.List;
|
||
|
import java.util.Map;
|
||
|
|
||
|
import de.hsadmin.cliClientConnector.CLIClientConnectorServlet.FunctionNotKnownException;
|
||
|
import de.hsadmin.cliClientConnector.CLIClientConnectorServlet.UnknownModuleException;
|
||
|
import de.hsadmin.core.model.Entity;
|
||
|
import de.hsadmin.core.model.ModuleInterface;
|
||
|
|
||
|
/**
|
||
|
* Parses Arguments for the CLI Client Connector Servlet
|
||
|
*
|
||
|
* @author Christof Donat
|
||
|
*
|
||
|
*/
|
||
|
public class ArgumentParser {
|
||
|
/// I am working for this Servlet instance
|
||
|
private CLIClientConnectorServlet master;
|
||
|
private DateFormat df = new SimpleDateFormat( "yyyy-MM-dd");
|
||
|
|
||
|
public ArgumentParser(CLIClientConnectorServlet master) {
|
||
|
this.master = master;
|
||
|
}
|
||
|
|
||
|
private String getUsageString() {
|
||
|
return " [ (-W name=value|--globalWhere:name=value) ...]\n"+
|
||
|
" [ (-S name=value|--globalSet:name=value) ...]\n"+
|
||
|
" [ (-D displayspec|--globalDisplay=displayspec) ...]\n"+
|
||
|
" [ (-c module.function|--call=module.function)\n" +
|
||
|
" [ (-w name=value|--where:name=value) ...]\n"+
|
||
|
" [ (-s name=value|--set:name=value) ...]\n"+
|
||
|
" [ (-d displayspec|--display:displayspec) ...]\n"+
|
||
|
" [ oids ...] ] ]\n"+
|
||
|
"\n"+
|
||
|
"(" + CLIClientConnectorServlet.version + ")\n";
|
||
|
}
|
||
|
|
||
|
private ArrayList<Method> getMethodList(Object o) {
|
||
|
Method[] meths = o.getClass().getMethods();
|
||
|
ArrayList<Method> methodlist = new ArrayList<Method>();
|
||
|
|
||
|
for( int i = 0; i < meths.length; i++ ) {
|
||
|
Method m = meths[i];
|
||
|
String n = m.getName();
|
||
|
if( n.startsWith("get") && !n.equals("getNew") ) {
|
||
|
String fn = m.getName().substring(3).toLowerCase();
|
||
|
if( fn.equals("class") ) continue;
|
||
|
if (m.getParameterTypes().length == 0) {
|
||
|
methodlist.add(m);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return methodlist;
|
||
|
}
|
||
|
|
||
|
private Hashtable<String,String> getValues(Object o, ArrayList<Method> methodlist, ArrayList<String>fieldNames, boolean deep, ArrayList<Object> foundObjects) {
|
||
|
Hashtable<String,String> row = new Hashtable<String,String>();
|
||
|
int i, j;
|
||
|
|
||
|
if( foundObjects == null ) foundObjects = new ArrayList<Object>();
|
||
|
|
||
|
for( i = 0; i < methodlist.size(); i++ ) {
|
||
|
Method m = methodlist.get(i);
|
||
|
try {
|
||
|
String name = fieldNames.get(i);
|
||
|
String type = m.getReturnType().getCanonicalName();
|
||
|
String val = "";
|
||
|
|
||
|
Object value = null;
|
||
|
try {
|
||
|
value = m.invoke(o);
|
||
|
} catch( Exception e ) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
|
||
|
if( value == null )
|
||
|
val = "";
|
||
|
else if( type.equals("java.lang.String") )
|
||
|
val = (String)value;
|
||
|
else if( type.equals("java.lang.Integer") )
|
||
|
val = String.valueOf((Integer)value);
|
||
|
else if( type.equals("java.lang.Long") )
|
||
|
val = String.valueOf((Long)value);
|
||
|
else if( type.equals("java.lang.Boolean") )
|
||
|
val = String.valueOf((Boolean)value);
|
||
|
else if( type.equals("java.util.Date") ) {
|
||
|
val = df.format((Date)value);
|
||
|
} else if( type.equals("java.util.Set") ) {
|
||
|
val = "<Set>";
|
||
|
} else try {
|
||
|
Entity v = (Entity)value;
|
||
|
val = v.createStringKey();
|
||
|
if( deep && !foundObjects.contains(v) ) {
|
||
|
foundObjects.add(v);
|
||
|
ArrayList<String> fieldNamesDeep = new ArrayList<String>();
|
||
|
ArrayList<Method> methodlistDeep = getMethodList(v);
|
||
|
for( j = 0; j < methodlistDeep.size(); j++ ) {
|
||
|
fieldNamesDeep.add(methodlistDeep.get(j).getName().substring(3).toLowerCase());
|
||
|
}
|
||
|
Hashtable<String,String> tmp = getValues(v,methodlistDeep,fieldNamesDeep,deep,foundObjects);
|
||
|
Enumeration<String> keys = tmp.keys();
|
||
|
while(keys.hasMoreElements()) {
|
||
|
try {
|
||
|
String k = (String)keys.nextElement();
|
||
|
row.put(name+"."+k, tmp.get(k));
|
||
|
} catch( Exception e ) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch(ClassCastException e) {
|
||
|
val = value.toString();
|
||
|
}
|
||
|
if (val != null) row.put(name, val);
|
||
|
} catch (Exception e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
return row;
|
||
|
}
|
||
|
|
||
|
private String formatObjectsWithoutDisplay(int j, ArrayList<String> fieldNames, ArrayList<Integer>columnWidths, ArrayList<Hashtable<String,String> > rows) {
|
||
|
int i;
|
||
|
StringBuffer rval = new StringBuffer();
|
||
|
|
||
|
for( i = 0; i < fieldNames.size(); i++ ) {
|
||
|
StringBuffer name = new StringBuffer(fieldNames.get(i));
|
||
|
int fieldwidth = columnWidths.get(i);
|
||
|
while( name.length() < fieldwidth )
|
||
|
name.append(" ");
|
||
|
rval.append(name.toString()+((i < fieldNames.size()-1)?" | ":""));
|
||
|
}
|
||
|
rval.append("\n");
|
||
|
for( i = 0; i < j; i++ )
|
||
|
rval.append("-");
|
||
|
rval.append("\n");
|
||
|
|
||
|
for( j = 0; j < rows.size(); j++ ) {
|
||
|
for( i = 0; i < fieldNames.size(); i++ ) {
|
||
|
StringBuffer value = new StringBuffer(rows.get(j).get(fieldNames.get(i)));
|
||
|
int fieldwidth = columnWidths.get(i);
|
||
|
while( value.length() < fieldwidth )
|
||
|
value.append(" ");
|
||
|
rval.append(value.toString()+((i < fieldNames.size()-1)?" | ":""));
|
||
|
}
|
||
|
rval.append("\n");
|
||
|
}
|
||
|
return rval.toString();
|
||
|
}
|
||
|
|
||
|
private String formatObjectsWithDisplay(ArrayList<Hashtable<String,String> > rows, String displayDef) {
|
||
|
StringBuffer rval = new StringBuffer();
|
||
|
for( int j = 0; j < rows.size(); j++) {
|
||
|
String rv = displayDef;
|
||
|
Enumeration<String> fNames = rows.get(j).keys();
|
||
|
while( fNames.hasMoreElements() ) {
|
||
|
String f = (String)fNames.nextElement();
|
||
|
rv = rv.replaceAll("\\$\\{"+f+"\\}", rows.get(j).get(f));
|
||
|
}
|
||
|
rv = rv.replaceAll("\\\\n", "\n");
|
||
|
rv = rv.replaceAll("\\\\t", "\t");
|
||
|
rv = rv.replaceAll("\\\\(.)?", "$1");
|
||
|
rval.append(rv);
|
||
|
}
|
||
|
return rval.toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* format Objects for the output as a Human readable table
|
||
|
*
|
||
|
* @param objects
|
||
|
* format these objects
|
||
|
*
|
||
|
* @return humanReadableString
|
||
|
* a string with the human readable representation of the objects
|
||
|
*/
|
||
|
public String formatObjects(List<?> objects, String displayDef) {
|
||
|
if( objects.size() == 0 ) return "";
|
||
|
if( objects.get(0) == null ) return "";
|
||
|
ArrayList<Method> methodlist = getMethodList(objects.get(0));
|
||
|
ArrayList<Integer>columnWidths = new ArrayList<Integer>();
|
||
|
ArrayList<String>fieldNames = new ArrayList<String>();
|
||
|
ArrayList<Hashtable<String,String> > rows =
|
||
|
new ArrayList<Hashtable<String,String> >();
|
||
|
int i, j;
|
||
|
|
||
|
for( i = 0; i < methodlist.size(); i++ ) {
|
||
|
Method m = methodlist.get(i);
|
||
|
String n = m.getName();
|
||
|
String fn = n.substring(3).toLowerCase();
|
||
|
fieldNames.add(fn);
|
||
|
columnWidths.add(n.length()+3);
|
||
|
}
|
||
|
|
||
|
for( j = 0; j < objects.size(); j++ ) {
|
||
|
Object o = objects.get(j);
|
||
|
Hashtable<String,String> row = getValues(o,methodlist,fieldNames,(displayDef != null), null);
|
||
|
for( i = 0; i < fieldNames.size(); i++ ) {
|
||
|
String val = row.get(fieldNames.get(i));
|
||
|
if( val != null && i < columnWidths.size() && val.length()+3 > columnWidths.get(i) )
|
||
|
columnWidths.set(i, val.length()+3);
|
||
|
}
|
||
|
rows.add(row);
|
||
|
}
|
||
|
|
||
|
if( displayDef == null ) {
|
||
|
j = 0;
|
||
|
for( i = 0; i < columnWidths.size(); i++ ) {
|
||
|
j += columnWidths.get(i)+2;
|
||
|
}
|
||
|
j -= 2;
|
||
|
|
||
|
return formatObjectsWithoutDisplay(j, fieldNames, columnWidths, rows);
|
||
|
} else
|
||
|
return formatObjectsWithDisplay(rows, displayDef);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The main parser function. Parses the Parameters, uses the master to call
|
||
|
* the functions and returns a formatet output.
|
||
|
*
|
||
|
* @param arguments
|
||
|
* @return humanReadableObjectsString
|
||
|
*/
|
||
|
public String parse(List<String> arguments, ModuleInterface module) {
|
||
|
String rval = "";
|
||
|
|
||
|
String currentModule = null;
|
||
|
String currentFunction = null;
|
||
|
Map<String,String> currentWhere = new Hashtable<String,String>();
|
||
|
Map<String,String> currentSet = new Hashtable<String,String>();
|
||
|
ArrayList<String> currentOIDs = new ArrayList<String>();
|
||
|
|
||
|
Map<String,String> globalWhere = new Hashtable<String,String>();
|
||
|
Map<String,String> globalSet = new Hashtable<String,String>();
|
||
|
String display = null;
|
||
|
String globalDisplay = null;
|
||
|
|
||
|
for( int i = 0; i < arguments.size(); i++ ) {
|
||
|
String arg = arguments.get(i);
|
||
|
|
||
|
if( arg.equals("-c") || arg.startsWith("--call:") ) {
|
||
|
// call
|
||
|
if( currentModule != null ) {
|
||
|
try {
|
||
|
// execute the last call now
|
||
|
rval += formatObjects(master.callModule(
|
||
|
currentModule,
|
||
|
currentFunction,
|
||
|
currentWhere,
|
||
|
currentSet,
|
||
|
currentOIDs,
|
||
|
module),(display==null)?globalDisplay:display);
|
||
|
} catch (FunctionNotKnownException e) {
|
||
|
rval += "Function unknown: "+currentModule+'.'+currentFunction+"\n";
|
||
|
} catch (UnknownModuleException e) {
|
||
|
rval += "Module unknown: "+currentModule+"\n";
|
||
|
}
|
||
|
}
|
||
|
// reset parameters for next call
|
||
|
currentWhere = new HashMap<String, String>();
|
||
|
currentWhere.putAll(globalWhere);
|
||
|
currentSet = new HashMap<String, String>();
|
||
|
currentSet.putAll(globalSet);
|
||
|
currentOIDs = new ArrayList<String>();
|
||
|
display = null;
|
||
|
|
||
|
// set the new call
|
||
|
boolean isShortParam = arg.equals("-c");
|
||
|
String calldef = isShortParam?arguments.get(i+1):arg.substring(7);
|
||
|
|
||
|
if( calldef != null ) {
|
||
|
String[] split = calldef.split("[.]", 2);
|
||
|
currentModule = split[0];
|
||
|
currentFunction = split[1];
|
||
|
}
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-w") || arg.startsWith("--where:") ) {
|
||
|
// where
|
||
|
boolean isShortParam = arg.equals("-w");
|
||
|
String wheredef = isShortParam?arguments.get(i+1):arg.substring(8);
|
||
|
if( wheredef != null ) {
|
||
|
String[] split = wheredef.split("[=]", 2);
|
||
|
currentWhere.put(split[0],split[1]);
|
||
|
}
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-W") || arg.startsWith("--globalWhere:") ) {
|
||
|
// global where
|
||
|
boolean isShortParam = arg.equals("-W");
|
||
|
String gwheredef = isShortParam?arguments.get(i+1):arg.substring(14);
|
||
|
if( gwheredef != null ) {
|
||
|
String[] split = gwheredef.split("[=]", 2);
|
||
|
globalWhere.put(split[0],split[1]);
|
||
|
}
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-s") || arg.startsWith("--set:") ) {
|
||
|
// set
|
||
|
boolean isShortParam = arg.equals("-s");
|
||
|
String setdef = isShortParam?arguments.get(i+1):arg.substring(6);
|
||
|
if( setdef != null ) {
|
||
|
String[] split = setdef.split("[=]", 2);
|
||
|
currentSet.put(split[0],split[1]);
|
||
|
}
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-S") || arg.startsWith("--globalSet:") ) {
|
||
|
// global set
|
||
|
boolean isShortParam = arg.equals("-S");
|
||
|
String gsetdef = isShortParam?arguments.get(i+1):arg.substring(12);
|
||
|
if( gsetdef != null ) {
|
||
|
String[] split = gsetdef.split("[=]", 2);
|
||
|
globalSet.put(split[0],split[1]);
|
||
|
}
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-d") || arg.startsWith("--display:") ) {
|
||
|
// display
|
||
|
boolean isShortParam = arg.equals("-d");
|
||
|
display = isShortParam?arguments.get(i+1):arg.substring(10);
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-D") || arg.startsWith("--globalDisplay:") ) {
|
||
|
// global display
|
||
|
boolean isShortParam = arg.equals("-D");
|
||
|
globalDisplay = isShortParam?arguments.get(i+1):arg.substring(16);
|
||
|
if( isShortParam ) i++;
|
||
|
} else if( arg.equals("-h") || arg.equals("--help") ) {
|
||
|
return getUsageString();
|
||
|
} else if( arg.startsWith("-") ) {
|
||
|
return "unknown option '"+arg+"'\n"+getUsageString();
|
||
|
} else currentOIDs.add(arg);
|
||
|
}
|
||
|
if( currentModule != null ) {
|
||
|
try {
|
||
|
rval += formatObjects(master.callModule(
|
||
|
currentModule,
|
||
|
currentFunction,
|
||
|
currentWhere,
|
||
|
currentSet,
|
||
|
currentOIDs,
|
||
|
module),(display==null)?globalDisplay:display);
|
||
|
} catch (FunctionNotKnownException e) {
|
||
|
rval += "Function unknown: "+currentModule+'.'+currentFunction+"\n";
|
||
|
} catch (UnknownModuleException e) {
|
||
|
rval += "Module unknown: "+currentModule+"\n";
|
||
|
}
|
||
|
}
|
||
|
return rval;
|
||
|
}
|
||
|
}
|