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.AbstractEntity; 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 getMethodList(Object o) { Method[] meths = o.getClass().getMethods(); ArrayList methodlist = new ArrayList(); 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 getValues(Object o, ArrayList methodlist, ArrayListfieldNames, boolean deep, ArrayList foundObjects) { Hashtable row = new Hashtable(); int i, j; if( foundObjects == null ) foundObjects = new ArrayList(); 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 = ""; } else try { AbstractEntity v = (AbstractEntity)value; val = v.createStringKey(); if( deep && !foundObjects.contains(v) ) { foundObjects.add(v); ArrayList fieldNamesDeep = new ArrayList(); ArrayList methodlistDeep = getMethodList(v); for( j = 0; j < methodlistDeep.size(); j++ ) { fieldNamesDeep.add(methodlistDeep.get(j).getName().substring(3).toLowerCase()); } Hashtable tmp = getValues(v,methodlistDeep,fieldNamesDeep,deep,foundObjects); Enumeration 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 fieldNames, ArrayListcolumnWidths, ArrayList > 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 > rows, String displayDef) { StringBuffer rval = new StringBuffer(); for( int j = 0; j < rows.size(); j++) { String rv = displayDef; Enumeration 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 methodlist = getMethodList(objects.get(0)); ArrayListcolumnWidths = new ArrayList(); ArrayListfieldNames = new ArrayList(); ArrayList > rows = new ArrayList >(); 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 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 arguments, ModuleInterface module) { String rval = ""; String currentModule = null; String currentFunction = null; Map currentWhere = new Hashtable(); Map currentSet = new Hashtable(); ArrayList currentOIDs = new ArrayList(); Map globalWhere = new Hashtable(); Map globalSet = new Hashtable(); 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(); currentWhere.putAll(globalWhere); currentSet = new HashMap(); currentSet.putAll(globalSet); currentOIDs = new ArrayList(); 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; } }