KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > mobilitools > smi > api > Agency


1 /*
2 * MobiliTools: an implementation of the Object Management Group's
3 * Mobile Agent Facility specification.
4 * Copyright (C) 2003 France Telecom R&D
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * MobiliTools $Name: $
21 *
22 * Contact: mobilitools-smi@lists.debian-sf.objectweb.org
23 *
24 * Authors: Bruno Dillenseger
25 */

26
27
28 package org.objectweb.mobilitools.smi.api;
29
30
31 import org.omg.CORBA.ORB JavaDoc;
32 import org.omg.CORBA.Any JavaDoc;
33 import org.omg.CORBA.SystemException JavaDoc;
34 import org.omg.CORBA.UnknownUserException JavaDoc;
35 import org.omg.CORBA.CompletionStatus JavaDoc;
36 import org.omg.CosNaming.NamingContextPackage.*;
37 import org.omg.CfMAF.*;
38 import org.objectweb.mobilitools.util.corba.NameService;
39 import org.objectweb.mobilitools.util.corba.NameServiceException;
40 import org.objectweb.mobilitools.util.thread.ShutdownLock;
41 import org.objectweb.mobilitools.smi.idl.*;
42 import org.objectweb.mobilitools.smi.*;
43 import java.util.*;
44 import java.io.*;
45 import java.lang.reflect.*;
46
47
48 /**
49     MobiliTools $Name: $, $Id: Agency.java,v 1.1.1.1 2003/03/28 14:48:05 dillense Exp $
50     <P>
51     Instances of this class are execution environments for agents, supporting
52     lifecycle/mobility management, using and providing MAFAgentSystem implementation.
53     An agency may be created by directly instantiating this class, by running this class
54     from command line or by running the AgencyGUI class.
55     <P>
56     An agency may be customized with an <code>AgencyPersonality</code> implementation. A <I>personality</I>
57     may be declared when creating a new agency (using the appropriate constructor), or via
58     inheritance. A personality's main role is to encapsulate agents by intercepting all lifecycle callbacks defined by
59     interface MobileObject.
60     @see org.objectweb.mobilitools.smi.goodies.AgencyGUI
61     @see AgencyPersonality
62     @see MobileObject
63 */

64 public class Agency
65     extends Observable
66     implements AgentSystem, AgencyPersonality
67 {
68     /**
69         if using an agency personality, set this attribute to true if you wish
70         the agency to perform System.exit(0) when terminating the agency.
71     */

72     static protected boolean standalone = false;
73     static public final String JavaDoc NOTIFY_TERMINATE = "terminate";
74
75     /**
76         Launches a SMI agency.
77         @param args command-line arguments should specify:
78         <UL>
79             <LI>args[0] the agency unique name in the given region,
80             <LI>args[1] the region name.
81         </UL>
82         @see #Agency(String, String, ORB)
83     */

84     public static void main(String JavaDoc[] args)
85     {
86         ORB JavaDoc orb = ORB.init(args, null);
87         String JavaDoc region = null;
88         standalone = true;
89         if (args.length >= 2)
90         {
91             try
92             {
93                 new Agency(args[0], args[1], orb);
94             }
95             catch (BadOperation e)
96             {
97                 System.err.println("Name " + args[0] + " already exists in region " + args[1] + ".");
98                 System.exit(-2);
99             }
100         }
101         else
102         {
103             System.err.println("arguments: agency_name region_name");
104             System.exit(-1);
105         }
106         System.out.println("Agency " + args[0] + " available in region " + args[1] + ".");
107         orb.run();
108     }
109
110
111     // region's name
112
protected String JavaDoc my_region;
113
114     // agency's name
115
protected String JavaDoc my_name;
116
117     // object reference to the MAFAgentSystem object
118
protected _MAFAgentSystemComplementImplBase tie;
119
120     // naming service front-end
121
protected NameService my_ns;
122
123     // name of the MAFAgentSystem object in the name service
124
protected String JavaDoc my_ns_name;
125
126     // location of the agency (CosNaming URI format)
127
protected Location my_location;
128
129     // reference to the ORB object
130
protected ORB JavaDoc my_orb;
131
132     // hashed lists of hosted agents
133
protected Hashtable agentsByRef, agentsByName;
134
135     // CORBA object reference to MAFFinder
136
protected MAFFinder my_finder;
137
138     // reference to an agency personality (if any)
139
protected AgencyPersonality my_personality;
140
141     // reference to the hosting agent system
142
protected AgentSystem my_shell;
143
144     // information record about the agent system (see MAF)
145
protected AgentSystemInfo my_info;
146
147     // lock to enforce a clean agency shutdown
148
protected ShutdownLock shutdownLock;
149
150     /**
151         Create a new agency for creating and receiving agents.
152         The authority for this agency is set from the "user.name" system
153         property. The agency's MAFAgentSystem interface is bound in the
154         CORBA naming service accordingly to the region name and the
155         agency name.
156         @param name name of the agency, unique in the given region.
157         @param region name of the region the agency belongs to.
158         @throws BadOperation if the name of the agency is not accepted by the MAFFinder (name already used?).
159     */

160     public Agency(String JavaDoc name, String JavaDoc region)
161         throws BadOperation
162     {
163         this(name, region, ORB.init(new String JavaDoc[0], System.getProperties()));
164     }
165
166
167     /**
168         Create a new agency for creating and receiving agents, and
169         customize it with the provided agency personality and shell.
170         The agency's MAFAgentSystem interface is bound in the
171         CORBA naming service accordingly to the region name and the
172         agency name.
173         @param region name of the region the agency belongs to.
174         @param personality object intercepting agent lifecycle callbacks.
175         @param shell reference that will be given to the agents
176         created in or moving to this agency.
177         @param info data record describing the customized agency (see MAF).
178         This info should hold the agency's MAF name, whose identity field is taken as the
179         agency's unique name in SMI's sense.
180         @throws BadOperation if the name of the agency is not accepted by the MAFFinder (name already used).
181         @see Constants#makeAgentSystemInfo(byte[], byte[])
182     */

183     public Agency(
184         String JavaDoc region,
185         AgencyPersonality personality,
186         AgentSystem shell,
187         AgentSystemInfo info)
188         throws BadOperation
189     {
190         this(region,
191             ORB.init(new String JavaDoc[0], System.getProperties()),
192             personality,
193             shell,
194             info);
195     }
196
197
198     /**
199         Create a new agency for creating and receiving agents.
200         The authority for this agency is set from the "user.name" system
201         property. The agency's MAFAgentSystem interface is bound in the
202         CORBA naming service accordingly to the region name and the
203         agency name.
204         @param name name of the agency, unique in the given region.
205         @param region name of the region the agency belongs to.
206         @param orb the ORB object to use.
207         @throws BadOperation if the name of the agency is not accepted by the MAFFinder (name already used?).
208         @see org.omg.CORBA.ORB#init()
209     */

210     public Agency(String JavaDoc name, String JavaDoc region, ORB JavaDoc orb)
211         throws BadOperation
212     {
213         this(
214             region,
215             orb,
216             null,
217             null,
218             Constants.makeAgentSystemInfo(
219                 ((String JavaDoc)System.getProperty("user.name", "-unspecified-")).getBytes(),
220                 name.getBytes()));
221     }
222
223
224     /**
225         Create a new agency for creating and receiving agents.
226         The authority for this agency is set from the "user.name" system
227         property. The agency's MAFAgentSystem interface is bound in the
228         CORBA naming service accordingly to the region name and the
229         agency name.
230         @param region name of the region the agency belongs to.
231         @param orb the ORB object to use.
232         @param personality the agency personality that will handle the agents. A null value means
233         no personality (i.e. current agency instance).
234         @param shell agency reference that will be given to the hosted agents after creation or move.
235         A null value means no specific shell, in which case the host agency will be used.
236         @param info the AgentSystemInfo information record about the agent system personality.
237         This info should hold the agency's MAF name, whose identity field is taken as the
238         agency's unique name in SMI's sense.
239         @throws BadOperation if the name of the agency is not accepted by the MAFFinder (already used?).
240         @see org.omg.CORBA.ORB#init()
241         @see Constants#makeAgentSystemInfo(byte[], byte[])
242     */

243     public Agency(
244         String JavaDoc region,
245         ORB JavaDoc orb,
246         AgencyPersonality personality,
247         AgentSystem shell,
248         AgentSystemInfo info)
249         throws BadOperation
250     {
251         shutdownLock = new ShutdownLock();
252         agentsByRef = new Hashtable();
253         agentsByName = new Hashtable();
254         my_info = info;
255         my_name = new String JavaDoc(info.agent_system_name.identity);
256         my_region = region;
257         my_location = new Location(region, my_name);
258         my_ns_name = my_location.getCosNamingName();
259         my_orb = orb;
260         if (personality == null)
261         {
262             my_personality = this;
263         }
264         else
265         {
266             my_personality = personality;
267         }
268         if (shell == null)
269         {
270             my_shell = this;
271         }
272         else
273         {
274             my_shell = shell;
275         }
276
277         // create a MAFAgentSystem implementation, connect it to the ORB,
278

279         tie = new MAFAgentSystem_impl(this, false);
280         my_orb.connect(tie);
281         String JavaDoc finder_name =
282             System.getProperty(Constants.regionPrefixProp, Constants.regionPrefixDefault) +
283             "/" +
284             region +
285             "/" +
286             System.getProperty(Constants.finderNameProp, Constants.finderNameDefault);
287         // get CORBA naming service
288
try
289         {
290             my_ns = new NameService(my_orb);
291         }
292         catch (NameServiceException e)
293         {
294             System.err.println("Fatal error - could not get CORBA name service: " + e);
295             throw new BadOperation(BadOperation.INFRASTRUCTURE, "Cannot create agency without COS name service", e);
296         }
297         // get the MAF Finder of agency's region (if any)
298
try
299         {
300             my_finder = MAFFinderHelper.narrow(my_ns.resolve(finder_name));
301             my_finder.register_agent_system(
302                 my_info.agent_system_name,
303                 my_location.toString(),
304                 my_info);
305         }
306         catch (NameServiceException e)
307         {
308             System.err.println("Unable to reach the MAFFinder in " + finder_name + " - no region finder support: " + e);
309             my_finder = null;
310         }
311         catch (SystemException JavaDoc e)
312         {
313             System.err.println("Unable to reach the MAFFinder " + finder_name + " - no region finder support: " + e);
314             my_finder = null;
315         }
316         catch (NameInvalid e)
317         {
318             throw new BadOperation(BadOperation.INVALIDNAME, "Exception in agency creation: name " + new Name(my_info.agent_system_name) + " has been rejected by the MAFFinder", e);
319         }
320         // bind the agency name in CORBA naming service
321
try
322         {
323             if (my_finder == null)
324             {
325                 my_ns.bind(my_ns_name, tie);
326             }
327             else // force binding since the MAFFinder has accepted the name
328
{
329                 my_ns.rebind(my_ns_name, tie);
330             }
331         }
332         catch (NameServiceException e)
333         {
334             System.err.println("Exception with CORBA naming service - unable to bind name " + my_ns_name + ":" + e);
335             if (my_finder != null)
336             {
337                 try
338                 {
339                     my_finder.unregister_agent_system(my_info.agent_system_name);
340                 }
341                 catch (Exception JavaDoc ex)
342                 {
343                     System.err.println("Warning - could not unregister agency " + new Name(my_info.agent_system_name) + " from the MAFFinder while agency creation is aborted: " + e);
344                 }
345             }
346             throw new BadOperation(BadOperation.INVALIDNAME, "Could not bind " + my_ns_name + " in CORBA naming service.", e);
347         }
348     }
349
350
351     /**
352         @return a data record describing current agent system (see MAF).
353     */

354     public AgentSystemInfo getAgentSystemInfo()
355     {
356         return my_info;
357     }
358
359
360     /**
361         @return a new AgentProfile instance for SMI (or personality) agents,
362         with the given properties.
363         @param properties the agent properties to be inserted in the profile.
364     */

365     public AgentProfile makeAgentProfile(Properties properties)
366     {
367         return new AgentProfile(
368             Constants.LANGUAGE_ID,
369             my_info.agent_system_type,
370             my_info.agent_system_description,
371             my_info.major_version,
372             my_info.minor_version,
373             Constants.SERIALIZATION,
374             Misc.property2any(properties, my_orb));
375     }
376
377
378     /**
379         Receives a moving agent,
380         invokes callback <code>afterMove()</code> on the newly installed agent.
381         @param class_name class name of the received agent.
382         @param agent_state the state of the received agent.
383         @param agent_name the MAF unique name of the received agent.
384         @param agent_profile the profile of the received agent (see MAF specifications).
385         @param place the name of the place where to settle the new agent.
386         @param code_base codebase to load classes for this agent.
387         @param class_provider the MAFAgentSystem implementation from where to pick the classes
388         of the received agent.
389         @throws ClassUnknown at least one of the needed classes could not be found
390         @throws DeserializationFailed the received agent is not of SMI agent system type,
391         or an exception was thrown during the agent deserialization
392         @throws MAFExtendedException an exception was thrown by the agent afterMove() method
393     */

394     public void receiveAgent(
395         String JavaDoc class_name,
396         byte[] agent_state,
397         org.omg.CfMAF.Name agent_name,
398         AgentProfile agent_profile,
399         String JavaDoc place,
400         String JavaDoc code_base,
401         MAFAgentSystem class_provider)
402         throws ClassUnknown, DeserializationFailed, MAFExtendedException
403     {
404         try
405         {
406             shutdownLock.in();
407         }
408         catch (ShutdownLock.ShutdownException e)
409         {
410             throw Constants.agencyIsClosed;
411         }
412         try
413         {
414             // check agent system type Id
415
if (agent_profile.agent_system_type != my_info.agent_system_type)
416             {
417                 System.err.println("Warning: rejected attempt to receive an object of foreign agent system type (" + String.valueOf(agent_name.agent_system_type) + ").");
418                 throw new DeserializationFailed();
419             }
420             // deserialization of the incoming agent
421
Boolean JavaDoc isRunning;
422             MobileObject agent = null;
423             try
424             {
425                 SMIObjectInputStream deserializer = new SMIObjectInputStream(
426                     new ByteArrayInputStream(agent_state),
427                     code_base,
428                     agent_profile,
429                     class_provider);
430                 isRunning = (Boolean JavaDoc) deserializer.readObject();
431                 agent = (MobileObject) deserializer.readObject();
432             }
433             catch (IOException e)
434             {
435                 e.printStackTrace();
436                 throw new DeserializationFailed();
437             }
438             catch (ClassNotFoundException JavaDoc e)
439             {
440                 e.printStackTrace();
441                 throw new ClassUnknown();
442             }
443             // registration of the new location of the agent in the MAFFinder (if available)
444
if (my_finder != null)
445             {
446                 try
447                 {
448                     my_finder.register_agent(agent_name, my_location.toString(), agent_profile);
449                 }
450                 catch (SystemException JavaDoc e)
451                 {
452                     e.printStackTrace();
453                     throw e;
454                 }
455                 catch (NameInvalid e)
456                 {
457                     throw new MAFExtendedException();
458                 }
459             }
460             // add the new agent to agent tables, and invoke callback on MobileObject
461
Name agent_name_wrapper = new Name(agent_name);
462             AgentInfo entry = new AgentEntry(
463                 agent,
464                 new Name(agent_name),
465                 place,
466                 isRunning.booleanValue(),
467                 code_base,
468                 Misc.any2property(agent_profile.properties));
469             synchronized(agent)
470             {
471                 registerAgent(agent, agent_name_wrapper, entry);
472                 try
473                 {
474                     my_personality.afterMove(agent, my_shell, my_location, place);
475                 }
476                 catch (Exception JavaDoc e)
477                 {
478                     if (!(e instanceof BadOperation))
479                     {
480                         System.err.println("Warning: unexpected exception thrown by agent " + agent_name_wrapper + " in afterMove()");
481                         e.printStackTrace();
482                     }
483                     unregisterAgent(agent, agent_name_wrapper);
484                     throw new MAFExtendedException();
485                 }
486             }
487             setChanged();
488             notifyObservers();
489         }
490         finally
491         {
492             shutdownLock.out();
493         }
494     }
495
496
497     /**
498         @return CORBA object reference to MAFFinder implementation this agency is bound to.
499         Returns null if the agency is running without MAFFinder support.
500     */

501     public MAFFinder getMAFFinder()
502     {
503         return my_finder;
504     }
505
506
507     /**
508         @return the name of the region the agency belongs to.
509     */

510     public String JavaDoc getRegion()
511     {
512         return my_region;
513     }
514
515
516     /**
517         @return a wrapper for the MAF name of the agency.
518     */

519     public Name getName()
520     {
521         return new Name(my_info.agent_system_name);
522     }
523
524
525     /**
526         @return the full name of the agency, as it appears in the CORBA naming service.
527         String'fied COSnaming names have the following format:
528         <code>/naming context1!kind1/.../object!kind</code>
529     */

530     public String JavaDoc getNsName()
531     {
532         return my_ns_name;
533     }
534
535
536     /**
537         @return the location of the agency.
538     */

539     public Location getLocation()
540     {
541         return my_location;
542     }
543
544
545     /**
546         @return a record of data about an agent hosted by the agency, or null
547         if the designated agent is not known by the agency.
548         @param agent the MAF unique name of the agent.
549     */

550     public AgentInfo getAgentInfo(Name agent)
551     {
552         AgentInfo result;
553         result = (AgentInfo)agentsByName.get(agent);
554         return result;
555     }
556
557
558     /**
559         @return a record of data about an agent hosted by the agency, or null
560         if the designated agent is not known by the agency.
561         @param agent the Java object reference to the agent.
562     */

563     public AgentInfo getAgentInfo(MobileObject agent)
564     {
565         synchronized(agent)
566         {
567             AgentInfo result;
568             result = (AgentInfo)agentsByRef.get(agent);
569             return result;
570         }
571     }
572
573
574     /**
575         Creates an agent in current agency.
576         The agent's default constructor is called unless a constructor taking
577         a single Object as argument is defined and "argument" is both non-null and
578         not an empty array.
579         @param agent_class the class name of the new agent.
580         @param name the identity part of the MAF name of the new agent
581         (must be unique in the set of names of the agency's authority; the authority
582         part of the MAF agent name will be the same as the agency's).
583         @param place the name of the place where to settle the new agent.
584         @param codebase codebase to load classes for this agent.
585         @param properties agent's properties.
586         @param argument parameter for agent constructor and initialization.
587         @throws BadOperation the agent creation failed
588         @see MobileObject#afterBirth(AgentSystem, AgentInfo, Object)
589     */

590     public AgentInfo createLocalAgent(
591         String JavaDoc agent_class,
592         Name name,
593         String JavaDoc place,
594         String JavaDoc codebase,
595         Properties properties,
596         Object JavaDoc argument)
597         throws BadOperation
598     {
599         return createLocalAgent(
600             agent_class,
601             name,
602             makeAgentProfile(properties),
603             place,
604             codebase,
605             null,
606             argument,
607             null);
608     }
609
610
611     /**
612         Creates an agent in current agency.
613         The agent's default constructor is called unless a constructor taking
614         a single Object as argument is defined and "argument" is both non-null and
615         not an empty array.
616         @param classname the class name of the new agent.
617         @param name the MAF unique name of the new agent.
618         @param profile agent MAF profile.
619         @param place the name of the place where to settle the new agent.
620         @param codebase codebase to load classes for this agent.
621         @param agent_data ignored if null or empty array ; otherwise, should contain a serialized
622         Java object which will be used as agent constructor and initialization parameter.
623         @param argument parameter for agent constructor and initialization (ignored if agent_data
624         is non-null and non-empty).
625         @param class_provider the MAFAgentSystem implementation from where to pick the classes;
626         (if null, the codebase will be interpreted locally.
627         @throws BadOperation the agent creation failed
628         @see MobileObject#afterBirth(AgentSystem, AgentInfo, Object)
629     */

630     public AgentInfo createLocalAgent(
631         String JavaDoc classname,
632         Name name,
633         AgentProfile profile,
634         String JavaDoc place,
635         String JavaDoc codebase,
636         byte[] agent_data,
637         Object JavaDoc argument,
638         MAFAgentSystem class_provider)
639         throws BadOperation
640     {
641         Class JavaDoc agentClass = null;
642         ClassLoader JavaDoc loader;
643         try
644         {
645             loader = Misc.getClassLoader(
646                 Thread.currentThread().getContextClassLoader(),
647                 codebase,
648                 profile,
649                 class_provider);
650             agentClass = loader.loadClass(classname);
651         }
652         catch (ClassNotFoundException JavaDoc e)
653         {
654             throw new BadOperation(BadOperation.CLASSFAULT, "Exception in create operation for agent " + name + ": undefined class " + classname + ".", e);
655         }
656         catch (Throwable JavaDoc e)
657         {
658             throw new BadOperation(BadOperation.INFRASTRUCTURE, "Exception in create operation for agent " + name + ": " + e);
659         }
660         if (agentClass == null)
661         {
662             throw new BadOperation(BadOperation.CLASSFAULT, "Exception in create operation for agent " + name + ": undefined class " + classname + ".");
663         }
664         if (agent_data != null && agent_data.length != 0)
665         {
666             try
667             {
668                 SMIObjectInputStream deserializer = new SMIObjectInputStream(
669                     new ByteArrayInputStream(agent_data),
670                     loader);
671                 argument = deserializer.readObject();
672             }
673             catch (IOException e)
674             {
675                 throw new BadOperation(BadOperation.SERIALIZATION, "Exception in create operation for agent " + name + ": could not deserialize argument object.", e);
676             }
677             catch (ClassNotFoundException JavaDoc e)
678             {
679                 throw new BadOperation(BadOperation.CLASSFAULT, "Exception in create operation for agent " + name + ": undefined class " + classname + ".", e);
680             }
681         }
682         return createLocalAgent(
683             agentClass,
684             name,
685             profile,
686             place,
687             codebase,
688             argument);
689     }
690
691
692     /**
693         Creates an agent in current agency, provided that its class has already
694         been loaded (or can be loaded by the system classloader).
695         The agent's default constructor is called unless a constructor taking
696         a single Object as argument is defined and "argument" is both non-null and
697         not an empty array.
698         @param agent_class the class of the new agent.
699         @param agent_name the MAF unique name of the new agent.
700         @param agent_profile the profile of the agent (see MAF specifications).
701         @param place the name of the place where to settle the new agent.
702         @param codebase codebase to load classes for this agent.
703         @param argument parameter for agent initialization and constructor.
704         @throws BadOperation agent creation has failed
705         @see MobileObject#afterBirth(AgentSystem, AgentInfo, Object)
706         @see AgencyPersonality
707     */

708     AgentInfo createLocalAgent(
709         Class JavaDoc agent_class,
710         Name agent_name,
711         AgentProfile agent_profile,
712         String JavaDoc place,
713         String JavaDoc codebase,
714         Object JavaDoc argument)
715         throws BadOperation
716     {
717         try
718         {
719             shutdownLock.in();
720         }
721         catch (ShutdownLock. ShutdownException e)
722         {
723             throw Constants.agencyIsClosed;
724         }
725         try
726         {
727             MobileObject agent = null;
728             AgentInfo entry;
729             // check the agent system type of the agent
730
if (agent_name.type() != my_info.agent_system_type)
731             {
732                 throw new BadOperation(BadOperation.AGENTTYPE, "Exception in create operation for agent " + agent_name + ": unsupported agent system type " + String.valueOf(agent_name.type()) + ".");
733             }
734
735             // create a new instance and register the new agent in the MAFFinder (if available)
736
try
737             {
738                 if (argument != null
739                     && ( ! (argument instanceof Object JavaDoc[])
740                          || (argument instanceof Object JavaDoc[] && ((Object JavaDoc[])argument).length != 0)))
741                 {
742                     try
743                     {
744                         Constructor constructor = agent_class.getConstructor(new Class JavaDoc[]{ Object JavaDoc.class });
745                         agent = (MobileObject) constructor.newInstance(new Object JavaDoc[]{ argument });
746                     }
747                     catch (NoSuchMethodException JavaDoc ex)
748                     {
749                         agent = null;
750                     }
751                 }
752                 if (agent == null)
753                 {
754                     agent = (MobileObject) agent_class.newInstance();
755                 }
756                 entry = new AgentEntry(
757                     agent,
758                     agent_name,
759                     place,
760                     true,
761                     codebase,
762                     Misc.any2property(agent_profile.properties));
763                 if (my_finder != null)
764                 {
765                     my_finder.register_agent(
766                         agent_name.getmafname(),
767                         my_location.toString(),
768                         agent_profile);
769                 }
770             }
771             catch (InvocationTargetException e)
772             {
773                 throw new BadOperation(BadOperation.REJECTED, "Exception in create operation for agent " + agent_name + ": exception in constructor.", e);
774             }
775             catch (InstantiationException JavaDoc e)
776             {
777                 throw new BadOperation(BadOperation.INSTANTIATION, "Exception in create operation for agent " + agent_name, e);
778             }
779             catch (IllegalAccessException JavaDoc e)
780             {
781                 throw new BadOperation(BadOperation.INSTANTIATION, "Exception in create operation for agent " + agent_name, e);
782             }
783             catch (ExceptionInInitializerError JavaDoc e)
784             {
785                 throw new BadOperation(BadOperation.INSTANTIATION, "Exception in create operation for agent " + agent_name + ": " + e);
786             }
787             catch (SecurityException JavaDoc e)
788             {
789                 throw new BadOperation(BadOperation.INSTANTIATION, "Exception in create operation for agent " + agent_name, e);
790             }
791             catch (SystemException JavaDoc e)
792             {
793                 throw new BadOperation(BadOperation.INFRASTRUCTURE, "Exception in create operation for agent " + agent_name, e);
794             }
795             catch (NameInvalid e)
796             {
797                 throw new BadOperation(BadOperation.OTHER, "Exception in create operation for agent " + agent_name + " (unspecified).", e);
798             }
799             // add agent to agent tables and invoke callback on MobileObject
800
synchronized(agent)
801             {
802                 registerAgent(agent, agent_name, entry);
803                 try
804                 {
805                     my_personality.afterBirth(agent, my_shell, entry, argument);
806                 }
807                 catch (Exception JavaDoc e)
808                 {
809                     unregisterAgent(agent, agent_name);
810                     if (my_finder != null)
811                     {
812                         try
813                         {
814                             my_finder.unregister_agent(agent_name.getmafname());
815                         }
816                         catch (SystemException JavaDoc ex)
817                         {
818                             ex.printStackTrace();
819                         }
820                         catch (EntryNotFound ex)
821                         {
822                             ex.printStackTrace();
823                         }
824                     }
825                     if (e instanceof BadOperation)
826                     {
827                         throw (BadOperation) e;
828                     }
829                     else
830                     {
831                         throw new BadOperation(BadOperation.REJECTED, "unexpected exception in afterBirth: " + e, e);
832                     }
833                 }
834             }
835             setChanged();
836             notifyObservers();
837             return entry;
838         }
839         finally
840         {
841             shutdownLock.out();
842         }
843     }
844
845
846     /**
847         Invokes the <code>beforeMove()</code> callback on the agent, and then tries
848         to move it if no exception has been thrown by <code>beforeMove()</code>.
849         If the move fails, the <code>afterMoveFailed()</code> callback is invoked
850         on the agent, and an exception is thrown.
851         @param agent name wrapper for agent's MAF name.
852         @param agency location of the target agency.
853         @param place the name of the target place in the given agency.
854         @throws BadOperation on aborted move.
855         @see MobileObject
856         @see AgencyPersonality
857     */

858     public void moveLocalAgent(Name agent, Location agency, String JavaDoc place)
859         throws BadOperation
860     {
861         AgentInfo entry = (AgentInfo)agentsByName.get(agent);
862         if (entry == null)
863         {
864             throw new BadOperation(
865                 BadOperation.UNKNOWNAGENT,
866                 "Exception in move operation: unknown agent " + agent + ".");
867         }
868         else
869         {
870             moveLocalAgent(entry.getAgent(), agency, place);
871         }
872     }
873
874
875     /**
876         Invokes the <code>beforeMove()</code> callback on the agent, and then tries
877         to move it if no exception has been thrown by <code>beforeMove()</code>.
878         If the move fails, the <code>afterMoveFailed()</code> callback is invoked
879         on the agent, and an exception is thrown.
880         @param agent Java object reference to the agent.
881         @param agency location of the target agency.
882         @param place the name of the target place in the given agency.
883         @throws BadOperation on aborted move.
884         @see MobileObject
885         @see AgencyPersonality
886     */

887     public void moveLocalAgent(MobileObject agent, Location agency, String JavaDoc place)
888         throws BadOperation
889     {
890         try
891         {
892             shutdownLock.in();
893         }
894         catch (ShutdownLock.ShutdownException e)
895         {
896             throw Constants.agencyIsClosed;
897         }
898         try
899         {
900             synchronized(agent)
901             {
902                 // check if the agent is known (in the agent tables)
903
AgentInfo entry = (AgentInfo) agentsByRef.get(agent);
904                 if (entry == null)
905                 {
906                     throw new BadOperation(
907                         BadOperation.UNKNOWNAGENT,
908                         "Exception in move operation: unknown agent.");
909                 }
910                 // find destination MAFAgentSystem implementation in the naming service
911
MAFAgentSystem dest_ref;
912                 String JavaDoc to_ns_name = agency.getCosNamingName();
913                 try
914                 {
915                     dest_ref = MAFAgentSystemHelper.narrow(my_ns.resolve(to_ns_name));
916                 }
917                 catch (NameServiceException e)
918                 {
919                     if (e.exception instanceof NotFound)
920                     {
921                         throw new BadOperation(
922                             BadOperation.DESTINATION,
923                             "Exception in move operation for agent " + entry.getName() + ": unknown destination agency " + agency + ".");
924                     }
925                     else
926                     {
927                         e.printStackTrace();
928                         throw new BadOperation(
929                             BadOperation.INFRASTRUCTURE,
930                             "Exception in move operation for agent " + entry.getName() + ": something is going wrong with CORBA naming service.");
931                     }
932                 }
933
934                 // try to move the agent:
935
// - callbacks on MobileObject interface,
936
// - remove the agent from agent tables,
937
// - agent serialization,
938
// - agent move (invocation of destination MAFAgentSystem implementation)
939
// - according to overall migration success or failure, callbacks on
940
// MobileObject interface.
941
AgentProfile profile = makeAgentProfile(entry.getProperties());
942                 BadOperation exception = null;
943                 Boolean JavaDoc isRunning;
944                 try
945                 {
946                     my_personality.beforeMove(agent, agency, place);
947                 }
948                 catch (BadOperation ex)
949                 {
950                     throw ex;
951                 }
952                 catch (Exception JavaDoc ex)
953                 {
954                     throw new BadOperation(BadOperation.REJECTED, "Unexpected exception in beforeMove() for agent " + entry.getName(), ex);
955                 }
956                 isRunning = new Boolean JavaDoc(localAgentIsRunning(agent));
957                 try
958                 {
959                     unregisterAgent(agent, entry.getName());
960                     ClassName[] classes = {
961                         new ClassName(agent.getClass().toString().substring("class ".length()), new byte[0])
962                     };
963                     ByteArrayOutputStream agent_state = new ByteArrayOutputStream();
964                     ObjectOutputStream objOut = new ObjectOutputStream(agent_state);
965                     objOut.writeObject(isRunning);
966                     objOut.writeObject(agent);
967                     dest_ref.receive_agent(
968                         entry.getName().getmafname(),
969                         profile,
970                         agent_state.toByteArray(),
971                         place,
972                         classes,
973                         entry.getCodebase(),
974                         tie);
975                     setChanged();
976                     notifyObservers();
977                 }
978                 catch (IOException e)
979                 {
980                     exception = new BadOperation(BadOperation.SERIALIZATION, "Exception in move operation for agent " + entry.getName() + " (serialization)", e);
981                 }
982                 catch (SystemException JavaDoc e)
983                 {
984                     exception = new BadOperation(BadOperation.INFRASTRUCTURE, "Exception in move operation for agent " + entry.getName() + " (CORBA)", e);
985                 }
986                 catch (ClassUnknown e)
987                 {
988                     exception = new BadOperation(BadOperation.CLASSFAULT, "Exception in move operation for agent " + entry.getName() + " (missing class)", e);
989                 }
990                 catch (DeserializationFailed e)
991                 {
992                     exception = new BadOperation(BadOperation.CLASSFAULT, "Exception in move operation for agent " + entry.getName() + " (deserialization)", e);
993                 }
994                 catch (MAFExtendedException e)
995                 {
996                     exception = new BadOperation(BadOperation.REJECTED, "Exception in move operation for agent " + entry.getName() + " (agent refused to settle in destination agency)", e);
997                     try
998                     {
999                         my_finder.register_agent(entry.getName().getmafname(), my_location.toString(), profile);
1000                    }
1001                    catch (SystemException JavaDoc ex)
1002                    {
1003                        e.printStackTrace();
1004                    }
1005                    catch (NameInvalid ex)
1006                    {
1007                        e.printStackTrace();
1008                    }
1009                }
1010                catch (ArgumentInvalid e)
1011                {
1012                    exception = new BadOperation(BadOperation.OTHER, "Exception in move operation for agent " + entry.getName() + " (unspecified problem)", e);
1013                }
1014                if (exception != null)
1015                {
1016                    registerAgent(agent, entry.getName(), entry);
1017                    try
1018                    {
1019                        my_personality.afterMoveFailed(agent, agency, place, exception.getReason(), exception.getMessage());
1020                    }
1021                    catch (Exception JavaDoc ex)
1022                    {
1023                        System.err.println("Warning: ignoring unexpected exception thrown by agent " + entry.getName() + " in afterMoveFailed() call-back:\n" + ex);
1024                        ex.printStackTrace();
1025                    }
1026                    throw exception;
1027                }
1028            }
1029        }
1030        finally
1031        {
1032            shutdownLock.out();
1033        }
1034    }
1035
1036
1037    /**
1038        Calls <code>beforeShutdown()</code> on the hosted agents,
1039        terminates agents that are still hosted, then calls <code>agencyShutdown()</code>
1040        on the agency, and finally shuts the agency down.
1041        @see MobileObject
1042        @see AgencyPersonality
1043    */

1044    public void terminate()
1045    {
1046        try
1047        {
1048            shutdownLock.shutdown();
1049        }
1050        catch (ShutdownLock.ShutdownException e)
1051        {
1052            throw Constants.agencyIsClosed;
1053        }
1054        // unregister the agency from the MAFFinder (if available)
1055
if (my_finder != null)
1056        {
1057            try
1058            {
1059                my_finder.unregister_agent_system(my_info.agent_system_name);
1060            }
1061            catch (SystemException JavaDoc e)
1062            {
1063                System.err.println("Warning: unable to unregister agency from MAFFinder:\n" + e.toString());
1064            }
1065            catch (EntryNotFound e)
1066            {
1067                System.err.println("Warning: unable to unregister agency from MAFFinder:\n" + e.toString());
1068            }
1069        }
1070        synchronized (agentsByRef)
1071        {
1072            Enumeration agents;
1073            // warns all the hosted agents
1074
agents = agentsByRef.elements();
1075            while (agents.hasMoreElements())
1076            {
1077                AgentInfo entry = (AgentInfo)agents.nextElement();
1078                try
1079                {
1080                    my_personality.beforeShutdown(entry.getAgent());
1081                }
1082                catch(Throwable JavaDoc ex)
1083                {
1084                    System.err.println("Warning: ignored exception thrown in beforeShutdown() by agent " + entry.getName() + ".\n" + ex);
1085                }
1086            }
1087            // unbind the agency from the COS naming service and disconnect the agency
1088
try
1089            {
1090                my_ns.unbind(my_ns_name);
1091            }
1092            catch (NameServiceException e)
1093            {
1094                System.err.println("Warning: unable to unbind name " + my_ns_name + " from naming service:\n" + e.toString());
1095            }
1096            my_orb.disconnect(tie);
1097            // terminates all the hosted agents
1098
agents = agentsByRef.elements();
1099            while (agents.hasMoreElements())
1100            {
1101                try
1102                {
1103                    terminateLocalAgent(((AgentInfo)agents.nextElement()).getName());
1104                }
1105                catch (BadOperation ex)
1106                {
1107                    System.err.println("Exception in terminate operation for agency " + new Name(my_info.agent_system_name) + ":\n" + ex);
1108                }
1109            }
1110            my_personality.agencyShutdown();
1111        }
1112        // notify observers
1113
setChanged();
1114        notifyObservers(NOTIFY_TERMINATE);
1115        // trigger a delayed System.exit if the agency is "standalone"
1116
if (standalone)
1117        {
1118            new ExitDelay(Integer.parseInt(System.getProperty(Constants.agencyExitDelayProp, Constants.agencyExitDelayDefault)));
1119        }
1120    }
1121
1122
1123    /**
1124        Invokes the <code>beforeDeath()</code> callback on an agent, and then terminates it.
1125        @param agent MAF unique name of the agent.
1126        @throws BadOperation the target agent is not known by the agency, or
1127        its termination threw an exception.
1128        @see MobileObject
1129        @see AgencyPersonality
1130    */

1131    public void terminateLocalAgent(Name agent)
1132        throws BadOperation
1133    {
1134        AgentInfo entry = (AgentInfo)agentsByName.get(agent);
1135        if (entry == null)
1136        {
1137            throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in terminate operation: unknown agent " + agent + ".");
1138        }
1139        terminateLocalAgent(entry.getAgent());
1140    }
1141
1142
1143    /**
1144        Invokes the beforeDeath() callback on an agent, and then terminates it.
1145        @param agent the Java object reference to the agent.
1146        @throws BadOperation the target agent is not known by the agency, or
1147        its termination threw an exception.
1148        @see MobileObject
1149        @see AgencyPersonality
1150    */

1151    public void terminateLocalAgent(MobileObject agent)
1152        throws BadOperation
1153    {
1154        try
1155        {
1156            shutdownLock.in();
1157        }
1158        catch (ShutdownLock.ShutdownException e)
1159        {
1160            throw Constants.agencyIsClosed;
1161        }
1162        try
1163        {
1164            BadOperation exception = null;
1165            synchronized(agent)
1166            {
1167                // check if the agent is known (in agent tables)
1168
AgentInfo entry = (AgentInfo)agentsByRef.get(agent);
1169                if (entry == null)
1170                {
1171                    throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in terminate operation: unknown agent.");
1172                }
1173                // callbacks on interface MobileObject
1174
// agent tables update
1175
// MAFFinder update (if available)
1176
try
1177                {
1178                    my_personality.beforeDeath(agent);
1179                }
1180                catch (Throwable JavaDoc e)
1181                {
1182                    System.err.println("Warning in terminateLocalAgent(" + entry.getName() + "): ignored exception thrown by beforeDeath().\n" + e.toString());
1183                    exception = new BadOperation(
1184                        BadOperation.REJECTED,
1185                        "Unexpected exception in beforeDeath() call-back in agent " + entry.getName(),
1186                        e instanceof Exception JavaDoc ? (Exception JavaDoc) e : null);
1187                }
1188                unregisterAgent(agent, entry.getName());
1189                try
1190                {
1191                    if (my_finder != null)
1192                    {
1193                        my_finder.unregister_agent(entry.getName().getmafname());
1194                    }
1195                }
1196                catch (Exception JavaDoc e)
1197                {
1198                    System.err.println("Warning in terminateLocalAgent(" + entry.getName() + "): ignored exception dealing with MAFFinder.\n" + e);
1199                    if (exception == null)
1200                    {
1201                        exception = new BadOperation(
1202                            BadOperation.INFRASTRUCTURE,
1203                            "Exception in terminate operation on agent " + entry.getName(),
1204                            e);
1205                    }
1206                }
1207            }
1208            setChanged();
1209            notifyObservers();
1210            if (exception != null)
1211            {
1212                throw exception;
1213            }
1214        }
1215        finally
1216        {
1217            shutdownLock.out();
1218        }
1219    }
1220
1221
1222    /**
1223        @return an array of names of hosted agents matching a given profile.
1224        The returned array is zero-sized if no agent matches the given profile (or if there is no agent at all).
1225        @param profile the agent profile to be matched; if null, all the agents are selected.
1226    */

1227    public Name[] listLocalAgents(AgentProfile profile)
1228    {
1229        synchronized (agentsByRef)
1230        {
1231            Name[] result;
1232            if (profile == null)
1233            {
1234                result = new Name[agentsByName.size()];
1235                Enumeration keys = agentsByName.keys();
1236                for (int i=0 ; keys.hasMoreElements() ; ++i)
1237                {
1238                    result[i] = (Name)keys.nextElement();
1239                }
1240            }
1241            else
1242            {
1243                Enumeration keys = agentsByName.keys();
1244                Vector select = new Vector();
1245                while (keys.hasMoreElements())
1246                {
1247                    Name name = (Name)keys.nextElement();
1248                    if (Misc.matchProfile(
1249                        profile,
1250                        makeAgentProfile(
1251                            ((AgentInfo)agentsByName.get(name)).getProperties())))
1252                    {
1253                        select.add(name);
1254                    }
1255                }
1256                result = new Name[select.size()];
1257                result = (Name[])(select.toArray(result));
1258            }
1259            return result;
1260        }
1261    }
1262
1263
1264    /**
1265        @return an array of MAF names of hosted agents matching a given profile.
1266        The returned array is zero-sized if no agent matches the given profile (or if there is no agent at all).
1267        @param profile the agent profile to be matched; if null, all the agents are
1268        selected.
1269    */

1270    public org.omg.CfMAF.Name[] listAgents(AgentProfile profile)
1271    {
1272        synchronized (agentsByRef)
1273        {
1274            org.omg.CfMAF.Name[] result;
1275            if (profile == null)
1276            {
1277                result = new org.omg.CfMAF.Name[agentsByName.size()];
1278                Enumeration keys = agentsByName.keys();
1279                for (int i=0 ; keys.hasMoreElements() ; ++i)
1280                {
1281                    result[i] = ((Name)keys.nextElement()).getmafname();
1282                }
1283            }
1284            else
1285            {
1286                Enumeration keys = agentsByName.keys();
1287                Vector select = new Vector();
1288                while (keys.hasMoreElements())
1289                {
1290                    Name name = (Name)keys.nextElement();
1291                    if (Misc.matchProfile(
1292                        profile,
1293                        makeAgentProfile(
1294                            ((AgentInfo)agentsByName.get(name)).getProperties())))
1295                    {
1296                        select.add(name.getmafname());
1297                    }
1298                }
1299                result = new org.omg.CfMAF.Name[select.size()];
1300                result = (org.omg.CfMAF.Name[])(select.toArray(result));
1301            }
1302            return result;
1303        }
1304    }
1305
1306
1307    /**
1308        @return an array of MAF names of local agents belonging to the given authority.
1309        The returned array is zero-sized if no agent matches the given profile (or if there is no agent at all).
1310        @param authority the agent's authority.
1311    */

1312    public org.omg.CfMAF.Name[] listAgents(byte[] authority)
1313    {
1314        synchronized (agentsByRef)
1315        {
1316            org.omg.CfMAF.Name[] result;
1317            Enumeration keys = agentsByName.keys();
1318            Vector select = new Vector();
1319            while (keys.hasMoreElements())
1320            {
1321                Name name = (Name)keys.nextElement();
1322                if ((new String JavaDoc(authority)).equals(new String JavaDoc(name.authority())))
1323                {
1324                    select.add(name.getmafname());
1325                }
1326            }
1327            result = new org.omg.CfMAF.Name[select.size()];
1328            result = (org.omg.CfMAF.Name[])(select.toArray(result));
1329            return result;
1330        }
1331    }
1332
1333
1334    /**
1335        Invokes the <code>beforeResume()</code> callback on an agent in order to resume its activity.
1336        Unless this callback throws an exception, the agent activity is then considered as resumed.
1337        @param agent MAF unique agent name.
1338        @throws BadOperation the agent could not be found and resumed, or it was already running.
1339        @see MobileObject
1340        @see AgencyPersonality
1341    */

1342    public void resumeLocalAgent(Name agent)
1343        throws BadOperation
1344    {
1345        AgentInfo entry = (AgentInfo)agentsByName.get(agent);
1346        if (entry != null)
1347        {
1348            resumeLocalAgent(entry.getAgent());
1349        }
1350        else
1351        {
1352            throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in resumeLocalAgent(): unknown agent " + agent + ".");
1353        }
1354    }
1355
1356
1357    /**
1358        Invokes the <code>beforeResume()</code> callback on an agent in order to resume its activity.
1359        Unless this callback throws an exception, the agent activity is then considered as resumed.
1360        @param agent the agent's Java object reference.
1361        @throws BadOperation the agent could not be found and resumed, or it was already running.
1362        @see MobileObject
1363        @see AgencyPersonality
1364    */

1365    public void resumeLocalAgent(MobileObject agent)
1366        throws BadOperation
1367    {
1368        try
1369        {
1370            shutdownLock.in();
1371        }
1372        catch (ShutdownLock.ShutdownException e)
1373        {
1374            throw Constants.agencyIsClosed;
1375        }
1376        try
1377        {
1378            synchronized(agent)
1379            {
1380                AgentInfo entry = (AgentInfo)agentsByRef.get(agent);
1381                if (entry != null)
1382                {
1383                    if (entry.isRunning())
1384                    {
1385                        throw new BadOperation(BadOperation.RUNNING, "Exception in resume operation: agent " + entry.getName() + " was already running.");
1386                    }
1387                    else
1388                    {
1389                        try
1390                        {
1391                            my_personality.beforeResume(agent);
1392                        }
1393                        catch (BadOperation ex)
1394                        {
1395                            throw ex;
1396                        }
1397                        catch (Exception JavaDoc ex)
1398                        {
1399                            throw new BadOperation(BadOperation.REJECTED, "Unexpected exception in beforeResume() for agent " + entry.getName(), ex);
1400                        }
1401                        entry.toggleRunning();
1402                    }
1403                }
1404                else
1405                {
1406                    throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in resumeLocalAgent: unknown agent " + entry.getName() + ".");
1407                }
1408            }
1409        }
1410        finally
1411        {
1412            shutdownLock.out();
1413        }
1414    }
1415
1416
1417    /**
1418        Invokes the <code>beforeSuspend()</code> callback on an agent in order to suspend its activity.
1419        Unless this callback throws an exception, the agent activity is then considered as suspended.
1420        @param agent MAF unique agent name.
1421        @throws BadOperation the agent could not be found and suspended, or was already suspended.
1422        @see MobileObject
1423        @see AgencyPersonality
1424    */

1425    public void suspendLocalAgent(Name agent)
1426        throws BadOperation
1427    {
1428        AgentInfo entry = (AgentInfo)agentsByName.get(agent);
1429        if (entry != null)
1430        {
1431            suspendLocalAgent(entry.getAgent());
1432        }
1433        else
1434        {
1435            throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in suspendLocalAgent operation: unknown agent " + agent + ".");
1436        }
1437    }
1438
1439
1440    /**
1441        Invokes the <code>beforeSuspend()</code> callback on an agent in order to suspend its activity.
1442        Unless this callback throws an exception, the agent activity is then considered as suspended.
1443        @param agent the agent's Java object reference.
1444        @throws BadOperation the agent could not be found and suspended, or was already suspended.
1445        @see MobileObject
1446        @see AgencyPersonality
1447    */

1448    public void suspendLocalAgent(MobileObject agent)
1449        throws BadOperation
1450    {
1451        try
1452        {
1453            shutdownLock.in();
1454        }
1455        catch (ShutdownLock.ShutdownException e)
1456        {
1457            throw Constants.agencyIsClosed;
1458        }
1459        try
1460        {
1461            synchronized(agent)
1462            {
1463                AgentInfo entry = (AgentInfo)agentsByRef.get(agent);
1464                if (entry != null)
1465                {
1466                    if (! entry.isRunning())
1467                    {
1468                        throw new BadOperation(BadOperation.SUSPENDED, "Exception in suspend operation: agent " + entry.getName() + " was already suspended.");
1469                    }
1470                    else
1471                    {
1472                        try
1473                        {
1474                            my_personality.beforeSuspend(agent);
1475                        }
1476                        catch (BadOperation ex)
1477                        {
1478                            throw ex;
1479                        }
1480                        catch (Exception JavaDoc ex)
1481                        {
1482                            throw new BadOperation(BadOperation.REJECTED, "Unexpected exception in beforeSuspend() for agent " + entry.getName(), ex);
1483                        }
1484                        entry.toggleRunning();
1485                    }
1486                }
1487                else
1488                {
1489                    throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in suspendLocalAgent(): unknown agent.");
1490                }
1491            }
1492        }
1493        finally
1494        {
1495            shutdownLock.out();
1496        }
1497    }
1498
1499
1500    /**
1501        Sets, changes or unsets an agent property.
1502        @param agent the agent MAF name wrapper.
1503        @param property property name.
1504        @param value property value; if null, the property is unset.
1505        @exception BadOperation the agent could not be found in local agency.
1506    */

1507    public void setLocalAgentProperty(Name agent, String JavaDoc property, String JavaDoc value)
1508        throws BadOperation
1509    {
1510        AgentInfo entry = (AgentInfo)agentsByName.get(agent);
1511        if (entry != null)
1512        {
1513            setLocalAgentProperty(entry.getAgent(), property, value);
1514        }
1515        else
1516        {
1517            throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in setLocalAgentProperty(): unknown agent " + agent + ".");
1518        }
1519    }
1520
1521
1522    /**
1523        Sets, changes or unsets an agent property.
1524        @param agent the agent's Java object reference.
1525        @param property property name.
1526        @param value property value; if null, the property is unset.
1527        @throws BadOperation the agent could not be found in local agency.
1528    */

1529    public void setLocalAgentProperty(MobileObject agent, String JavaDoc property, String JavaDoc value)
1530        throws BadOperation
1531    {
1532        try
1533        {
1534            shutdownLock.in();
1535        }
1536        catch (ShutdownLock.ShutdownException e)
1537        {
1538            throw Constants.agencyIsClosed;
1539        }
1540        try
1541        {
1542            synchronized(agent)
1543            {
1544                AgentInfo entry = (AgentInfo)agentsByRef.get(agent);
1545                if (entry == null)
1546                {
1547                    throw new BadOperation(BadOperation.UNKNOWNAGENT, "Exception in setLocalAgentProperty(): unknown agent.");
1548                }
1549                Properties props = entry.getProperties();
1550                String JavaDoc oldValue;
1551                if (value == null)
1552                {
1553                    oldValue = (String JavaDoc)props.remove(value);
1554                    if (oldValue == null)
1555                    {
1556                        return;
1557                    }
1558                }
1559                else
1560                {
1561                    oldValue = (String JavaDoc)props.setProperty(property, value);
1562                }
1563                if (my_finder != null)
1564                {
1565                    try
1566                    {
1567                        my_finder.register_agent(
1568                            entry.getName().getmafname(),
1569                            my_location.toString(),
1570                            makeAgentProfile(props));
1571                    }
1572                    catch (Exception JavaDoc ex)
1573                    {
1574                        BadOperation exception = null;
1575                        System.err.println("Exception in setLocalAgentProperty() for agent " + entry.getName() + ": " + ex);
1576                        if (ex instanceof SystemException JavaDoc &&
1577                            ((SystemException JavaDoc)ex).completed.value() != CompletionStatus._COMPLETED_YES)
1578                        {
1579                            exception = new BadOperation(
1580                                BadOperation.INFRASTRUCTURE,
1581                                "Exception with MAFFinder in property change operation for agent " + entry.getName(),
1582                                ex);
1583                        }
1584                        else if (ex instanceof NameInvalid)
1585                        {
1586                            exception = new BadOperation(
1587                                BadOperation.INVALIDNAME,
1588                                "Exception in property change operation for agent " + entry.getName() + ": invalid name.",
1589                                ex);
1590                        }
1591                        if (exception != null)
1592                        {
1593                            if (oldValue == null)
1594                            {
1595                                props.remove(property);
1596                            }
1597                            else
1598                            {
1599                                props.setProperty(property, oldValue);
1600                            }
1601                            throw exception;
1602                        }
1603                    }
1604                }
1605            }
1606        }
1607        finally
1608        {
1609            shutdownLock.out();
1610        }
1611    }
1612
1613
1614    /**
1615        @return true if the designated agent is currently active, false if
1616        the agent is suspended.
1617        @param agent wrapper to the agent's MAF name.
1618        @throws BadOperation the agent could not be found in local agency.
1619    */

1620    public boolean localAgentIsRunning(Name agent)
1621        throws BadOperation
1622    {
1623        AgentInfo entry = (AgentInfo)agentsByName.get(agent);
1624        if (entry != null)
1625        {
1626            return localAgentIsRunning(entry.getAgent());
1627        }
1628        else
1629        {
1630            throw new BadOperation(BadOperation.UNKNOWNAGENT, "Can't state activity status of unknown agent " + agent + ".");
1631        }
1632    }
1633
1634
1635    /**
1636        @return true if the designated agent is currently active, false if
1637        the agent is suspended.
1638        @param agent the agent's Java object reference.
1639        @throws BadOperation the agent could not be found in local agency.
1640    */

1641    public boolean localAgentIsRunning(MobileObject agent)
1642        throws BadOperation
1643    {
1644        try
1645        {
1646            shutdownLock.in();
1647        }
1648        catch (ShutdownLock.ShutdownException e)
1649        {
1650            throw Constants.agencyIsClosed;
1651        }
1652        try
1653        {
1654            synchronized(agent)
1655            {
1656                AgentInfo entry = (AgentInfo)agentsByRef.get(agent);
1657                if (entry != null)
1658                {
1659                    return entry.isRunning();
1660                }
1661                else
1662                {
1663                    throw new BadOperation(BadOperation.UNKNOWNAGENT, "Can't state activity status of unknown agent.");
1664                }
1665            }
1666        }
1667        finally
1668        {
1669            shutdownLock.out();
1670        }
1671    }
1672
1673
1674    /**
1675        @return the ORB object used by current agency.
1676    */

1677    public ORB JavaDoc getORB()
1678    {
1679        return my_orb;
1680    }
1681
1682
1683    /**
1684     * Add an agent to the agency's internal tables.
1685     * @param agent the agent to be added
1686     * @param the name of the agent
1687     * @param entry information record on the agent
1688     */

1689    private void registerAgent(MobileObject agent, Name name, AgentInfo entry)
1690    {
1691        synchronized (agentsByRef)
1692        {
1693            agentsByName.put(name, entry);
1694            agentsByRef.put(agent, entry);
1695        }
1696    }
1697
1698
1699    /**
1700     * Remove an agent from the agency's internal tables.
1701     * @param agent the agent to remove
1702     * @param the name of the agent
1703     */

1704    private void unregisterAgent(MobileObject agent, Name name)
1705    {
1706        synchronized(agentsByRef)
1707        {
1708            agentsByName.remove(name);
1709            agentsByRef.remove(agent);
1710        }
1711    }
1712
1713
1714    /**
1715        The agency may invoke System.exit() to make the JVM exit
1716        when the agency is terminated.
1717        @param mode true enables the automatic exit on agency termination, false disables.
1718        @param delay delay in ms before calling System.exit(), after all callbacks
1719        (on agents, on agency personality) have returned; a negative value results in
1720        (1) dedicated system property, or (2) previous value set, or (3) default value to be applied.
1721        @see Constants
1722    */

1723    public void exitOnTerminate(boolean mode, long delay)
1724    {
1725        standalone = mode;
1726        if (standalone && delay >= 0)
1727        {
1728            System.setProperty(Constants.agencyExitDelayProp, String.valueOf(delay));
1729        }
1730    }
1731
1732
1733    /**
1734     * Internal class to launch a delayed exit of process
1735     */

1736    class ExitDelay extends Thread JavaDoc
1737    {
1738        long delay;
1739
1740        public ExitDelay(long ms_delay)
1741        {
1742            delay = ms_delay;
1743            start();
1744        }
1745
1746        public void run()
1747        {
1748            try
1749            {
1750                sleep(delay);
1751            }
1752            catch (InterruptedException JavaDoc ex)
1753            {
1754                System.err.println(ex.toString());
1755            }
1756            System.exit(0);
1757        }
1758    }
1759
1760
1761    ///////////////////////////////////////////////////
1762
// implementation of interface AgencyPersonality //
1763
///////////////////////////////////////////////////
1764

1765
1766    /**
1767     * Call afterBirth() on agent.
1768    */

1769    public void afterBirth(MobileObject agent, AgentSystem agency, AgentInfo entry, Object JavaDoc arguments)
1770        throws BadOperation
1771    {
1772        agent.afterBirth(agency, entry, arguments);
1773    }
1774
1775
1776    /**
1777     * Call beforeMove() on agent.
1778     */

1779    public void beforeMove(MobileObject agent, Location location, String JavaDoc place)
1780        throws BadOperation
1781    {
1782        agent.beforeMove(location, place);
1783    }
1784
1785
1786    /**
1787     * Call afterMove() on agent.
1788     */

1789    public void afterMove(MobileObject agent, AgentSystem agency, Location location, String JavaDoc place)
1790        throws BadOperation
1791    {
1792        agent.afterMove(agency, location, place);
1793    }
1794
1795
1796    /**
1797     * Call afterMoveFailed on agent.
1798     */

1799    public void afterMoveFailed(
1800        MobileObject agent,
1801        Location agency,
1802        String JavaDoc place,
1803        int reason,
1804        String JavaDoc message)
1805    {
1806        agent.afterMoveFailed(agency, place, reason, message);
1807    }
1808
1809
1810    /**
1811     * Call beforeDeath() on agent
1812     */

1813    public void beforeDeath(MobileObject agent)
1814    {
1815        agent.beforeDeath();
1816    }
1817
1818
1819    /**
1820     * Call beforeSuspend() on agent
1821     */

1822    public void beforeSuspend(MobileObject agent)
1823        throws BadOperation
1824    {
1825        agent.beforeSuspend();
1826    }
1827
1828
1829    /**
1830     * Call beforeResume() on agent
1831     */

1832    public void beforeResume(MobileObject agent)
1833        throws BadOperation
1834    {
1835        agent.beforeResume();
1836    }
1837
1838
1839    /**
1840     * Call beforeShutdown() on agent
1841     */

1842    public void beforeShutdown(MobileObject agent)
1843    {
1844        agent.beforeShutdown();
1845    }
1846
1847
1848    /**
1849     * Nothing special to do
1850     */

1851    public void agencyShutdown()
1852    {
1853    }
1854}
1855
Popular Tags