/**
*
* 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.util.Enumeration; // J2ME CLDC OK
import java.util.Vector; // J2ME CLDC OK
import java.util.Stack; // J2ME CLDC OK
import jade.core.Specifier;
import jade.util.leap.List;
import jade.util.leap.ArrayList;
/**
* This class provides a number of methods that help in parsing
* the command line. It is also used by the StartNewAgent class of the RMA.
* @version $Date: 2010-04-08 15:54:18 +0200 (gio, 08 apr 2010) $ $Revision: 6298 $
**/
public class BootHelper {
/** These constants are used by the mini-parser implemented by the method T2 */
private static final int BETWEENTOKENS = 0;
private static final int WORDTOKEN = 1;
private static final int STRINGTOKEN = 2;
private static final int ESCAPE = 3;
/**
* Reads the passed String and decompose it into a vector of Strings.
* Each String is a token of type agentName: or className( or argument
* This method is declared public because it is currently used by
* <code>jade.tools.rma.StartNewAgentAction</code>
*
* @param s1 The source string.
* @param keepquote when true no char is removed,
* apart from blanks between tokens.
* when false, quote chars are removed and also escaped quotes become
* just quotes.
*
* @return The vector of strings.
*/
public Vector T2(String s1, boolean keepquote) {
Vector l = new Vector();
if (s1 == null) {
return l;
}
int state = BETWEENTOKENS;
Stack returnState = new Stack();
StringBuffer token = new StringBuffer();
int i;
for (i = 0; i < s1.length(); i++) {
char ch = s1.charAt(i);
switch (state) {
case BETWEENTOKENS :
if (ch != ' ') {
if (ch == '"') {
state = STRINGTOKEN;
if (keepquote) {
token.append(ch);
}
returnState.push(new Integer(BETWEENTOKENS));
} else if (ch == '\\') {
state = ESCAPE;
returnState.push(new Integer(BETWEENTOKENS));
} else {
token.append(ch);
state = WORDTOKEN;
}
} else if (token.length() > 0) {
l.addElement(token.toString());
token = new StringBuffer();
}
break;
case WORDTOKEN :
if (ch == ' ') {
state = BETWEENTOKENS;
l.addElement(token.toString());
token = new StringBuffer();
} else if (ch == '"') {
state = STRINGTOKEN;
if (keepquote) {
token.append(ch);
}
returnState.push(new Integer(WORDTOKEN));
} else if (ch == '\\') {
state = ESCAPE;
returnState.push(new Integer(WORDTOKEN));
} else {
token.append(ch);
}
break;
case STRINGTOKEN :
if (ch == '"') {
if (keepquote) {
token.append(ch);
}
state = ((Integer) returnState.pop()).intValue();
} else if (ch == '\\') {
state = ESCAPE;
returnState.push(new Integer(STRINGTOKEN));
} else {
token.append(ch);
}
break;
case ESCAPE :
if ((ch != '"') || (keepquote)) {
token.append('\\');
}
token.append(ch);
state = ((Integer) returnState.pop()).intValue();
break;
}
}
if (token.length() > 0) {
l.addElement(token.toString());
}
return l;
}
/**
* parse an array of Strings and return an Iterator of
* <code>Specifier</code>
* This method is declared public because it is currently used by
* <code>jade.tools.rma.StartNewAgentAction</code>
* @param args is an array of string of agent specifiers of the
* type "name:class(arguments)"
* @return an Iterator over a List of <code>Specifier</code>
*/
public Enumeration getCommandLineAgentSpecifiers(Vector args) {
Vector all = new Vector();
int i = 0;
while (i < args.size()) { //1
String cur = (String) args.elementAt(i);
// search for the agent name
int index1 = cur.indexOf(':');
if ((index1 > 0) && (index1 < (cur.length() - 1))) { //2
// in every cycle we generate a new object Specifier
Specifier as = new Specifier();
as.setName(cur.substring(0, index1));
// set the agent class
int index2 = cur.indexOf('(', index1);
if (index2 < 0) {
// no arguments to this agent
as.setClassName(cur.substring(index1 + 1, cur.length()));
} else { //3
as.setClassName(cur.substring(index1 + 1, index2));
// having removed agentName,':',agentClass, and '(',
// what remains is the firstArgument of the Agent
// search for all the arguments up to the closed parenthesis
List asArgs = new ArrayList();
String nextArg =
cur.substring(index2 + 1); //from the '(' to the end
while (!getAgentArgument(nextArg, asArgs)) { //4
i++;
if (i >= args.size()) { //5
System.err.println(
"Missing closed bracket to delimit agent arguments. The system cannot be launched");
//FIXME printUsageInfo = true;
} //5
nextArg = (String) args.elementAt(i);
} // 4
Object agentArgs[] = new Object[asArgs.size()];
for (int i3 = 0; i3 < asArgs.size(); i3++) {
agentArgs[i3] = (String) asArgs.get(i3);
}
as.setArgs(agentArgs);
} // 3
all.addElement(as);
} //2
i++;
} //1
return all.elements();
} // 0
/**
* @param arg is the argument passed on the command line
* @param as is the List where arguments must be added
* @return true if this was the last argument, i.e. it found a closed bracket
*/
public boolean getAgentArgument(String arg, List as) {
boolean isLastArg = false;
String realArg;
// if the last char is a closed parenthesis, then this is the last argument
if (arg.endsWith(")")) {
if (arg.endsWith("\\)")) {
isLastArg = false;
realArg = arg;
} else {
isLastArg = true;
realArg = arg.substring(0, arg.length()
- 1); //remove last parenthesis
}
} else {
isLastArg = false;
realArg = arg;
}
if (realArg.length() > 0) {
// replace the escaped closed parenthesis with a simple parenthesis
as.add(replace(realArg, "\\)", ")"));
}
return isLastArg;
}
private String replace(String arg, String oldStr, String newStr) {
int index = arg.indexOf(oldStr);
String tmp = arg;
while (index >= 0) {
tmp = tmp.substring(0, index) + newStr
+ tmp.substring(index + oldStr.length());
index = tmp.indexOf(oldStr);
}
return tmp;
}
}