KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > server > ondemand > ServiceGroup


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.server.ondemand;
25
26 import java.util.*;
27 import java.util.logging.Level JavaDoc;
28 import java.util.logging.Logger JavaDoc;
29 import java.security.AccessController JavaDoc;
30 import java.security.PrivilegedExceptionAction JavaDoc;
31 import java.security.PrivilegedActionException JavaDoc;
32 import com.sun.logging.LogDomains;
33 import com.sun.appserv.server.ServerLifecycle;
34 import com.sun.appserv.server.ServerLifecycleException;
35 import com.sun.enterprise.server.PEMain;
36 import com.sun.enterprise.server.ondemand.entry.*;
37 import com.sun.enterprise.config.ConfigException;
38 import com.sun.enterprise.server.ServerContext;
39 import com.sun.enterprise.InvocationManager;
40 import com.sun.enterprise.ComponentInvocation;
41 import com.sun.enterprise.Switch;
42
43 /**
44  * Super class of all servicegroups. Service group is a collection
45  * of services in application server. Service group design follows
46  * a variant of composite design pattern. Thus each servicegroup
47  * is a composite of other servicegroup.
48  *
49  * This super class basically has the logic to handle the servicegroup
50  * state and a general logic to handle the children of the servicegroup.
51  *
52  * @see ServiceGroupBuilder
53  * @see MainServiceGroup
54  * @see EjbServiceGroup
55  * @see WebServiceGroup
56  * @see ResourcesServiceGroup
57  */

58 public abstract class ServiceGroup {
59
60     protected static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.CORE_LOGGER);
61     private ArrayList sgList = new ArrayList();
62
63     public static final int NOTSTARTED = 0;
64     public static final int STARTING = 1;
65     public static final int STARTED = 2;
66     public static final int STOPPING = 8;
67     public static final int STOPPED = 9;
68
69     private int state = NOTSTARTED;
70
71     private ServerLifecycle[] services = {};
72     private static ArrayList<ServiceGroupListener> listeners;
73
74     static {
75         listeners = new ArrayList();
76         String JavaDoc extListener =
77         System.getProperty("com.sun.enterprise.server.ondemand.ExternalListener");
78         if(extListener != null) {
79             try {
80                 ServiceGroupListener servicegrouplistener =
81                 (ServiceGroupListener)Class.forName(extListener).newInstance();
82                 listeners.add(servicegrouplistener);
83             } catch(Throwable JavaDoc t) {
84                 t.printStackTrace();
85             }
86         }
87     }
88
89     private void notifyListener (int state, ServiceGroup sg) {
90         for (ServiceGroupListener l : listeners) {
91             try {
92                 switch (state) {
93                     case STARTING :
94                         l.beforeStart(sg.getClass().getName());
95                         break;
96                     case STARTED :
97                         l.afterStart(sg.getClass().getName());
98                 }
99             } catch (Throwable JavaDoc t) {
100                 t.printStackTrace();
101             }
102         }
103     }
104
105     public static void addServiceGroupListener(ServiceGroupListener listener) {
106         listeners.add(listener);
107     }
108
109     public static void removeServiceGroupListener(ServiceGroupListener listener) {
110         listeners.remove(listener);
111     }
112
113     /**
114      * Add a servicegroup as child of this servicegroup.
115      */

116     public void addServiceGroup(ServiceGroup group) {
117         sgList.add(group);
118     }
119                                                                                                                              
120     /**
121      * Remove a servicegroup from its children.
122      */

123     public void removeServiceGroup(ServiceGroup group) {
124         sgList.remove(group);
125     }
126
127     /**
128      * Iterator of children.
129      */

130     public Iterator serviceGroupIterator() {
131         return sgList.iterator();
132     }
133
134     /**
135      * If atleast one of the servicegroup that need to be started
136      * is interested in this context, then the servicegroup is
137      * not notified.
138      */

139     public boolean isNotified(EntryContext context) {
140         Iterator it = serviceGroupIterator();
141         while (it.hasNext()) {
142             final ServiceGroup sg = (ServiceGroup) it.next();
143             if (sg.getState() != STARTED) {
144                 if (sg.analyseEntryContext(context)) {
145                      return false;
146                 }
147             }
148         }
149         return true;
150     }
151
152     /**
153      * Logic to start all children based on entrycontext, If any of the child
154      * recognises the entrycontext, then this will attempt to start that
155      * servicegroup.
156      */

157     public void startChildren(final EntryContext context) throws ServiceGroupException {
158         Iterator it = serviceGroupIterator();
159         while (it.hasNext()) {
160             final ServiceGroup sg = (ServiceGroup) it.next();
161
162             if (_logger.isLoggable(Level.FINER)) {
163                 _logger.finer("Trying " + sg + " servicegroup");
164             }
165
166             if (sg.getState() != STARTED) {
167                 if (sg.analyseEntryContext(context)) {
168                     synchronized (sg) {
169                         if (sg.getState() == NOTSTARTED) {
170                             sg.setState(STARTING);
171                             if (_logger.isLoggable(Level.FINE)) {
172                                _logger.fine("Starting " + sg + " servicegroup with context :" + context);
173                             }
174                             notifyListener(STARTING, sg);
175                             ComponentInvocation dummy = preInvoke();
176                             try {
177                                 AccessController.doPrivileged
178                                     (new PrivilegedExceptionAction JavaDoc() {
179                                     public Object JavaDoc run() throws Exception JavaDoc {
180                                         sg.start(context);
181                                         return null;
182                                     }
183                                 });
184                             } catch (PrivilegedActionException JavaDoc pae) {
185                                 throw new ServiceGroupException(
186                                       pae.getException());
187                             } finally {
188                                 postInvoke(dummy);
189                             }
190                             notifyListener(STARTED, sg);
191                             sg.setState(STARTED);
192                         }
193                     }
194                 }
195             }
196         }
197     }
198
199     /**
200      * The preInvoke is used to insert a dummy invocation context to the
201      * invocation chain for everything that happens within the service
202      * startup. This is detected by the InvocationManager and the
203      * threads created from within this context will not inherit the
204      * context of the parent.
205      *
206      * This is required since an application thread might end up in starting
207      * a container. Thread pools managed by that container should not
208      * inherit the properties by the application, since both are unrelated.
209      */

210     private ComponentInvocation preInvoke() {
211         InvocationManager im = Switch.getSwitch().getInvocationManager();
212         ComponentInvocation dummy =
213         new ComponentInvocation(ComponentInvocation.SERVICE_STARTUP);
214         im.preInvoke(dummy);
215         return dummy;
216     }
217
218     /**
219      * See the comment on preInvoke.
220      */

221     private void postInvoke(ComponentInvocation dummy) {
222         InvocationManager im = Switch.getSwitch().getInvocationManager();
223         im.postInvoke(dummy);
224     }
225
226     // Stop all children.
227
public void stopChildren(EntryContext context) throws ServiceGroupException {
228         Iterator it = serviceGroupIterator();
229         while (it.hasNext()) {
230             ServiceGroup sg = (ServiceGroup) it.next();
231             if (sg.getState() != STOPPED && sg.getState() != NOTSTARTED) {
232                 sg.stop(context);
233             }
234         }
235     }
236
237     // Abort all children.
238
public void abortChildren(EntryContext context) {
239         Iterator it = serviceGroupIterator();
240         while (it.hasNext()) {
241             ServiceGroup sg = (ServiceGroup) it.next();
242             if (sg.getState() != STOPPED) {
243                 sg.abort(context);
244             }
245         }
246     }
247
248     // Start lifecycle services. Concrete servicegroup implementations
249
// may use this method.
250
protected void startLifecycleServices(String JavaDoc[][] s, ServerContext sc) {
251         services = new ServerLifecycle[s.length];
252         for (int i =0; i < s.length; i ++) {
253             try {
254                 String JavaDoc service = s[i][1];
255                 ServerLifecycle slc = (ServerLifecycle)
256                 Class.forName(service).newInstance();
257                 services[i] = slc;
258                 slc.onInitialization(sc);
259             } catch (Exception JavaDoc e) {
260                 _logger.log(Level.WARNING, e.getMessage(), e);
261             }
262         }
263
264         for (ServerLifecycle slc : services) {
265             try {
266                 slc.onStartup(sc);
267             } catch (Exception JavaDoc e) {
268                 e.printStackTrace();
269             }
270         }
271
272         for (ServerLifecycle slc : services) {
273             try {
274                 slc.onReady(sc);
275             } catch (Exception JavaDoc e) {
276                 _logger.log(Level.WARNING, e.getMessage(), e);
277             }
278         }
279     }
280
281     // Stop lifecycle services. concrete servicegroup implementations
282
// may use this method.
283
protected void stopLifecycleServices() {
284         for (ServerLifecycle slc : services) {
285             try {
286                 slc.onShutdown();
287             } catch (Exception JavaDoc e) {
288                 _logger.log(Level.WARNING, e.getMessage(), e);
289             }
290         }
291
292         for (ServerLifecycle slc : services) {
293             try {
294                 slc.onTermination();
295             } catch (Exception JavaDoc e) {
296                 _logger.log(Level.WARNING, e.getMessage(), e);
297             }
298         }
299     }
300
301     /**
302      * Triggers the start of the servicegroup. The entry context
303      * that caused this startup is used by the servicegroup to obtain
304      * any startup information it require.
305      *
306      * @param context EntryContext object.
307      * @see EntryContext.
308      */

309     public abstract void start(EntryContext context) throws ServiceGroupException ;
310
311     /**
312      * Analyse the entrycontext and specifies whether this servicegroup
313      * can be started or not.
314      *
315      * @return boolean If true is returned, this servicegroup can be started
316      * If false is returned, the entrycontext is not recognized by the
317      * servicegroup.
318      */

319     public abstract boolean analyseEntryContext(EntryContext context);
320
321     /**
322      * Stop the servicegroup.
323      */

324     public abstract void stop(EntryContext context) throws ServiceGroupException;
325
326     /**
327      * Abort the servicegroup. Unused. For future!
328      */

329     public abstract void abort(EntryContext context);
330
331     /**
332      * Set the state of the servicegroup.
333      */

334     public void setState(int state) {
335         this.state = state;
336     }
337
338     /**
339      * Return the state of the servicegroup.
340      */

341     public int getState() {
342         return this.state;
343     }
344 }
345
Popular Tags