/** * * 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. * */ package jade; //#APIDOC_EXCLUDE_FILE //#J2ME_EXCLUDE_FILE import java.net.InetAddress; import java.util.Enumeration; // J2ME CLDC OK import java.util.Vector; // J2ME CLDC OK import jade.util.leap.List; import jade.util.leap.ArrayList; import jade.util.leap.Iterator; import jade.util.leap.Properties; import jade.util.ExtendedProperties; import jade.util.PropertiesException; import jade.core.ProfileImpl; import jade.core.Profile; import jade.core.Specifier; /** * A profile implementation enhanced to support boot's * argument parsing. This class serves as the bridge between * boot properties and profile properties. It defines a * collection of property keys which correspond to boot * argument names. These are used to access the boot properties * from the argument properties. The class Profile defines * a similar collection of keys which are used to access profile * properties. * @author Dick Cowan - HP Labs * @version $Date: 2010-04-19 17:42:22 +0200 (lun, 19 apr 2010) $ $Revision: 6323 $ */ public class BootProfileImpl extends ProfileImpl { public static final String ACLCODEC_KEY = "aclcodec"; public static final String CONF_KEY = "conf"; public static final String CONTAINER_KEY = "container"; public static final String DUMP_KEY = "dump"; public static final String GUI_KEY = "gui"; public static final String HELP_KEY = "help"; public static final String MTP_KEY = "mtp"; public static final String NOMTP_KEY = "nomtp"; public static final String NAME_KEY = "name"; public static final String LOGIN_KEY = "auth"; public static final String SMHOST_KEY = "smhost"; public static final String SMPORT_KEY = "smport"; public static final String VERSION_KEY = "version"; public static final String NOMOBILITY_KEY = "nomobility"; ExtendedProperties argProp = null; BootHelper helper = new BootHelper(); /** * Construct default profile with empty argument properties */ public BootProfileImpl() { // creates the default profile super(true); argProp = new ExtendedProperties(); } /** * Construct profile with specified arguments * @param args Boot arguments */ public BootProfileImpl(String[] args) throws PropertiesException { this(); ExtendedProperties properties = new ExtendedProperties(args); bootProps = (Properties)properties.clone(); setArgProperties(properties); } /** * Return the properties collection which resulted from the arguments. * This collection is used to create/modify the underlying profile's * properties. * @return ExtendedProperties The argument property collection. */ public ExtendedProperties getArgProperties() { return argProp; } /** * Copy a collection of argument properties into the existing * argument properties and then into the profile properties. * When moving between the argument properties and profile * properties different keys are required. * @param source A collection of argument properties. The * keys to this collection are from the XXX_KEY strings * defined in this class. */ public void setArgProperties(ExtendedProperties source) { argProp.copyProperties(source); String value = null; boolean flag = false; // Transfer argument properties into profile properties ExtendedProperties profileProp = (ExtendedProperties)getProperties(); boolean isMain = true; if (argProp.getProperty(Profile.MAIN) != null) { isMain = fetchAndVerifyBoolean(Profile.MAIN); } else { isMain = !fetchAndVerifyBoolean(CONTAINER_KEY); } if (isMain) { profileProp.setProperty(Profile.MAIN, "true"); } else { profileProp.setProperty(Profile.MAIN, "false"); // Since the value is false, we cancel the default done in ProfileImpl's constructor setSpecifiers(Profile.MTPS, new ArrayList(0)); // remove default MTP } String sm = argProp.getProperty(LOCAL_SERVICE_MANAGER); if(sm != null) { profileProp.setProperty(Profile.LOCAL_SERVICE_MANAGER, sm); } /* PER IL DF value = argProp.getProperty(df.KBDF_MAX_RESULTS); if (value != null) { profileProp.setProperty(df.KBDF_MAX_RESULTS, value); } value = argProp.getProperty(df.DBDF_DRIVER); if (value != null) { profileProp.setProperty(df.DBDF_DRIVER, value); } value = argProp.getProperty(df.DBDF_URL); if (value != null) { profileProp.setProperty(df.DBDF_URL, value); }*/ /* value = argProp.getProperty(PASSWD_KEY); if (value != null) { //profileProp.setProperty(Profile.PASSWD_FILE, value); } */ value = argProp.getProperty(IMTP); if (value != null) { profileProp.setProperty(Profile.IMTP, value); } String host = argProp.getProperty(MAIN_HOST); if (host != null) { profileProp.setProperty(Profile.MAIN_HOST, host); } else { host = profileProp.getProperty(Profile.MAIN_HOST); if (host == null) { host = getDefaultNetworkName(); profileProp.setProperty(Profile.MAIN_HOST, host); } } String port = argProp.getProperty(MAIN_PORT); if (port == null) { // Default for a sole main container: use the local port, or // the default port if also the local port is null. if(isFirstMain()) { port = argProp.getProperty(LOCAL_PORT); } if(port == null) { // All other cases: use the default port. port = Integer.toString(DEFAULT_PORT); } } profileProp.setProperty(Profile.MAIN_PORT, port); String localHost = argProp.getProperty(LOCAL_HOST); if(localHost == null) { // Default for a sole main container: use the MAIN_HOST property if(isFirstMain()) { localHost = host; } else { // Default for a peripheral container or an added main container: use the local host localHost = getDefaultNetworkName(); } } profileProp.setProperty(Profile.LOCAL_HOST, localHost); String localPort = argProp.getProperty(LOCAL_PORT); if(localPort == null) { // Default for a sole main container: use the MAIN_PORT property if(isFirstMain()) { localPort = port; } else { // Default for a peripheral container or an added main container: use the default port localPort = Integer.toString(DEFAULT_PORT); } } profileProp.setProperty(Profile.LOCAL_PORT, localPort); value = argProp.getProperty(REMOTE_SERVICE_MANAGER_ADDRESSES); if (value != null) { try { Vector v = Specifier.parseSpecifierList(value); // Convert the Vector into a List List l = new ArrayList(v.size()); Enumeration e = v.elements(); while (e.hasMoreElements()) { l.add(e.nextElement()); } setSpecifiers(Profile.REMOTE_SERVICE_MANAGER_ADDRESSES, l); } catch(Exception e) { e.printStackTrace(); } } value = argProp.getProperty(NAME_KEY); if (value != null) { profileProp.setProperty(Profile.PLATFORM_ID, value); } value = argProp.getProperty(LOGIN_KEY); if (value != null) { profileProp.setProperty(Profile.USERAUTH_KEY, value); } value = argProp.getProperty(MTP_KEY); if (value != null) { setSpecifiers(Profile.MTPS, parseSpecifiers(value)); } //NOMTP flag = fetchAndVerifyBoolean(NOMTP_KEY); if (flag) { // Since the value was set to true, cancel the MTP settings setSpecifiers(Profile.MTPS, new ArrayList(0)); } value = argProp.getProperty(ACLCODEC_KEY); if (value != null) { setSpecifiers(Profile.ACLCODECS, parseSpecifiers(value)); } // Get agent list (if any) value = argProp.getProperty(AGENTS); flag = fetchAndVerifyBoolean(GUI_KEY); if (flag) { // need to run RMA agent if (value != null) { value = "RMA:jade.tools.rma.rma " + value; // put before other agents } else { value = "RMA:jade.tools.rma.rma"; // only one } } if (value != null) { Vector agentVector = helper.T2(value, false); List agents = new ArrayList(); for (Enumeration e = helper.getCommandLineAgentSpecifiers(agentVector); e.hasMoreElements(); ) { agents.add((Specifier) e.nextElement()); } setSpecifiers(Profile.AGENTS, agents); } // Get service list (if any) value = argProp.getProperty(SERVICES); if(value == null) { // Remove mobility service from the list if '-nomobility' was specified flag = fetchAndVerifyBoolean(NOMOBILITY_KEY); if (flag) { value = DEFAULT_SERVICES_NOMOBILITY; } else { value = DEFAULT_SERVICES; } } setSpecifiers(Profile.SERVICES, parseSpecifiers(value)); // finally, copy into profileProp all the properties that // were present in argProp AND were not already present in profileProp. // The fact that we do not copy those properties that were already // present in profileProp is a sanity check to avoid modification // of properties that were set in the code above for (Enumeration e=argProp.keys(); e.hasMoreElements(); ) { String key = (String)e.nextElement(); if (getParameter(key,null) == null) setParameter(key, argProp.get(key).toString()); } // The following is for debugging only. Probably should not document the "dumpProfile" attribute. // Note All the jade.util.leap.ArrayList structures will only print their type unless a // toString() method were added to them. if (argProp.getBooleanProperty("dumpProfile", false)) { ArrayList aList = new ArrayList(); System.out.println("---------- Jade Boot profile property values ----------"); for (Enumeration e = profileProp.sortedKeys(); e.hasMoreElements(); ) { String key = (String) e.nextElement(); Object o = profileProp.get(key); if (o.getClass().isAssignableFrom(aList.getClass())) { System.out.print(key + "="); ArrayList al = (ArrayList)o; Iterator itor = al.iterator(); if (!itor.hasNext()) { System.out.println("<empty>"); } else { StringBuffer sb = new StringBuffer(); while (itor.hasNext()) { sb.append(itor.next()); if (itor.hasNext()) { sb.append(" "); } } System.out.println(sb.toString()); } } else { System.out.println(key + "=" + profileProp.getProperty(key)); } } System.out.println("-------------------------------------------------------"); } } /** * Fetch and verify a boolean attribute. * @param aKey The property key to check. * @return True or false depending on the attributes setting. False if attribute doesn't exist. * @throws PropertiesException if there is a value but its not either "true" or "false". */ protected boolean fetchAndVerifyBoolean(String aKey) throws PropertiesException { String value = argProp.getProperty(aKey); if (value != null) { if (value.equalsIgnoreCase("true")) { return true; } if (value.equalsIgnoreCase("false")) { return false; } throw new PropertiesException("The value of the attribute " + aKey + " must be either true or false."); } return false; } private static final String ARGUMENT_SEPARATOR = ";"; /** * Parse a String reading for a set of * <code>parameter(arg)</code> * each delimited by a <code>;</code> and no space in between. * <p> * For instance * <code>jade.mtp.iiop(50);http.mtp.http(8080)</code> is a valid * string, while <code>jade.mtp.iiop(50 80);http.mtp.http(8080)</code> * is not valid * For each object specifier, a new java object <code>Specifier</code> * is added to the passed <code>out</code> List parameter. */ public List parseSpecifiers(String str) throws PropertiesException { List result = new ArrayList(); // Cursor on the given string: marks the parser position int cursor = 0; while (cursor < str.length()) { int commaPos = str.indexOf(ARGUMENT_SEPARATOR, cursor); if (commaPos == -1) { commaPos = str.length(); } String arg = str.substring(cursor, commaPos); int openBracketPos = arg.indexOf('('); int closedBracketPos = arg.indexOf(')'); Specifier s = new Specifier(); if ((openBracketPos == -1) && (closedBracketPos == -1)) { // No brackets: no argument s.setClassName(arg); } else { // An open bracket, then something, then a closed bracket: // the class name is before the open bracket, and the // argument is between brackets. if ((openBracketPos != -1) && (closedBracketPos != -1) && (openBracketPos < closedBracketPos)) { s.setClassName(arg.substring(0, openBracketPos)); Object a[] = new Object[1]; a[0] = arg.substring(openBracketPos + 1, closedBracketPos); s.setArgs(a); } else { throw new PropertiesException( "Ill-formed specifier: mismatched parentheses."); } } cursor = commaPos + 1; result.add(s); } // while (cursor) return result; } }