Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: recoin/system/RuntimeManager.java


1   
2   package recoin.system;
3   
4   import recoin.group.Component;
5   import recoin.group.Module;
6   import recoin.group.ModuleGroup;
7   import recoin.group.connector.AdminConnector;
8   import recoin.system.session.SessionManager;
9   import recoin.exception.*;
10  import recoin.exception.ClassLoadingException;
11  import recoin.exception.InitiationException;
12  
13  import java.util.Enumeration;
14  import java.util.Hashtable;
15  import java.util.Vector;
16  
17  import org.apache.log4j.Logger;
18  
19  /**
20   * The RuntimeManager administrates and observes the runtime components of the application.
21   * <br><br>
22   * A RuntimeManager executes orders received from an ApplicationManager object. Because
23   * the RuntimeManager is a central object that holds references to all runtime components, 
24   * all exceptions and logging is handled here.
25   * @author Jan H. Scheufen
26   * @version 0.2.9
27   */
28  public class RuntimeManager 
29  {
30    /**
31     * The global properties that were set in the configuration file.
32     */
33    private Hashtable properties;
34    /**
35     * The SessionManager.
36     */
37    private SessionManager sessionManager;
38    /**
39     * The ApplicationManager that controls the application.
40     */
41    private ApplicationManager applicationManager;
42    /**
43     * The RepositoryManager to load and unload Module objects to and from the layers.
44     */
45    private RepositoryManager repositoryManager;
46    /**
47     * The remote administration service.
48     */
49    private AdminConnector remoteAdmin;
50    /**
51     * The ModuleGroups.
52     */
53    private Hashtable moduleGroups;
54    /**
55     * The logger for this class.
56     */
57    static Logger logger;
58    
59    /**
60     * Creates a new RuntimeManager that is controlled by the specified ApplicationManager.
61     * It is initiated with the specified properties and uses the data in the specified
62     * Repository by loading the RepositoryManager class that is declared in the
63     * Repository.
64     * @param aManager the ApplicationManager that controls this RuntimeManager
65     * @param props the global properties
66     * @param rep the Repository to use
67     * @throws recoin.exception.ClassLoadingException
68     */
69    public RuntimeManager(ApplicationManager aManager, Hashtable props, Repository rep) throws ClassLoadingException 
70    {
71      // Initialize the logger for this class.
72      logger = Logger.getLogger( RuntimeManager.class.getName() );
73      logger.info(System.getProperty("line.separator") + "        ######################################" + System.getProperty("line.separator") +
74                  "-------<||||||||  Starting up RECOIN  ||||||||>--------------------------------------<<<<<<" + System.getProperty("line.separator") +
75                  "        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");
76      moduleGroups = new Hashtable();
77      properties = props;
78  
79      applicationManager = aManager;
80      sessionManager = new SessionManager(this);
81      try
82      {
83        repositoryManager = (RepositoryManager)Class.forName(rep.getClassname()).newInstance();
84        repositoryManager.setRepository(rep);
85        repositoryManager.setRuntimeManager(this);
86        repositoryManager.initiate();
87        logger.info("RepositoryManager "+repositoryManager.getClass().getName()+" loaded successfully.");
88      }
89      catch( ClassNotFoundException e )
90      {
91        throw new ClassLoadingException( "Couldn't find class for RepositoryManager "+rep.getClassname(), e );
92      }
93      catch( InstantiationException e )
94      {
95        throw new ClassLoadingException( "Couldn't initiate RepositoryManager "+rep.getClassname(), e );
96      }
97      catch( IllegalAccessException e )
98      {
99        throw new ClassLoadingException( "Illegal Access for class "+rep.getClassname(), e );
100     }
101     catch (InitiationException e)
102     {
103       logger.error("RepositoryManager "+rep.getClassname()+" not initiated!");
104     }
105         
106     logger.info("Starting remote administration service.");
107     remoteAdmin = new AdminConnector( this );
108 
109     logger.debug("Populating module groups.");
110     String groupname = "";
111     
112     // ##### Connector Group #####
113     groupname = ModuleGroup.CONNECTOR;
114     moduleGroups.put( groupname, createModuleGroup(groupname) );
115 
116     // ##### PreQuery Group #####
117     groupname = ModuleGroup.PREQUERY;
118     moduleGroups.put( groupname, createModuleGroup(groupname) );
119 
120     // ##### Adapter Group #####
121     groupname = ModuleGroup.ADAPTER;
122     moduleGroups.put( groupname, createModuleGroup(groupname) );
123 
124     // ##### PostResult Group #####
125     groupname = ModuleGroup.POSTRESULT;
126     moduleGroups.put( groupname, createModuleGroup(groupname) );
127 
128   }
129   
130   /**
131    * Returns the ModuleGroups in a Hashtable where the groupnames are the keys.
132    * @return the ModuleGroups
133    */
134   public Hashtable getModuleGroups()
135   {
136     return moduleGroups;
137   }
138 
139   /**
140    * Returns the RepositoryManager that is used to access the repository.
141    * @return the RepositoryManager
142    */
143   public RepositoryManager getRepositoryManager()
144   {
145     return repositoryManager;
146   }
147 
148   /**
149    * Returns the SessionManager.
150    * @return the SessionManager
151    */
152   public SessionManager getSessionManager()
153   {
154     return sessionManager;
155   }
156   
157   /**
158    * Removes those modules from the specified Vector which have their
159    * <code>activate</code> field set to false and returns the resulting Vector.
160    * @param modules a Vector of Module objects
161    * @return the filtered Vector
162    */
163   private Vector getStartupModules( Vector modules )
164   {
165     // Reset all Components inside of Module objects to uninitiated and remove unwanted modules.
166     for( Enumeration enum = modules.elements(); enum.hasMoreElements(); )
167     {
168       Module m = (Module) enum.nextElement();
169       for( Enumeration compEnum = m.getComponents().elements(); compEnum.hasMoreElements(); )
170       {
171         try
172         {
173           Component component = (Component)compEnum.nextElement();
174           component.setInitiated(false);
175           repositoryManager.updateComponent( component );
176         }
177         catch (RepositoryException e)
178         {
179           logger.error("Unable to update Component in repository.",e);
180         }
181       }
182       if( !m.getActivateOnStartup() )
183       {
184         try
185         {
186           modules.remove( m );
187           m.setActive(false);
188           repositoryManager.updateModule( m );
189         }
190         catch (RepositoryException e)
191         {
192           logger.error("Unable to update Module with id="+m.getID(),e);
193         }
194       }
195     }
196     logger.debug("Found "+modules.size()+" Modules to load on startup.");
197     return modules;
198   }
199   
200   /**
201    * Creates and returns a ModuleGroup for the specified groupname that is automatically
202    * populated with the Modules of the same groupname that have declared to be loaded
203    * on startup, i.e. have their <code>activate</code> field set to <code>true</code>.
204    * @param groupname the name of the ModuleGroup
205    * @return the new ModuleGroup
206    */
207   private ModuleGroup createModuleGroup( String groupname )
208   {
209     ModuleGroup group = (ModuleGroup) new ModuleGroup( this, groupname );
210     Vector modules = new Vector();
211     try
212     {
213       modules = repositoryManager.getModulesByGroupname(groupname);
214     }
215     catch (RepositoryException e)
216     {
217       logger.error("Couldn't get Modules for groupname="+groupname+" from repository.", e);
218     }
219     modules = getStartupModules( modules );
220     logger.debug("Found total of "+modules.size()+" startup Modules for ModuleGroup name="+groupname);
221     // Set modules and activate them.
222     if( modules.size() > 0 )
223     {
224       group.setModules( modules );
225     }
226     logger.info("ModuleGroup '"+groupname+"' created successfully.");
227     // Update repository.
228     logger.debug("Updating Module information in repository for newly added Module objects.");
229     for( Enumeration enum = modules.elements(); enum.hasMoreElements(); )
230     {
231       try
232       {
233         Module module = (Module) enum.nextElement();
234         repositoryManager.updateModule( module );
235       }
236       catch (RepositoryException e)
237       {
238         logger.error("Unable to update Module after activating Module objects in group '"+groupname+"'.",e);
239       }
240     }
241     return group;
242   }
243 
244   /**
245    * Loads the specified Component into the Module with the specified ID.
246    * After locating the Module, the Component is added to the Module. If the
247    * Component had already been loaded previously, it is first removed
248    * and then added again, thus performing a reload.
249    * @param component the Component to load
250    * @param moduleID the ID of the Module
251    * @return true if Component has been added successfully, false otherwise
252    */
253   public boolean loadComponent(Component component, int moduleID)
254   {
255     // find Module object in moduleGroups
256     for( Enumeration groupKeys = moduleGroups.keys(); groupKeys.hasMoreElements(); )
257     {
258       String name = (String)groupKeys.nextElement();
259       ModuleGroup group = (ModuleGroup)moduleGroups.get( name );
260       for( Enumeration modules = group.getModules().elements(); modules.hasMoreElements(); )
261       {
262         Module module = (Module)modules.nextElement();
263         if( module.getID() == moduleID )
264         {
265           for( Enumeration compEnum = module.getComponents().elements(); compEnum.hasMoreElements(); )
266           {
267             Component comp = (Component)compEnum.nextElement();
268             if( comp.getID() == component.getID() )
269             {
270               module.removeComponent( comp );
271             }
272           }
273           // add the Component to the Module
274           module.addComponent( component );
275         }
276       }
277     }
278 
279     try
280     {
281       // to make sure, first unload Component in repository. Otherwise RepositoryException
282       // might be thrown because of duplicate key entry!
283       repositoryManager.unloadComponent( component.getID(), moduleID );
284       // update the relationship between Component and Module
285       repositoryManager.loadComponent( component.getID(), moduleID );
286       // update the state of the Component loaded in the Module
287       repositoryManager.updateComponent( component, moduleID );      
288     }
289     catch (RepositoryException e)
290     {
291       logger.error("Unable to update repository while (re)loading Component with id="+component.getID()+" to Module with id="+moduleID,e);
292       return false;
293     }
294     return true;
295   }
296 
297   /**
298    * Unloads the specified Component from the Module with the specified ID.
299    * After locating the Module, the Component is removed from the Module and
300    * its <code>initiated</code> field is set to <code>false</code>.
301    * @param component the Component to load
302    * @param moduleID the ID of the Module
303    * @return true if Component has been removed successfully, false otherwise
304    */
305   public boolean unloadComponent(int componentID, int moduleID)
306   {
307     // find Module object in moduleGroups
308     for( Enumeration groupKeys = moduleGroups.keys(); groupKeys.hasMoreElements(); )
309     {
310       String name = (String)groupKeys.nextElement();
311       ModuleGroup group = (ModuleGroup)moduleGroups.get( name );
312       for( Enumeration modules = group.getModules().elements(); modules.hasMoreElements(); )
313       {
314         Module module = (Module)modules.nextElement();
315         if( module.getID() == moduleID )
316         {
317           Component component;
318           // remove Component if it is contained in the Module.
319           for( Enumeration enum = module.getComponents().elements(); enum.hasMoreElements(); )
320           {
321             component = (Component) enum.nextElement();
322             if( component.getID() == componentID )
323             {
324               module.removeComponent( component );
325               // since only one Component with the same id can be in Module, break for-loop
326               break;
327             }
328           }
329         }
330       }
331     }
332 
333     try
334     {
335       // update the relationship between Component and Module in the repository.
336       // the state of the Component is automatically lost, so Component doesn't have
337       // to be updated!
338       repositoryManager.unloadComponent( componentID, moduleID );
339     }
340     catch (RepositoryException e)
341     {
342       logger.error("Unable to update repository while unloading Component with id="+componentID+" from Module with id="+moduleID,e);
343       return false;
344     }
345     return true;
346   }
347 
348   /**
349    * Deploys the specfified Module to the ModuleGroup that has the same groupname.
350    * After the Module is added to the ModuleGroup, it is activated.
351    * @param module the Module
352    */
353   public void deployModule(Module module)
354   {
355     ModuleGroup group = (ModuleGroup)moduleGroups.get( module.getGroupname() );
356     if( group.getModules().contains( module ))
357       logger.warn("Module id="+module.getID()+" already contained in ModuleGroup '"+group.getGroupname());
358     else
359       logger.debug("Adding Module id="+module.getID()+" to ModuleGroup '"+group.getGroupname());
360     try
361     {
362       // add Module to ModuleGroup and activate
363       group.addModule( module );
364       // update repository
365       repositoryManager.activateModule( module.getID(), module.isActive() );
366       // Also update Component objects.
367       for( Enumeration compEnum = module.getComponents().elements(); compEnum.hasMoreElements(); )
368       {
369         Component component = (Component)compEnum.nextElement();
370         // update initiated state of component in repository
371         repositoryManager.updateComponent( component, module.getID() );
372       }
373       logger.debug("Module with id="+module.getID()+" successfully deployed to group '"+group.getGroupname()+"'.");
374     }
375     catch (IllegalModuleException e)
376     {
377       logger.error("Unable to add Module with id="+module.getID()+" to ModuleGroup "+group.getGroupname(),e);
378     }
379     catch (RepositoryException e)
380     {
381       logger.error("Unable to update Module with id="+module.getID()+" in repository.",e);
382     }
383   }
384 
385   /**
386    * Undeploys the Module with the specified ID. Because only the ID is used to
387    * locate the Module, all ModuleGroups are searched and any Modules with the
388    * same ID are removed. In general this shouldn't happen, because there should
389    * only be one ModuleGroup for each groupname.
390    * @param id the ID of the Module
391    */
392   public void undeployModule(int id)
393   {
394     // find Module object in moduleGroups
395     for( Enumeration groupKeys = moduleGroups.keys(); groupKeys.hasMoreElements(); )
396     {
397       String name = (String)groupKeys.nextElement();
398       ModuleGroup group = (ModuleGroup)moduleGroups.get( name );
399       for( Enumeration modules = group.getModules().elements(); modules.hasMoreElements(); )
400       {
401         Module module = (Module)modules.nextElement();
402         if( module.getID() == id )
403         {
404           try
405           {
406             // Remove Module from ModuleGroup and deactivate.
407             group.removeModule( module );
408             // Update state of Module in repository 
409             repositoryManager.activateModule( module.getID(), module.isActive() );
410             // Also update Component objects.
411             for( Enumeration compEnum = module.getComponents().elements(); compEnum.hasMoreElements(); )
412             {
413               Component component = (Component)compEnum.nextElement();
414               component.setInitiated(false);
415               // update initiated state of component in repository
416               repositoryManager.updateComponent( component, module.getID() );
417             }
418           }
419           catch (RepositoryException e)
420           {
421             logger.error("Unable to update repository while undeploying Module with id="+id,e);
422           }
423         }
424       }
425     }
426   }
427 
428 }