// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.examples.sifquery; import java.io.*; import java.util.*; import openadk.library.*; /** * A convenience class to parse the command-line of all ADK Example agents * and to read a list of zones from a zones.properties file, if present in * the current working directory.<p> * * @version ADK 1.0 */ public class ADKExamples { /** * False if the /noreg option was specified, indicating the agent should * not send a SIF_Register message when connecting to zones */ public static boolean Reg = true; /** * True if the /unreg option was specified, indicating the agent should * send a SIF_Unregister when shutting down and disconnecting from zones */ public static boolean Unreg = false; /** * The SIFVersion specified on the command-line */ public static SIFVersion Version = SIFVersion.LATEST; /** * Parsed command-line arguments */ public static String[] args = null; /** * Parse the command-line. This method may be called repeatedly, usually * once from the sample agent's <code>main</code> function prior to * initializing the ADK and again from the <code>Agent.initialize</code> * method after initializing the Agent superclass. When called without an * Agent instance, only those options that do not rely on an AgentProperties * object are processed (e.g. the /D option). * <p> * * If a file named 'agent.rsp' exists in the current directory, any command * line options specified will be appended to the command-line arguments * passed to this method. Each line of the agent.rsp text file may be * comprised of one or more arguments separated by spaces, so that the * entirely set of arguments can be on one line or broken up onto many * lines.<p> * * @param agent An Agent instance that will be updated when certain * command-line options are parsed * @param args The string of arguments provided by the <code>main</code> * function */ public static Map<String,String> parseCL( Agent agent, String[] arguments ) { if( args == null ) { args = arguments; if( args.length > 0 && args[0].charAt(0) != '/' ) { // Look for an agent.rsp response file File rsp = new File( args[0] ); if( rsp.exists() ) { try { Vector<String> v = new Vector<String>(); BufferedReader in = new BufferedReader( new FileReader( rsp ) ); String line = in.readLine(); while( line != null ) { StringTokenizer tok = new StringTokenizer( line, " " ); while( tok.hasMoreTokens() ) v.addElement( tok.nextToken() ); line = in.readLine(); } // Append any arguments found to the args array if( v.size() > 0 ) { args = new String[ args.length + v.size() ]; System.arraycopy( arguments, 0, args, 0, arguments.length ); System.arraycopy( v.toArray(), 0, args, arguments.length, v.size() ); System.out.print("Reading command-line arguments from " + args[0] + ": " ); for( int i = 0; i < args.length; i++ ) System.out.print( args[i] + " " ); System.out.println(); System.out.println(); } } catch( Exception ex ) { System.out.println("Error reading command-line arguments from agent.rsp file: " + ex ); } } } } if( agent == null ) { // Look for options that do not affect the AgentProperties... for( int i = 0; i < args.length; i++ ) { if( args[i].equalsIgnoreCase("/debug") ) { if( i < args.length-1 ) { try { ADK.debug = ADK.DBG_NONE; int k = Integer.parseInt(args[++i]); if( k == 1 ) ADK.debug = ADK.DBG_MINIMAL; else if( k == 2 ) ADK.debug = ADK.DBG_MODERATE; else if( k == 3 ) ADK.debug = ADK.DBG_DETAILED; else if( k == 4 ) ADK.debug = ADK.DBG_VERY_DETAILED; else if( k == 5 ) ADK.debug = ADK.DBG_ALL; } catch( Exception e ) { ADK.debug = ADK.DBG_ALL; } } else ADK.debug = ADK.DBG_ALL; } else if( args[i].startsWith("/D") ) { String prop = args[i].substring(2); if( i != args.length-1 ) System.getProperties().setProperty(prop,args[++i]); else System.out.println("Usage: /Dproperty value"); } else if( args[i].equalsIgnoreCase("/log") && i != args.length -1 ) { try { ADK.setLogFile( args[++i] ); } catch( IOException ioe ) { System.out.println("Could not redirect debug output to log file: " + ioe ); } } else if( args[i].equalsIgnoreCase("/ver") && i != args.length -1 ) { Version = SIFVersion.parse( args[++i] ); } else if( args[i].equals( "/?" ) ) { System.out.println(); System.out.println("These options are common to all ADK Example agents. For help on the usage"); System.out.println("of this agent in particular, run the agent without any parameters. Note that"); System.out.println("most agents support multiple zones if a zones.properties file is found in"); System.out.println("the current directory."); System.out.println(); printHelp(); System.exit(0); } } return null; } // Parse all other options... AgentProperties props = agent.getProperties(); Map<String, String> misc = new HashMap<String,String>(); int port = -1; String host = null; boolean useHttps = false; String keystore = null; String ksPwd = null; String truststore = null; String tsPwd = null; boolean clientAuth = false; for( int i = 0; i < args.length; i++ ) { if( args[i].equalsIgnoreCase("/sourceId") && i != args.length -1 ) agent.setId( args[++i] ); else if( args[i].equalsIgnoreCase("/noreg") ) Reg = false; else if( args[i].equalsIgnoreCase("/unreg") ) Unreg = true; else if( args[i].equalsIgnoreCase("/pull") ) props.setMessagingMode( AgentMessagingMode.PULL ); else if( args[i].equalsIgnoreCase("/push") ) props.setMessagingMode( AgentMessagingMode.PUSH ); else if( args[i].equalsIgnoreCase("/port") && i != args.length-1 ) { try { port = Integer.parseInt(args[++i]); } catch( NumberFormatException nfe ) { System.out.println("Invalid port: "+args[i-1]); } } else if( args[i].equalsIgnoreCase("/https") ) { useHttps = true; } else if( args[i].equalsIgnoreCase("/keystore") ) { keystore = args[++i]; } else if( args[i].equalsIgnoreCase("/ksPwd") ) { ksPwd = args[++i]; } else if( args[i].equalsIgnoreCase("/truststore") ) { truststore = args[++i]; } else if( args[i].equalsIgnoreCase("/tsPwd") ) { tsPwd = args[++i]; } else if( args[i].equalsIgnoreCase("/auth") ) { clientAuth = true; } else if( args[i].equalsIgnoreCase("/host") && i != args.length -1 ) host = args[++i]; else if( args[i].equalsIgnoreCase("/timeout") && i != args.length -1 ) { try { props.setDefaultTimeout( Integer.parseInt(args[++i]) ); } catch( NumberFormatException nfe ) { System.out.println("Invalid timeout: "+args[i-1]); } } else if( args[i].equalsIgnoreCase("/freq") && i != args.length -1 ) { try { props.setPullFrequency( Integer.parseInt(args[++i]) ); } catch( NumberFormatException nfe ) { System.out.println("Invalid pull frequency: "+args[i-1]); } } else if( args[i].equalsIgnoreCase("/opensif") ) { // OpenSIF reports attempts to re-subscribe to objects as an // error instead of a success status code. The ADK would therefore // throw an exception if it encountered the error, so we can // disable that behavior here. props.setIgnoreProvisioningErrors( true ); } else if( args[i].charAt(0) == '/' ) { if( i == args.length - 1 || args[i+1].startsWith("/") ) misc.put( args[i].substring(1), null ); else misc.put( args[i].substring(1), args[++i] ); } } if( useHttps ) { // Set transport properties (HTTPS) HttpsProperties https = agent.getDefaultHttpsProperties(); if( keystore != null ) https.setKeyStore(keystore); if( ksPwd != null ) https.setKeyStorePassword(ksPwd); if( truststore != null ) https.setTrustStore(truststore); if( tsPwd != null ) https.setTrustStorePassword(tsPwd); https.setRequireClientAuth(clientAuth); if( port != -1 ) https.setPort(port); https.setHost(host); props.setTransportProtocol("https"); } else { // Set transport properties (HTTP) HttpProperties http = agent.getDefaultHttpProperties(); if( port != -1 ) http.setPort(port); http.setHost(host); props.setTransportProtocol("http"); } return misc; } /** * Display help to System.out */ public static void printHelp() { System.out.println(" /sourceId name The name of the agent"); System.out.println(" /ver version Default SIF Version to use (e.g. 10r1, 10r2, etc.)"); System.out.println(" /debug level Enable debugging to the console"); System.out.println(" 1 - Minimal"); System.out.println(" 2 - Moderate"); System.out.println(" 3 - Detailed"); System.out.println(" 4 - Very Detailed"); System.out.println(" 5 - All"); System.out.println(" /log file Redirects logging to the specified file"); System.out.println(" /pull Use Pull mode"); System.out.println(" /freq Sets the Pull frequency (defaults to 15 seconds)"); System.out.println(" /push Use Push mode"); System.out.println(" /port n The local port for Push mode (defaults to 12000)"); System.out.println(" /host addr The local IP address for push mode (defaults to any)"); System.out.println(" /noreg Do not send a SIF_Register on startup (sent by default)"); System.out.println(" /unreg Send a SIF_Unregister on exit (not sent by default)"); System.out.println(" /timeout ms Sets the ADK timeout period (defaults to 30000)"); System.out.println(" /opensif Ignores provisioning errors from OpenSIF"); System.out.println(" /Dproperty val Sets a Java System property"); System.out.println(); System.out.println(" HTTPS Transport Options:"); System.out.println(" /https Use HTTPS instead of HTTP"); System.out.println(" /auth Require Client Authentication"); System.out.println(" /keystore file The keystore file to use"); System.out.println(" /kspwd password The keystore password"); System.out.println(" /truststore file The truststore file to use"); System.out.println(" /tspwd password The truststore password"); System.out.println(); System.out.println(" Response Files:"); System.out.println(" To use a response file instead of typing arguments on the command-line," ); System.out.println(" pass the name of the response file as the first argument. This text" ); System.out.println(" file may contain any combination of arguments on one or more lines," ); System.out.println(" which are appended to any arguments specified on the command-line." ); System.out.println(); } /** * Looks for a file named zones.properties and if found reads its contents * into a HashMap where the key of each entry is the Zone ID and the value * is the Zone URL. A valid HashMap is always returned by this method; the * called typically assigns the value of the /zone and /url command-line * options to that map (when applicable). */ @SuppressWarnings("unchecked") public static HashMap readZonesList() throws IOException { HashMap list = new HashMap(); File f = new File( "zones.properties" ); if( f.exists() ) { System.out.println("Reading zone list from zones.properties file..."); Properties props = new Properties(); props.load( new FileInputStream(f) ); list.putAll(props); } return list; } }