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 sl;
25
26
27 import java.io.Serializable;
28 import java.io.Writer;
29 import java.io.IOException;
30
31 import java.util.List;
32 import java.util.ArrayList;
33 import java.util.Iterator;
34 import java.util.Properties;
35 import java.util.Enumeration;
36
37 /***
38 This class represents a JADE Agent Identifier. JADE internal agent
39 tables use this class to record agent names and addresses.
40 */
41 public class AID implements Cloneable, Comparable, Serializable {
42
43 /***
44 @serial
45 */
46 private String name = new String();
47
48 /***
49 @serial
50 */
51 private List addresses = new ArrayList();
52
53 /***
54 @serial
55 */
56 private List resolvers = new ArrayList();
57
58 /***
59 @serial
60 */
61 private Properties userDefSlots = new Properties();
62
63
64 /***
65 * Constructs an Agent-Identifier whose slot name is set to an empty string
66 */
67 public AID() {
68 this("");
69 }
70
71 /*** Constructor for an Agent-identifier
72 * @param guid is the Globally Unique identifer for the agent. The slot name
73 * assumes that value in the constructed object.
74 */
75 public AID(String guid) {
76 name = guid;
77 }
78
79 /***
80 * This method permits to set the symbolic name of an agent.
81 * This must be unique within the HAP of the agent.
82 */
83 public void setName(String n){
84 name = n;
85 }
86
87 /***
88 * This method returns the name of the agent.
89 */
90 public String getName(){
91 return name;
92 }
93
94 /***
95 * This method permits to add a transport address where
96 * the agent can be contacted.
97 */
98 public void addAddresses(String url) {
99 addresses.add(url);
100 }
101
102 /***
103 * To remove a transport address.
104 * @param url the address to remove
105 * @return true if the addres has been found and removed, false otherwise.
106 */
107 public boolean removeAddresses(String url) {
108 return addresses.remove(url);
109 }
110
111 /***
112 * To remove alla addresses of the agent
113 */
114 public void clearAllAddresses(){
115 addresses.clear();
116 }
117
118 /***
119 * Returns an iterator of all the addresses of the agent.
120 * @see java.util.Iterator
121 */
122 public Iterator getAllAddresses(){
123 return addresses.iterator();
124 }
125
126 /***
127 * This method permits to add the AID of a resolver (an agent where name
128 * resolution services for the agent can be contacted)
129 */
130 public void addResolvers(AID aid){
131 resolvers.add(aid);
132 }
133
134 /***
135 * To remove a resolver.
136 * @param aid the AID of the resolver to remove
137 * @return true if the resolver has been found and removed, false otherwise.
138 */
139 public boolean removeResolvers(AID aid){
140 return resolvers.remove(aid);
141 }
142
143 /***
144 * To remove all resolvers.
145 */
146 public void clearAllResolvers(){
147 resolvers.clear();
148 }
149
150 /***
151 * Returns an iterator of all the resolvers.
152 * @see java.util.Iterator
153 */
154 public Iterator getAllResolvers() {
155 return resolvers.iterator();
156 }
157
158 /***
159 * To add a user defined slot (a pair key, value).
160 * @param key the name of the property
161 * @param value the corresponding value of the property
162 */
163 public void addUserDefinedSlot(String key, String value){
164 userDefSlots.setProperty(key, value);
165 }
166
167
168 /***
169 * Returns an array of string containing all the addresses of the agent
170 */
171 public String[] getAddressesArray() {
172 Object[] objs = addresses.toArray();
173 String[] result = new String[objs.length];
174 System.arraycopy(objs, 0, result, 0, objs.length);
175 return result;
176 }
177
178 /***
179 * Returns an array containing all the AIDs of the resolvers.
180 */
181 public AID[] getResolversArray() {
182 Object[] objs = resolvers.toArray();
183 AID[] result = new AID[objs.length];
184 System.arraycopy(objs, 0, result, 0, objs.length);
185 return result;
186 }
187
188 /***
189 * Returns the user-defined slots as properties.
190 * @return all the user-defined slots as a <code>java.util.Properties</code> java Object.
191 * @see java.util.Properties
192 */
193 public Properties getAllUserDefinedSlot(){
194 return userDefSlots;
195 }
196
197 /***
198 * This method is called from ACLMessage in order to create
199 * the String encoding of an ACLMessage.
200 */
201 public void toText(Writer w) {
202 try {
203 w.write("( agent-identifier ");
204 if ((name!=null)&&(name.length()>0))
205 w.write(" :name " + name);
206 if (addresses.size()>0)
207 w.write(" :addresses (sequence ");
208 for (int i=0; i<addresses.size(); i++)
209 try {
210 w.write((String)addresses.get(i) + " ");
211 } catch (IndexOutOfBoundsException e) {e.printStackTrace();}
212 if (addresses.size()>0)
213 w.write(")");
214 if (resolvers.size()>0)
215 w.write(" :resolvers (sequence ");
216 for (int i=0; i<resolvers.size(); i++) {
217 try {
218 ((AID)resolvers.get(i)).toText(w);
219 } catch (IndexOutOfBoundsException e) {e.printStackTrace();}
220 w.write(" ");
221 }
222 if (resolvers.size()>0)
223 w.write(")");
224 Enumeration e = userDefSlots.propertyNames();
225 String tmp;
226 while (e.hasMoreElements()) {
227 tmp = (String)e.nextElement();
228 w.write(" " + tmp + " " + userDefSlots.getProperty(tmp));
229 }
230 w.write(")");
231 w.flush();
232 } catch(IOException ioe) {
233 ioe.printStackTrace();
234 }
235 }
236
237 /***
238 * Returns the symbolic name of the agent.
239 */
240 public String toString() {
241 return name;
242 }
243
244 /***
245 * Clone the AID object.
246 */
247 public synchronized Object clone() {
248 AID result;
249 try {
250 result = (AID)super.clone();
251 }
252 catch(CloneNotSupportedException cnse) {
253 result = new AID();
254
255 }
256 return result;
257 }
258
259 /***
260 Equality operation. This method compares an <code>AID</code> object with
261 another or with a Java <code>String</code>. The comparison is case
262 insensitive.
263 @param o The Java object to compare this <code>AID</code> to.
264 @return <code>true</code> if one of the following holds:
265 <ul>
266 <li> The argument <code>o</code> is an <code>AID</code> object
267 with the same <em>GUID</em> in its name slot (apart from
268 differences in case).
269 <li> The argument <code>o</code> is a <code>String</code> that is
270 equal to the <em>GUID</em> contained in the name slot of this
271 Agent ID (apart from differences in case).
272 </ul>
273 */
274 public boolean equals(Object o) {
275
276 if(o instanceof String) {
277 return name.equalsIgnoreCase((String)o);
278 }
279 try {
280 AID id = (AID)o;
281 return name.equalsIgnoreCase(id.name);
282 }
283 catch(ClassCastException cce) {
284 return false;
285 }
286
287 }
288
289
290 /***
291 Comparison operation. This operation imposes a total order
292 relationship over Agent IDs.
293 @param o Another <code>AID</code> object, that will be compared
294 with the current <code>AID</code>.
295 @return -1, 0 or 1 according to the lexicographical order of the
296 <em>GUID</em> of the two agent IDs, apart from differences in
297 case.
298 */
299 public int compareTo(Object o) {
300 AID id = (AID)o;
301 return name.compareToIgnoreCase(id.name);
302 }
303
304
305 /***
306 Hash code. This method returns an hash code in such a way that two
307 <code>AID</code> objects with equal names or with names differing
308 only in case have the same hash code.
309 @return The hash code for this <code>AID</code> object.
310 */
311 public int hashCode() {
312 return name.toLowerCase().hashCode();
313 }
314
315 /***
316 * Returns the local name of the agent (without the HAP)
317 */
318 String getLocalName() {
319 int atPos = name.lastIndexOf('@');
320 if(atPos == -1)
321 return name;
322 else
323 return name.substring(0, atPos);
324 }
325
326 /***
327 * Returns the HAP of the agent.
328 */
329 String getHap() {
330 int atPos = name.lastIndexOf('@');
331 if(atPos == -1)
332 return name;
333 else
334 return name.substring(atPos + 1);
335 }
336
337 }