KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > julia > control > lifecycle > BasicLifeCycleControllerMixin


1 /***
2  * Julia: France Telecom's implementation of the Fractal API
3  * Copyright (C) 2001-2002 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: Eric.Bruneton@rd.francetelecom.com
20  *
21  * Author: Eric Bruneton
22  */

23
24 package org.objectweb.fractal.julia.control.lifecycle;
25
26 import org.objectweb.fractal.api.Component;
27 import org.objectweb.fractal.api.NoSuchInterfaceException;
28 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
29 import org.objectweb.fractal.api.factory.InstantiationException;
30
31 import org.objectweb.fractal.julia.Controller;
32 import org.objectweb.fractal.julia.InitializationContext;
33 import org.objectweb.fractal.julia.factory.ChainedInstantiationException;
34
35 /**
36  * Provides a basic implementation of the {@link
37  * org.objectweb.fractal.api.control.LifeCycleController} interface.
38  * This implementation is based on a counter managed by interceptors. This
39  * controller needs associated interceptor objects, such as those generated by
40  * the {@link org.objectweb.fractal.julia.asm.InterceptorClassGenerator} with a
41  * {@link org.objectweb.fractal.julia.asm.LifeCycleCodeGenerator}, in order to
42  * work properly (these interceptors are only needed on external server
43  * interfaces).
44  * <br>
45  * <br>
46  * <b>Requirements</b>
47  * <ul>
48  * <li>the component to which this controller object belongs must provide the
49  * {@link Component} interface and the {@link LifeCycleCoordinator}
50  * interface.</li>
51  * </ul>
52  */

53
54 public abstract class BasicLifeCycleControllerMixin
55   implements Controller, LifeCycleCoordinator
56 {
57
58   // -------------------------------------------------------------------------
59
// Private constructor
60
// -------------------------------------------------------------------------
61

62   private BasicLifeCycleControllerMixin () {
63   }
64
65   // -------------------------------------------------------------------------
66
// Fields and methods added and overriden by the mixin class
67
// -------------------------------------------------------------------------
68

69   /**
70    * The life cycle state of this component. Zero means stopped, one means
71    * stopping and two means started.
72    */

73
74   public int fcState;
75
76   /**
77    * The number of currently executing method calls in this component.
78    */

79
80   public int fcInvocationCounter;
81
82   /**
83    * The coordinator used to stop this component with other components
84    * simultaneously.
85    */

86
87   public LifeCycleCoordinator fcCoordinator;
88
89   /**
90    * Initializes the fields of this mixin and then calls the overriden method.
91    *
92    * @param ic information about the component to which this controller object
93    * belongs.
94    * @throws InstantiationException if the initialization fails.
95    */

96
97   public void initFcController (final InitializationContext ic)
98     throws InstantiationException JavaDoc
99   {
100     try {
101       if (!(ic.getInterface("lifecycle-controller") instanceof LifeCycleCoordinator)) {
102         throw new Exception JavaDoc();
103       }
104     } catch (Exception JavaDoc e) {
105       try {
106         ic.getInterface("/lifecycle-coordinator");
107       } catch (Exception JavaDoc f) {
108         throw new ChainedInstantiationException(
109           f, null, "The component must provide a LifeCycleCoordinator interface");
110       }
111     }
112     _super_initFcController(ic);
113   }
114
115   // -------------------------------------------------------------------------
116
// Implementation of the LifeCycleController interface
117
// -------------------------------------------------------------------------
118

119   public String JavaDoc getFcState () {
120     return fcState == 0 ? STOPPED : STARTED;
121   }
122
123   public void startFc () throws IllegalLifeCycleException {
124     if (fcState != 2) {
125       _this_setFcState(true);
126     }
127   }
128
129   public void stopFc () throws IllegalLifeCycleException {
130     if (fcState == 2) {
131       _this_stopFc(new LifeCycleCoordinator[] { getFcCoordinator() });
132       _this_setFcState(false);
133     }
134   }
135
136   // -------------------------------------------------------------------------
137
// Implementation of the LifeCycleCoordinator interface
138
// -------------------------------------------------------------------------
139

140   public boolean setFcStarted () throws IllegalLifeCycleException {
141     synchronized (this) {
142       if (fcState == 2) {
143         return false;
144       }
145       fcState = 2;
146       /**
147        * The following line unblock the threads that may be blocked in the
148        * component, in the incrementFcInvocationCounter method.
149        */

150       notifyAll();
151       return true;
152     }
153   }
154
155   public void setFcStopping (final LifeCycleCoordinator coordinator)
156     throws IllegalLifeCycleException
157   {
158     synchronized (this) {
159       fcState = 1;
160       fcCoordinator = coordinator;
161       if (fcInvocationCounter == 0) {
162         fcCoordinator.fcInactivated(getFcCoordinator());
163       }
164     }
165   }
166
167   public boolean setFcStopped () throws IllegalLifeCycleException {
168     synchronized (this) {
169       if (fcState == 0) {
170         return false;
171       }
172       fcState = 0;
173       fcCoordinator = null;
174       return true;
175     }
176   }
177
178   // -------------------------------------------------------------------------
179
// Methods called by the associated interceptor
180
// -------------------------------------------------------------------------
181

182   /**
183    * Increments the number of currently executing method calls in this
184    * component. If the component is started this method just increments this
185    * counter. If the component is stopped, it waits until the component is
186    * restarted, and then increments the counter. Finally, if the component is
187    * stopping, there are two cases. If the counter is not null, it is just
188    * incremented. If it is null, this method asks the coordinator if the method
189    * call can be executed, or if it should be delayed until the component is
190    * restarted. The method then blocks or not, depending on the coordinator's
191    * response, before incrementing the counter.
192    */

193
194   public void incrementFcInvocationCounter () {
195     /* this code is inlined in the interceptor objects
196     synchronized (this) {
197       if (fcState == 2) {
198         ++fcInvocationCounter;
199         return;
200       } */

201       boolean ok;
202       do {
203         if (fcState == 0) {
204           ok = false;
205         } else if (fcState == 1) {
206           if (fcInvocationCounter == 0) {
207             ok = fcCoordinator.fcActivated(getFcCoordinator());
208           } else {
209             ok = true;
210           }
211         } else {
212           ok = true;
213         }
214         if (!ok) {
215           try {
216             wait();
217           } catch (final InterruptedException JavaDoc e) {
218           }
219         }
220       } while (!ok);
221       ++fcInvocationCounter;
222     /* } */
223   }
224
225   /**
226    * Decrements the number of currently executing method calls in this
227    * component. If the component is stopping, and if the counter of currently
228    * executing method calls becomes null after being decremented, this method
229    * notifies the coordinator that the component has become inactive.
230    */

231
232   public void decrementFcInvocationCounter () {
233     /* this code is inlined in the interceptor objects
234     synchronized (this) {
235       if (fcState == 2) {
236         --fcInvocationCounter;
237         return;
238       } */

239       --fcInvocationCounter;
240       if (fcInvocationCounter == 0) {
241         fcCoordinator.fcInactivated(getFcCoordinator());
242       }
243     /* } */
244   }
245
246   // -------------------------------------------------------------------------
247
// Utility methods
248
// -------------------------------------------------------------------------
249

250   /**
251    * Returns the {@link LifeCycleCoordinator} interface of this component.
252    *
253    * @return the {@link LifeCycleCoordinator} interface of the component to
254    * which this controller object belongs.
255    */

256
257   public LifeCycleCoordinator getFcCoordinator () {
258     try {
259       return (LifeCycleCoordinator)_this_weaveableC.
260         getFcInterface("lifecycle-controller");
261     } catch (Exception JavaDoc e) {
262       try {
263         return (LifeCycleCoordinator)_this_weaveableC.
264           getFcInterface("/lifecycle-coordinator");
265       } catch (NoSuchInterfaceException f) {
266         throw new Error JavaDoc("Internal error"); // should not happen
267
}
268     }
269   }
270
271   // -------------------------------------------------------------------------
272
// Fields and methods required by the mixin class in the base class
273
// -------------------------------------------------------------------------
274

275   /**
276    * The <tt>weaveableC</tt> field required by this mixin. This field is
277    * supposed to reference the {@link Component} interface of the component to
278    * which this controller object belongs.
279    */

280
281   public Component _this_weaveableC;
282
283   /**
284    * The <tt>setFcState</tt> method required by this mixin. This method is
285    * supposed to work as this {@link BasicLifeCycleCoordinatorMixin#setFcState
286    * setFcState} method.
287    *
288    * @param started <tt>true</tt> to set the lifecycle state of the components
289    * to {@link #STARTED STARTED}, or <tt>false</tt> to set this state to
290    * {@link #STOPPED STOPPED}.
291    * @throws IllegalLifeCycleException if a problem occurs.
292    */

293
294   public abstract void _this_setFcState (boolean started)
295     throws IllegalLifeCycleException;
296
297   /**
298    * The <tt>stopFc</tt> method required by this mixin. This method is
299    * supposed to work as this {@link BasicLifeCycleCoordinatorMixin#stopFc
300    * stopFc} method.
301    *
302    * @param components the {@link LifeCycleCoordinator} interface of the
303    * components to be stopped.
304    * @throws IllegalLifeCycleException if a problem occurs.
305    */

306
307   public abstract void _this_stopFc (LifeCycleCoordinator[] components)
308     throws IllegalLifeCycleException;
309
310   /**
311    * The {@link Controller#initFcController initFcController} method overriden
312    * by this mixin.
313    *
314    * @param ic information about the component to which this controller object
315    * belongs.
316    * @throws InstantiationException if the initialization fails.
317    */

318
319   public abstract void _super_initFcController (InitializationContext ic)
320     throws InstantiationException JavaDoc;
321 }
322
Popular Tags