View Javadoc

1   /******************************************************************
2   JADE - Java Agent DEvelopment Framework is a framework to develop 
3   multi-agent systems in compliance with the FIPA specifications.
4   Copyright (C) 2000 CSELT S.p.A. 
5   
6   GNU Lesser General Public License
7   
8   This library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation, 
11  version 2.1 of the License. 
12  
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  Lesser General Public License for more details.
17  
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the
20  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  Boston, MA  02111-1307, USA.
22  *****************************************************************/
23  
24  package JADE_SL;
25  
26  
27  import java.io.Writer; // FIXME: This must go away
28  import java.io.IOException; // FIXME: This must go away
29  //import java.io.StringWriter;
30  import java.util.*;
31  
32  /***
33   This class represents a JADE Agent Identifier. JADE internal agent
34   tables use this class to record agent names and addresses.
35   */
36  public class AID  {
37    
38    /***
39    @serial
40    */
41    private String name = new String();
42    
43    /***
44    @serial
45    */
46    private List addresses = new ArrayList();
47    
48    /***
49    @serial
50    */
51    private List resolvers = new ArrayList();
52    
53    /***
54    @serial
55    */
56    private Properties userDefSlots = new Properties();
57  
58  
59    /***
60     * Constructs an Agent-Identifier whose slot name is set to an empty string
61     */
62    public AID() {
63      this("",ISGUID);
64    }
65  
66    /*** Constructor for an Agent-identifier
67     * This constructor (which is deprecated), examines the name
68     * to see if the "@" chararcter is present.  If so, it calls 
69     * <code> this(name, ISGUID)<code> 
70     * otherwise it calls <code>this(name, ISLOCALNAME)</code>
71     * This ensures better compatibility with JADE2.2 code.
72     * @param guid is the Globally Unique identifer for the agent. The slot name
73     * assumes that value in the constructed object. 
74     * @deprecated This constructor might generate a wrong AID, if
75     * the passed parameter is not a guid (globally unique identifier), but
76     * the local name of an agent (e.g. "da0"). 
77     * @see AID#AID(String boolean)
78     */
79    public AID(String guid) {
80        this(guid,ISGUID);
81    }
82  
83  
84      /*** Constructor for an Agent-identifier
85       * @param name is the value for the slot name for the agent. 
86       * @param isGUID indicates if the passed <code>name</code>
87       * is already a globally unique identifier or not. Two
88       * constants <code>ISGUID</code>, <code>ISLOCALNAME</code>
89       * have also been defined for setting a value for this parameter.
90       * If the name is a local name, then the HAP (Home Agent Platform)
91       * is concatenated to the name, separated by  "@".
92       **/
93      public AID(String name, boolean isGUID) {
94  	// initialize the static variable atHAP, if not yet initialized
95  	if (atHAP == null)
96  	    atHAP = "@"+zeus.util.SystemProps.getProperty("HAP.address");
97  	if (isGUID)
98  	    setName(name);
99  	else
100 	    setLocalName(name);
101     }
102 
103     /*** constant to be used in the constructor of the AID **/
104     public static final boolean ISGUID = true;
105     /*** constant to be used in the constructor of the AID **/
106     public static final boolean ISLOCALNAME = false;
107 
108     /*** private variable containing the right part of a local name **/
109     private static String atHAP = null; 
110 
111   /***
112   * This method permits to set the symbolic name of an agent.
113   * The passed parameter must be a GUID and not a local name. 
114   */
115   public void setName(String n){
116     name = n.trim();
117   }
118 
119   /***
120   * This method permits to set the symbolic name of an agent.
121   * The passed parameter must be a local name. 
122   */
123   public void setLocalName(String n){
124     name = n.trim();
125     if ((name != null) && (!name.endsWith(atHAP))) 
126 	name = name.concat(atHAP); 
127   }
128 
129   /***
130   * This method returns the name of the agent.
131   */
132   public String getName(){
133     return name;
134   }
135 
136   /***
137   * This method permits to add a transport address where 
138   * the agent can be contacted.
139   * The address is added only if not yet present
140   */
141   public void addAddresses(String url) {
142   	if (!addresses.contains(url)) {
143 	    addresses.add(url);
144   	}
145   }
146 
147   /***
148   * To remove a transport address.
149   * @param url the address to remove
150   * @return true if the addres has been found and removed, false otherwise.
151   */
152   public boolean removeAddresses(String url) {
153     return addresses.remove(url);
154   }
155   
156   /***
157   * To remove all addresses of the agent
158   */
159   public void clearAllAddresses(){
160     addresses.clear();
161   }
162 
163   /***
164   * Returns an iterator of all the addresses of the agent.
165   * @see jade.util.leap.Iterator
166   */
167   public Iterator getAllAddresses(){
168     return addresses.iterator();
169   }
170 
171   /***
172   * This method permits to add the AID of a resolver (an agent where name 
173   * resolution services for the agent can be contacted) 
174   */
175   public void addResolvers(AID aid){
176     resolvers.add(aid);
177   }
178 
179   /***
180   * To remove a resolver.
181   * @param aid the AID of the resolver to remove
182   * @return true if the resolver has been found and removed, false otherwise.
183   */
184   public boolean removeResolvers(AID aid){
185     return resolvers.remove(aid);
186   }
187 
188   /***
189   * To remove all resolvers.
190   */
191   public void clearAllResolvers(){
192     resolvers.clear();
193   }
194 
195   /***
196   * Returns an iterator of all the resolvers.
197   * @see jade.util.leap.Iterator
198   */
199   public Iterator getAllResolvers() {
200     return resolvers.iterator();
201   }
202 
203   /***
204   * To add a user defined slot (a pair key, value).
205   * @param key the name of the property
206   * @param value the corresponding value of the property
207   */
208   public void addUserDefinedSlot(String key, String value){
209     userDefSlots.setProperty(key, value);
210   }
211 
212   
213   /***
214   * Returns an array of string containing all the addresses of the agent
215   */
216   public String[] getAddressesArray() {
217     Object[] objs = addresses.toArray();
218     String[] result = new String[objs.length];
219     System.arraycopy(objs, 0, result, 0, objs.length);
220     return result;
221   }
222 
223   /***
224   * Returns an array containing all the AIDs of the resolvers.
225   */
226   public AID[] getResolversArray() {
227     Object[] objs = resolvers.toArray();
228     AID[] result = new AID[objs.length];
229     System.arraycopy(objs, 0, result, 0, objs.length);
230     return result;
231   }
232 
233   /***
234   * Returns the user-defined slots as properties. 
235   * @return all the user-defined slots as a <code>jade.util.leap.Properties</code> java Object.
236   * @see jade.util.leap.Properties
237   */
238   public Properties getAllUserDefinedSlot(){
239     return userDefSlots;
240   }
241 
242 
243     /***
244      * @return the String full representation of this AID
245      **/
246     public String toString() {
247 	StringBuffer s = new StringBuffer("( agent-identifier ");
248 	if ((name!=null)&&(name.length()>0)) {
249 	    s.append(" :name ");
250 			s.append(name);
251 	}
252 	if (addresses.size()>0)
253 	    s.append(" :addresses (sequence ");
254 	for (int i=0; i<addresses.size(); i++)
255 	    try {
256 				s.append((String)addresses.get(i));
257 				s.append(" ");
258 	    } 
259 	    catch (IndexOutOfBoundsException e) {e.printStackTrace();}
260 	if (addresses.size()>0)
261 	    s.append(")");
262 	if (resolvers.size()>0)
263 	    s.append(" :resolvers (sequence ");
264 	for (int i=0; i<resolvers.size(); i++) { 
265 	    try {
266 				s.append(resolvers.get(i).toString());
267 	    } 
268 	    catch (IndexOutOfBoundsException e) {e.printStackTrace();}
269 	    s.append(" ");
270 	}
271 	if (resolvers.size()>0)
272 	    s.append(")");
273 	Enumeration e = userDefSlots.propertyNames();
274 	String tmp;
275 	while (e.hasMoreElements()) {
276 	    tmp = (String)e.nextElement();
277 	    s.append(" :X-");
278 	    s.append(tmp);
279 	    s.append(" ");
280 	    s.append(userDefSlots.getProperty(tmp));
281 	}
282 	s.append(")");
283 	return s.toString();
284     }
285 
286   /***
287    * This method is called from ACLMessage in order to create
288    * the String encoding of an ACLMessage.
289    * @deprecated replaced by the method toString
290    */
291   public void toText(Writer w) {
292   try {
293       w.write(toString());
294       w.flush();
295   } catch(IOException ioe) {
296     ioe.printStackTrace();
297   }
298   }
299 
300 
301 
302   /***
303   * Clone the AID object.
304   */
305     public synchronized Object clone() {
306         AID      result = new AID(this.name);
307 
308         result.addresses = (ArrayList)((ArrayList)addresses).clone();
309 
310         result.resolvers = (ArrayList)((ArrayList)resolvers).clone();
311 
312         // Copying user defined slots
313         //Enumeration enum = userDefSlots.propertyNames();
314         //while (enum.hasMoreElements()) {
315         //    String key = (String) enum.nextElement();
316         //    result.addUserDefinedSlot(key, 
317         //                              (String) userDefSlots.getProperty(key));
318         //}
319         result.userDefSlots = userDefSlots;
320 
321         return result;
322     } 
323   /*public synchronized Object clone() {
324     AID result;
325     try {
326       result = (AID)super.clone();
327     }
328     catch(CloneNotSupportedException cnse) {
329       result = new AID();
330       // throw new InternalError(); // This should never happen
331     }
332     return result;
333   }
334 	*/
335 	
336   /***
337     Equality operation. This method compares an <code>AID</code> object with
338     another or with a Java <code>String</code>. The comparison is case
339     insensitive.
340     @param o The Java object to compare this <code>AID</code> to.
341     @return <code>true</code> if one of the following holds:
342     <ul>
343     <li> The argument <code>o</code> is an <code>AID</code> object
344     with the same <em>GUID</em> in its name slot (apart from
345     differences in case).
346     <li> The argument <code>o</code> is a <code>String</code> that is
347     equal to the <em>GUID</em> contained in the name slot of this
348     Agent ID (apart from differences in case).
349     </ul>
350   */
351   public boolean equals(Object o) {
352 
353       if (o == null)
354 	  return false;
355     if(o instanceof String) {
356       return CaseInsensitiveString.equalsIgnoreCase(name, (String)o);
357     }
358     try {
359       AID id = (AID)o;
360       return CaseInsensitiveString.equalsIgnoreCase(name, id.name);
361     }
362     catch(ClassCastException cce) {
363       return false;
364     }
365 
366   }
367 
368 
369   /***
370      Comparison operation. This operation imposes a total order
371      relationship over Agent IDs.
372      @param o Another <code>AID</code> object, that will be compared
373      with the current <code>AID</code>.
374      @return -1, 0 or 1 according to the lexicographical order of the
375      <em>GUID</em> of the two agent IDs, apart from differences in
376      case.
377   */
378   public int compareTo(Object o) {
379     AID id = (AID)o;
380     return name.toLowerCase().toUpperCase().compareTo(id.name.toLowerCase().toUpperCase());
381   }
382 
383 
384   /***
385     Hash code. This method returns an hash code in such a way that two
386     <code>AID</code> objects with equal names or with names differing
387     only in case have the same hash code.
388     @return The hash code for this <code>AID</code> object.
389   */
390   public int hashCode() {
391     return name.toLowerCase().hashCode();
392   }
393 
394   /***
395   * Returns the local name of the agent (without the HAP).
396   * If the agent is not local, then the method returns its GUID.
397   */
398   public String getLocalName() {
399     int atPos = name.lastIndexOf('@');
400     if(atPos == -1)
401       return name;
402     else
403       return name.substring(0, atPos);
404   }
405 
406   /***
407   * Returns the HAP of the agent.
408   */
409   String getHap() {
410     int atPos = name.lastIndexOf('@');
411     if(atPos == -1)
412       return name;
413     else
414       return name.substring(atPos + 1);
415   }
416 
417 }