KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > prose > RootComponent


1 //
2
// This file is part of the prose package.
3
//
4
// The contents of this file are subject to the Mozilla Public License
5
// Version 1.1 (the "License"); you may not use this file except in
6
// compliance with the License. You may obtain a copy of the License at
7
// http://www.mozilla.org/MPL/
8
//
9
// Software distributed under the License is distributed on an "AS IS" basis,
10
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
// for the specific language governing rights and limitations under the
12
// License.
13
//
14
// The Original Code is prose.
15
//
16
// The Initial Developer of the Original Code is Andrei Popovici. Portions
17
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
18
// All Rights Reserved.
19
//
20
// Contributor(s):
21
// $Id: RootComponent.java,v 1.1.1.1 2003/07/02 15:30:51 apopovic Exp $
22
// =====================================================================
23
//
24
// (history at end)
25
//
26

27 package ch.ethz.prose;
28
29 // used packages
30
import java.lang.reflect.InvocationTargetException JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.lang.reflect.Modifier JavaDoc;
33 import java.util.Arrays JavaDoc;
34 import java.util.Enumeration JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.TreeSet JavaDoc;
39 import java.util.Vector JavaDoc;
40
41 /**
42  * Class RootComponent looks for properties called
43  * "ch.ethz.prose.ESSystem.X", where X is 0,1,2,..; If this
44  * property is defined and represents a class name which
45  * has two static methods with no parameters called <code>startup</code>
46  * and <code>teardown</code> then the <code>startup</code> method is
47  * called for this class. These methods should only throw
48  * <code>SystemStartupException</code> or
49  * <code>SystemTeardownException</code> respectively.
50  * The class specified in the property has to implement the interface
51  * <code>Component</code>.
52  *
53  * @property ch.ethz.prose.ESSystem.X
54  * <b>Values:</b> A class name containing static startup and teardown methods.
55  * Current possible values:
56  * <ul>
57  * <li> <code>ch.ethz.prose.ExtensionViewerSystem</code>
58  * <li> <code>ch.ethz.prose.dist.JiniExtensionSystem</code>
59  * <li> <code>ch.ethz.prose.dist.RemoteExtensionSystem</code>
60  * </ul>
61  * <br>
62  * <b>Usage:</b> controls aditional services to be started up together
63  * with the <code>ProseSystem</code> itself. Note that <em>X</em> is
64  * a placeholder for 1,2,3,..
65  *
66  *
67  * @version $Revision: 1.1.1.1 $
68  * @author Philippe Schoch
69  */

70 public
71 class RootComponent implements Component {
72
73   static List JavaDoc startupMethods = null;
74   static List JavaDoc teardownMethods = null;
75   public static boolean reverseOrder = false;
76
77
78   static boolean isStarted = false;
79   /**
80    *
81    * @param
82    */

83   protected RootComponent( )
84     {
85
86     }
87
88
89   /**
90    * Search the property set for properies named
91    * <code>ch.ethz.prose.ESSystem.X</code>, where X may be
92    * 0, 1, 2, ..etc.
93    * If the values of the properties denote classnames and
94    * each of the classNames has a method called <code>startup</code> throwing
95    * a <code>ExtensionSystemStartupException</code> and a method called <code>teardown</code>
96    * throwing a <code>ExtensionSystemTeardownException</code> then this <code>startup</code>
97    * method is executed.
98    */

99   public static synchronized void startup() throws SystemStartupException
100     {
101       if (isStarted)
102     return;
103       isStarted=true;
104
105       startupMethods = new Vector JavaDoc();
106       teardownMethods = new Vector JavaDoc();
107
108       // initialize the startup/teardown methods of all components
109
initStartupTeardownMethods();
110
111       // call inital startup functionality of all components
112
doStartup();
113     }
114
115   /**
116    * Call every <code>teardown</code> method one by one of every started <code>Component</code>
117    * in the order they are started.
118    * If <code>teardown</code> methods should be called in the reverse order as the <code>startup</code> calls
119    * simply set the flag <code>reverseOrder</code> to <code>true</code>. By default this flag is set to
120    * <code>false<code/>.
121    */

122   public synchronized static void teardown() throws SystemTeardownException
123     {
124       if (!isStarted)
125     return;
126       isStarted=false;
127         if (reverseOrder)
128         {
129         synchronized(teardownMethods)
130                 {
131             List JavaDoc temp = new Vector JavaDoc();
132             while (!(teardownMethods.isEmpty()))
133                 {
134                 temp.add(0, ((Vector JavaDoc)teardownMethods).firstElement());
135                 teardownMethods.remove(0);
136                 }
137                 teardownMethods = temp;
138             }
139         }
140
141     // call inital teardown functionality of all components
142
doTeardown();
143     }
144
145
146   private static void initStartupTeardownMethods() throws SystemStartupException
147     {
148         Set JavaDoc propNames = new TreeSet JavaDoc();
149     List JavaDoc clsNames = new Vector JavaDoc();
150     Enumeration JavaDoc keys = System.getProperties().keys();
151     String JavaDoc propPrefix = "ch.ethz.prose.ESSystem.";
152
153     // retrieve the matching property names
154
while(keys.hasMoreElements())
155         {
156             String JavaDoc crtPropName = (String JavaDoc)keys.nextElement();
157             if (crtPropName.startsWith(propPrefix) &&
158                 crtPropName.length() > propPrefix.length())
159                 propNames.add(crtPropName);
160         }
161
162     Iterator JavaDoc j = propNames.iterator();
163     while (j.hasNext())
164         clsNames.add(System.getProperty((String JavaDoc)j.next()));
165
166     // retrieve the matching classNames
167
Iterator JavaDoc i = clsNames.iterator();
168     while(i.hasNext())
169         {
170             String JavaDoc crtClsName = null;
171             Method JavaDoc startupMethod = null;
172             Method JavaDoc teardownMethod = null;
173             try
174                 {
175                     crtClsName = (String JavaDoc)i.next();
176                     Class JavaDoc sysClass = Class.forName(crtClsName);
177                     startupMethod = sysClass.getMethod("startup",new Class JavaDoc[]{});
178                     teardownMethod = sysClass.getMethod("teardown",new Class JavaDoc[]{});
179
180                     if ( ((startupMethod.getModifiers() & Modifier.STATIC) != Modifier.STATIC) ||
181                          ((teardownMethod.getModifiers() & Modifier.STATIC) != Modifier.STATIC) ||
182                          (!Arrays.asList(startupMethod.getExceptionTypes()).contains(SystemStartupException.class)) ||
183                          (!Arrays.asList(teardownMethod.getExceptionTypes()).contains(SystemTeardownException.class)))
184                         throw new SystemStartupException("methods startup/teardown are non-static or don't have" +
185                                                          " compatible throws clauses");
186                 }
187             catch (ClassNotFoundException JavaDoc noSuchClass)
188                 { throw new SystemStartupException("Startup class " + crtClsName + " not found"); }
189             catch (NoSuchMethodException JavaDoc noSuchMethod)
190                 { throw new SystemStartupException("startup and teardown methods not present in class " + crtClsName); }
191
192             startupMethods.add(startupMethod);
193             teardownMethods.add(teardownMethod);
194         }
195
196     // Collections.reverse(teardownMethods);
197
}
198
199
200   private static void doStartup() throws SystemStartupException
201     {
202         Iterator JavaDoc i = null;
203
204         i=startupMethods.iterator();
205
206         try
207             {
208                 while (i.hasNext())
209                     {
210                         Method JavaDoc crtMeth = (Method JavaDoc)i.next();
211                         crtMeth.invoke(null,new Object JavaDoc[]{});
212                     }
213             }
214         catch (IllegalAccessException JavaDoc notPublic)
215             {
216                 notPublic.printStackTrace();
217                 throw new SystemStartupException("Cannot access startup method");
218             }
219         catch (InvocationTargetException JavaDoc realException)
220             {
221                 realException.printStackTrace();
222                 throw (SystemStartupException)realException.getTargetException();
223             }
224     }
225
226
227   private static void doTeardown() throws SystemTeardownException
228     {
229         Iterator JavaDoc i = null;
230
231         i=teardownMethods.iterator();
232
233         try
234             {
235                 while (i.hasNext())
236                     {
237                         Method JavaDoc crtMeth = (Method JavaDoc)i.next();
238                         crtMeth.invoke(null,new Object JavaDoc[]{});
239                     }
240             }
241         catch (IllegalAccessException JavaDoc notPublic)
242             {
243                 throw new SystemTeardownException("Cannot access teardown method");
244             }
245         catch (InvocationTargetException JavaDoc realException)
246             {
247                 throw (SystemTeardownException)realException.getTargetException();
248             }
249     }
250
251 }
252
253
254 //======================================================================
255
//
256
// $Log: RootComponent.java,v $
257
// Revision 1.1.1.1 2003/07/02 15:30:51 apopovic
258
// Imported from ETH Zurich
259
//
260
// Revision 1.3 2003/05/26 17:49:44 popovici
261
// changes in the portnames; idempotent methods better implemented. ProseSystem now depends on the remote prose
262
//
263
// Revision 1.2 2003/05/06 15:51:27 popovici
264
// Mozilla-ification
265
//
266
// Revision 1.1 2003/05/05 13:58:31 popovici
267
// renaming from runes to prose
268
//
269
// Revision 1.6 2003/04/17 15:15:13 popovici
270
// Extension->Aspect renaming
271
//
272
// Revision 1.5 2003/03/04 18:36:38 popovici
273
// Organization of imprts
274
//
275
// Revision 1.4 2003/03/04 11:27:15 popovici
276
// Important refactorization step (march):
277
// - removal of 'JoinPointEvents'; JoinPoints now have the same function as events
278
// - reimplementation of the JVMAIDebuggerAspectInterface (better performance, coding conventions, removal of ProseVM
279
// structures
280
//
281
// Revision 1.3 2003/01/17 21:09:46 pschoch
282
// Bug fix: in RootComponent new variable propNames for sorting PropertyNames; variable clsNames changed to Vector
283
//
284
// Revision 1.2 2003/01/17 12:14:42 pschoch
285
// Bug fixes
286
// Unused variable 'clsObjects' deleted
287
// Variable 'clsNames' changed from 'HashSet' to 'TreeSet' to enforce
288
// property reading in the correct order
289
//
290
// Revision 1.1 2002/11/26 17:14:32 pschoch
291
// RootComponent now added (replaces RootComponent now added (replaces old ProseSystem)
292
// ProseSystem now owns and starts the Aspect interface.
293
// ProseSystem now containes a 'test' AspectManager
294
// AspectManager now owns the JoinPointManager.
295
// ExtensionManger can be 'connected' to the JVM, or disconnected. The
296
// JoinPointManager of a connected Ext.Mgr enables joinpoints; the
297
// JoinPointManger of a disconnected Ext.Mgr never enables join-points
298
// Documentation updated accordingly.
299
//
300
Popular Tags