/** * JADE - Java Agent DEvelopment Framework is a framework to develop * multi-agent systems in compliance with the FIPA specifications. * Copyright (C) 2000 CSELT S.p.A. * * GNU Lesser General Public License * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /** Tests: * java jade.Boot (with/without rmiregistry started): run a main-container * java jade.Boot -host pippo.cselt.it * java jade.Boot -host fbellif.cselt.it * java jade.Boot -host fbellif.cselt.it -port 1200 * java jade.Boot -help * java jade.Boot -gui **/ package jade; //#APIDOC_EXCLUDE_FILE //#J2ME_EXCLUDE_FILE import java.net.InetAddress; import java.net.UnknownHostException; import java.io.File; import java.io.PrintStream; import java.util.Enumeration; // J2ME CLDC OK import java.util.Vector; // J2ME CLDC OK import jade.core.Runtime; import jade.core.Profile; //import jade.core.BootProfileImpl; import jade.util.ExtendedProperties; import jade.util.PropertiesException; //import jade.security.SecurityFactory; /** * Boots <B><em>JADE</em></b> system, parsing command line arguments in the old (3.x) style. * @author Giovanni Rimassa - Universita' di Parma * @author Dick Cowan - HP Labs * @version $Date: 2010-04-19 17:42:22 +0200 (lun, 19 apr 2010) $ $Revision: 6323 $ */ public class Boot3 { /** separator between the agent name and the agent class */ private static final String NAME2CLASS_SEPARATOR = ":"; private ExtendedProperties properties = null; private BootProfileImpl profile = null; /** * Main entry point for invocation. * @param args The command line arguments. These use the form key:value * or -key (shorthand for key:true). */ public static void main(String args[]) { new Boot3(args); } /** * Constructor. Starts Jade with provided arguments. * @param args The command line arguments. These use the form key:value */ public Boot3(String[] args) { try { profile = new BootProfileImpl(prepareArgs(args)); // qui adesso gli passa anche dbconf } catch (PropertiesException pe) { System.out.println(pe); System.exit(-1); } if (profile.getParameter(Profile.IMTP, null) == null) { profile.setParameter(Profile.IMTP, "jade.imtp.rmi.RMIIMTPManager"); } if (profile.getParameter(Profile.STYLE_3_X, null) == null) { profile.setParameter(Profile.STYLE_3_X, "true"); } properties = profile.getArgProperties(); if (properties.getBooleanProperty(BootProfileImpl.DUMP_KEY, false)) { listProperties(System.out); } if (properties.getBooleanProperty(BootProfileImpl.VERSION_KEY, false)) { System.out.println(Runtime.getCopyrightNotice()); return; } if (properties.getBooleanProperty(BootProfileImpl.HELP_KEY, false)) { usage(System.out); return; } if (properties.getProperty(Profile.MAIN_HOST) == null) { try { properties.setProperty(Profile.MAIN_HOST, InetAddress.getLocalHost().getHostName()); } catch (UnknownHostException uhe) { System.out.print("Unknown host exception in getLocalHost(): "); System.out.println(" please use '-host' and/or '-port' options to setup JADE host and port"); System.exit(1); } } if (properties.getBooleanProperty(BootProfileImpl.CONF_KEY, false)) { new BootGUI(this); if (properties.getBooleanProperty(BootProfileImpl.DUMP_KEY, false)) { listProperties(System.out); } } // --- initialize JVM-scoped Security Factory --- // (the security settings contained into this profile // will be used for all containers into this JVM in // despite of settings into profile of other future containers) //SecurityFactory sf = SecurityFactory.getSecurityFactory(profile); try { check(); // Exit the JVM when there are no more containers around Runtime.instance().setCloseVM(true); if (profile.getBooleanProperty(Profile.MAIN, true)) { Runtime.instance().createMainContainer(profile); } else { Runtime.instance().createAgentContainer(profile); } } catch (BootException be) { System.err.println(be); return; } } /** * Transform original style boot arguments to new form. * <pre> * In the following 'x' and 'y' denote arbitrary strings; 'n' an integer. * Transformation Rules: * Original New * ------------------------------ * -host x host:x * -owner x owner:x * -name x name:x * -port n port:n * -mtp x mtp:x * -aclcodec:x aclcodec:x * -conf x import:x * -conf -conf * -container -container * -gui -gui * -version -version * -v -version * -help -help * -h -help * -nomtp -nomtp * -nomobility -nomobility * -y x y:x * agent list agents:agent list * </pre> * If the arguments contain either import:x or agents:x * we will assume that the arguments are already in the new * format and leave them alone. For "import:" we test if * what follows is a file name and in the event it isn't we * assume that it was if there are any other "-x" options following. * <p> * You can't mix the old form with the new as this would make the * distinction between foo:bar as meaning a property named foo with * a value bar or an agent named foo implmented by class bar impossible. * <p> * @param args The command line arguments. */ protected String[] prepareArgs(String[] args) { boolean printUsageInfo = false; if ((args == null) || (args.length == 0)) { // printUsageInfo = true; } else { boolean isNew = false; boolean likely = false; for (int i = 0; i < args.length; i++) { if (args[i].startsWith("import:")) { int j = args[i].indexOf(':'); isNew = ( (j < args[i].length()-1) && (isFileName(args[i].substring(j+1))) ); likely = !isNew; // in case malformed file name } else if (args[i].startsWith("agents:")) { isNew = true; } else if (args[i].startsWith("-") && likely) { isNew = true; } } if (isNew) { return args; } } int n = 0; boolean endCommand = false; // true when there are no more options on the command line Vector results = new Vector(); while ((n < args.length) &&!endCommand) { String theArg = args[n]; if (theArg.equalsIgnoreCase("-conf")) { if (++n == args.length) { // no modifier results.add(theArg); } else { // Use whatever is next as a candidate file name String nextArg = args[n]; if (isFileName(nextArg)) { // it was a file name results.add("import:" + nextArg); } else { // its either an illformed file name or something else results.add(theArg); n--; } } } else if (theArg.equalsIgnoreCase("-host")) { if (++n == args.length) { System.err.println("Missing host name "); printUsageInfo = true; } else { results.add("host:" + args[n]); } }else if (theArg.equalsIgnoreCase("-owner")) { if (++n == args.length) { // "owner:password" not provided on command line results.add("owner:" + ":"); } else { results.add("owner:" + args[n]); } } else if (theArg.equalsIgnoreCase("-name")) { if (++n == args.length) { System.err.println("Missing platform name"); printUsageInfo = true; } else { results.add("name:" + args[n]); } } else if (theArg.equalsIgnoreCase("-imtp")) { if (++n == args.length) { System.err.println("Missing IMTP class"); printUsageInfo = true; } else { results.add("imtp:" + args[n]); } } else if (theArg.equalsIgnoreCase("-port")) { if (++n == args.length) { System.err.println("Missing port number"); printUsageInfo = true; } else { try { Integer.parseInt(args[n]); } catch (NumberFormatException nfe) { System.err.println("Wrong int for the port number"); printUsageInfo = true; } results.add("port:" + args[n]); } } else if (theArg.equalsIgnoreCase("-container")) { results.add(theArg); } else if (theArg.equalsIgnoreCase("-backupmain")) { results.add(theArg); } else if (theArg.equalsIgnoreCase("-gui")) { results.add(theArg); } else if (theArg.equalsIgnoreCase("-version") || theArg.equalsIgnoreCase("-v")) { results.add("-version"); } else if (theArg.equalsIgnoreCase("-help") || theArg.equalsIgnoreCase("-h")) { results.add("-help"); } else if (theArg.equalsIgnoreCase("-nomtp")) { results.add(theArg); } else if(theArg.equalsIgnoreCase("-nomobility")){ results.add(theArg); } else if (theArg.equalsIgnoreCase( "-dump")) { // new form but useful for debugging results.add(theArg); } else if (theArg.equalsIgnoreCase("-mtp")) { if (++n == args.length) { System.err.println("Missing mtp specifiers"); printUsageInfo = true; } else { results.add("mtp:" + args[n]); } } else if (theArg.equalsIgnoreCase("-aclcodec")) { if (++n == args.length) { System.err.println("Missing aclcodec specifiers"); printUsageInfo = true; } else { results.add("aclcodec:" + args[n]); } } else if (theArg.startsWith("-") && n+1 < args.length) { // Generic option results.add(theArg.substring(1)+":"+args[++n]); } else { endCommand = true; //no more options on the command line } n++; // go to the next argument } // end of while // all options, but the list of Agents, have been parsed if (endCommand) { // parse the list of agents, now --n; // go to the previous argument StringBuffer sb = new StringBuffer(); for (int i = n; i < args.length; i++) { sb.append(args[i] + " "); } results.add("agents:" + sb.toString()); } if (printUsageInfo) { results.add("-help"); } String[] newArgs = new String[results.size()]; for (int i = 0; i < newArgs.length; i++) { newArgs[i] = (String) results.elementAt(i); } return newArgs; } /** * Test if an argument actually references a file. * @param arg The argument to test. * @return True if it does, false otherwise. */ protected boolean isFileName(String arg) { File testFile = new File(arg); return testFile.exists(); } /** * Show usage information. * @param out The print stream to output to. */ public void usage(PrintStream out) { out.println("Usage: java jade.Boot [options] [agent specifiers]"); out.println(""); out.println("where options are:"); out.println(" -host <host name>\tHost where RMI registry for the platform is located"); out.println(" -port <port number>\tThe port where RMI registry for the platform resides"); out.println(" -gui\t\t\tIf specified, a new Remote Management Agent is created."); out.println(" -container\t\tIf specified, a new Agent Container is added to an existing platform"); out.println(" \t\t\tOtherwise a new Agent Platform is created"); out.println(" -conf\t\t\tShows the gui to set the configuration properties to start JADE."); out.println(" -conf <file name>\tStarts JADE using the configuration properties read in the specified file."); out.println(" -dump\t\t\tIf specified, lists boot's current properties."); out.println(" -version\t\tIf specified, current JADE version number and build date is printed."); out.println(" -mtp\t\t\tSpecifies a list, separated by ';', of external Message Transport Protocols to be activated."); out.println(" \t\t\tBy default the HTTP-MTP is activated on the main-container and no MTP is activated on the other containers."); out.println(" -nomtp\t\tHas precedence over -mtp and overrides it."); out.println(" \t\t\tIt should be used to override the default behaviour of the main-container (by default the -nomtp option unselected)."); out.println(" -aclcodec\t\tSpecifies a list, separated by ';', of ACLCodec to use. By default the string codec is used."); out.println(" -name <platform name>\tThe symbolic platform name specified only for the main container."); out.println(" -owner <username:password>\tThe owner of a container or platform."); out.println(" -nomobility\t\tIf specified, disables the mobility and cloning support for the container."); out.println(" -auth <Simple|Unix|NT|Kerberos>\tThe user authentication module to be used."); out.println(" -help\t\t\tPrints out usage informations."); out.println(" -<key> <value>\t\tApplication specific options."); out.println(""); out.print("An agent specifier is composed of an agent name and an agent class, separated by \""); out.println(NAME2CLASS_SEPARATOR + "\""); out.println(""); out.println("Take care that the specified agent name represents only the local name of the agent."); out.println("Its guid (globally unique identifier) is instead assigned by the AMS after concatenating"); out.println("the home agent platform identifier (e.g. john@foo.cselt.it:1099/JADE)"); out.println(""); out.println("Examples:"); out.println(" Connect to default platform, starting an agent named 'peter'"); out.println(" implemented in 'myAgent' class:"); out.println(" \tjava jade.Boot -container peter:myAgent"); out.println(""); out.println(" Connect to a platform on host zork.zot.za, on port 1100,"); out.println(" starting two agents"); out.println(" java jade.Boot -container -host zork.zot.za -port 1100 peter:heAgent paula:sheAgent"); out.println(""); out.println(" Create an Agent Platform and starts an agent on the local Agent Container"); out.println(" \tjava jade.Boot Willy:searchAgent"); out.println(""); System.exit(0); } /** * List boot properties to provided print stream. * @param out PrintStream to list properties to. */ public void listProperties(PrintStream out) { out.println("---------- Jade Boot property values ----------"); for (Enumeration e = properties.sortedKeys(); e.hasMoreElements(); ) { String key = (String) e.nextElement(); out.println(key + "=" + properties.getProperty(key)); } out.println("-----------------------------------------------"); } /** * Get boot properties. * @return ExtendedProperties Boot properties. */ public ExtendedProperties getProperties() { return properties; } /** * Set boot properties. Copies provided properties over existing ones. * @param updates Properties to be copied. */ public void setProperties(ExtendedProperties updates) throws BootException { properties.copyProperties(updates); profile.setArgProperties(properties); } /** * This method verifies the configuration properties and eventually correct them. * It checks if the port number is a number greater than 0 otherwise it throws a BootException, * and if the -nomtp has been set, then delete some other mtp wrongly set. * If the user wants to start a platform the host * must be the local host so if a different name is speficied it * will be corrected and an exception will be thrown. * @throws BootException if anything is found to be inconsistent. */ protected void check() throws BootException { try { Integer.parseInt(profile.getParameter(Profile.MAIN_PORT, Integer.toString(BootProfileImpl.DEFAULT_PORT))); } catch (NumberFormatException nfe) { throw new BootException("Malformed port number"); } // Remove the MTP list if '-nomtp' is specified if (profile.getBooleanProperty(BootProfileImpl.NOMTP_KEY, false)) { if (profile.getParameter(BootProfileImpl.MTP_KEY, null) != null) { throw new BootException("Error: If noMTP is set, you can't specify MTPs."); } } // Check that the local-host is actually local String localHost = profile.getParameter(Profile.LOCAL_HOST, null); if (localHost != null && !Profile.isLocalHost(localHost)) { throw new BootException("Error: Not possible to launch JADE a remote host ("+properties.getProperty(Profile.LOCAL_HOST)+"). Check the -host and -local-host options."); } } }