/** * *************************************************************** * 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.core; import java.util.Enumeration; import java.util.Vector; /** * This class represent a specifier and collects a name, a className, * and an array of arguments. Profile specifiers are used to describe * several kinds of complex information when configuring JADE * (e.g. MTPs to install, agents to start up, kernel services to * activate). * * The general string format for a specifier is * <p><code>name<b>:</b>className<b>(</b><i>separated arglist</i><b>)</b></code></p> * The separated argument list uses a separator character that can be configured when * invoking parsing-related utility methods. * * @author LEAP */ public class Specifier { public static final char SPECIFIER_SEPARATOR = ';'; public static final String NULL_SPECIFIER_LIST = "null"; private String name = null; private String className = null; private Object[] args = null; /** Set the name for this specifier object. @param n The name to give to this specifier. */ public void setName(String n) { name = n; } /** Retrieve the name for this specifier object. @return The name of the specifier, if one was set, or <code>null</code> otherwise. */ public String getName() { return name; } /** Set the name of the class of this specifier. @param cn The class name to assign to the specifier object. */ public void setClassName(String cn) { className = cn; } /** Retrieve the class name of this specifier. @return The class name of the specifier, if one was set, or <code>null</code> otherwise. */ public String getClassName() { return className; } /** Set the argument list for this specifier object. @param a An object array containing the argument list for this specifier. */ public void setArgs(Object[] a) { args = a; } /** Retrieve the argument list for this specifier. @return An object array containing the argument list, if one was set, or <code>null</code> otherwise. */ public Object[] getArgs() { return args; } /** * This method is used by Boot, ProfileImpl, and RMA in order * to have a String representation of this Specifier according to the * format <code>name:className(arg1 arg2 argn)</code> * * @return A string representation of this specifier, according to * the format above. **/ public String toString() { // TAKE CARE: do not change this method otherwise Boot might fail StringBuffer tmp = new StringBuffer(); if (name != null) { tmp.append(name); tmp.append(":"); } if (className != null) { tmp.append(className); } if (args != null) { tmp.append("("); for (int i=0; i<args.length; i++) { tmp.append(args[i]); if (i<args.length-1) { //#ALL_EXCLUDE_BEGIN tmp.append(" "); //#ALL_EXCLUDE_END /*#ALL_INCLUDE_BEGIN tmp.append(","); //#ALL_INCLUDE_END*/ } } tmp.append(")"); } return tmp.toString(); } /** This static utility method can parse the string representation of a list of specifiers. The general format of a specifier is used, with a comma as argument separator, i.e.: <p><code>name<b>:</b>className<b>(</b><i>comma-separated arglist</i><b>)</b></code></p> While comma is the separator character within a specifier arguments, the semicolon is used to separate the different specifiers in the list. @param specsLine The string containing the representation of the specifier list, according to the format above. @return A vector containing the parsed specifiers. */ public static Vector parseSpecifierList(String specsLine) throws Exception { Vector specs = parseList(specsLine, SPECIFIER_SEPARATOR); for (int i = 0; i < specs.size(); ++i) { String s = (String) specs.elementAt(i); if (s.length() > 0) { specs.setElementAt(parseSpecifier(s, ','), i); } else { specs.removeElementAt(i--); } } return specs; } /** * This static utility method produces a string representation of a list of Specifier objects. */ public static String encodeSpecifierList(Vector v){ return encodeList(v, SPECIFIER_SEPARATOR); } public static final Vector parseList(String list, char delimiter) { Vector v = new Vector(); if (list != null && !list.equals("") && !list.equals(NULL_SPECIFIER_LIST)) { // Copy the string with the specifiers into an array of char char[] specsChars = new char[list.length()]; list.getChars(0, list.length(), specsChars, 0); // Create the StringBuffer to hold the first element StringBuffer sbElement = new StringBuffer(); int i = 0; while (i < specsChars.length) { char c = specsChars[i]; if (c != delimiter) { sbElement.append(c); } else { // The element is terminated. v.addElement(sbElement.toString().trim()); // Create the StringBuffer to hold the next element sbElement = new StringBuffer(); } ++i; } // Append the last element v.addElement(sbElement.toString().trim()); } return v; } public static String encodeList(Vector v, char delimiter){ StringBuffer sb = new StringBuffer(); Enumeration elements = v.elements(); while(elements.hasMoreElements()){ sb.append(elements.nextElement()); if(elements.hasMoreElements()){ sb.append(delimiter); } } return sb.toString(); } /** * Utility method that parses a stringified object specifier in the form * <p><code>name<b>:</b>className<b>(</b><i>separated arglist</i><b>)</b></code></p> * a Specifier object. * Both the name and the list of arguments are optional. * * @param specString A string containing the representation of the * specifier, according to the format above. * @param argsDelimiter The character to use as a delimiter within the argument list. * @return A specifier object, built according to the parsed information. */ public static Specifier parseSpecifier(String specString, char argsDelimiter) throws Exception { Specifier s = new Specifier(); // NAME int index1 = specString.indexOf(':'); int index2 = specString.indexOf('('); if (index2 < 0) { index2 = 99999; } if (index1 > 0 && index1 < index2) { // The name exists, colon exists, and is followed by the class name s.setName(specString.substring(0, index1)); // Skip colon index1++; } else { // No name specified index1 = 0; } // CLASS index2 = specString.indexOf('(', index1); if (index2 < 0) { // No arguments --> just add the class name s.setClassName(specString.substring(index1)); } else { // There are arguments --> add the class name and then parse the args s.setClassName(specString.substring(index1, index2)); // ARGUMENTS if (!specString.endsWith(")")) { throw new Exception("Incorrect specifier \""+specString+"\". Missing final parenthesis"); } // Get everything is in between '(' and ')' String args = specString.substring(index2+1, specString.length()-1); s.setArgs(parseArguments(args, argsDelimiter)); } return s; } /** */ private static String[] parseArguments(String args, char argsDelimiter) { Vector argList = new Vector(); int argStart = 0; int argEnd = args.indexOf(argsDelimiter); while (argEnd >= 0) { String arg = args.substring(argStart, argEnd); argList.addElement(arg.trim()); argStart = argEnd+1; argEnd = args.indexOf(argsDelimiter, argStart); } // Last argument String arg = args.substring(argStart, args.length()); argList.addElement(arg.trim()); // Convert the List into an Array String arguments[] = new String[argList.size()]; int i = 0; for (Enumeration e = argList.elements(); e.hasMoreElements(); arguments[i++] = (String) e.nextElement()); return arguments; } }