1 /* gnuPOAManager.java --
2    Copyright (C) 2005 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package gnu.CORBA.Poa;
40 
41 import org.omg.CORBA.BAD_INV_ORDER;
42 import org.omg.CORBA.LocalObject;
43 import org.omg.PortableInterceptor.NON_EXISTENT;
44 import org.omg.PortableServer.POAManager;
45 import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
46 import org.omg.PortableServer.POAManagerPackage.State;
47 
48 import java.util.HashSet;
49 import java.util.Iterator;
50 
51 /**
52  * The implementation of the POA manager. The manager is a controlled
53  * switch that can change its states in response to the method calls
54  * and throw exceptions if the requested change is invalid. It is possible
55  * to check the state this switch. It does not do anything else.
56  *
57  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
58  */
59 public class gnuPOAManager
60   extends LocalObject
61   implements POAManager
62 {
63   /**
64    * Use serialVersionUID for interoperability.
65    */
66   private static final long serialVersionUID = 1;
67 
68   /**
69    * The POAs, controlled by this manager.
70    */
71   private HashSet POAs = new HashSet();
72 
73   /**
74    * The state of the manager. The newly created manager is always
75    * in the holding state.
76    */
77   State state = State.HOLDING;
78 
79   /**
80    * Get the state of the POA manager.
81    */
get_state()82   public State get_state()
83   {
84     return state;
85   }
86 
87   /**
88    * Turns the associated POAs into active state, allowing them to receive
89    * and process requests.
90    *
91    * @throws AdapterInactive if the POAs are in the inactive state.
92    * If once inactivated, the POA cannot be activated again. This
93    * method can only be called to leave the holding or discarding state.
94    */
activate()95   public void activate()
96                 throws AdapterInactive
97   {
98     if (state != State.INACTIVE)
99       state = State.ACTIVE;
100     else
101       throw new AdapterInactive();
102 
103     notifyInterceptors(state.value());
104   }
105 
106   /**
107    * Turns the associated POAs into holding state. In this state, the POAs
108    * queue incoming requests but do not process them.
109    *
110    * @param wait_for_completion if true, the method call suspends the current
111    * thread till POAs complete the requests they are currently processing. If
112    * false, the method returns immediately.
113 
114    * @throws AdapterInactive if the POAs are in the inactive state.
115    */
hold_requests(boolean wait_for_completion)116   public void hold_requests(boolean wait_for_completion)
117                      throws AdapterInactive
118   {
119     if (state != State.INACTIVE)
120       state = State.HOLDING;
121     else
122       throw new AdapterInactive();
123 
124     notifyInterceptors(state.value());
125 
126     if (wait_for_completion)
127       waitForIdle();
128   }
129 
130   /**
131    *
132    * Turns the asociated POAs into inactive state. The POAs in the incative
133    * state will reject new requests. If the POA is once inactivated, it
134    * cannot be activated again. The operation is used when
135    * the associated POAs are to be shut down.
136    *
137    * @param etherealize_objects if true, the servant managers of the
138    * associated POAs, having RETAIN and USE_SERVANT_MANAGER policies,
139    * will receive a call of {@link ServantActivatorOperations#etherealize}.
140    *
141    * @param wait_for_completion if true, the method call suspends the current
142    * thread till POAs complete the requests they are currently processing. If
143    * false, the method returns immediately.
144    *
145    * @throws AdapterInactive if the POAs are already in the inactive state.
146    *
147    * @see POAOperations#destroy
148    */
deactivate(boolean etherealize_objects, boolean wait_for_completion )149   public void deactivate(boolean etherealize_objects,
150                          boolean wait_for_completion
151                         )
152                   throws AdapterInactive
153   {
154     if (state == State.INACTIVE)
155       throw new AdapterInactive("Repetetive inactivation");
156     state = State.INACTIVE;
157 
158     notifyInterceptors(state.value());
159 
160     if (wait_for_completion)
161       waitForIdle();
162 
163     Iterator iter = POAs.iterator();
164     while (iter.hasNext())
165       {
166         gnuPOA poa = (gnuPOA) iter.next();
167 
168         // If the servant activator is non null, this means it has been
169         // set - hence the policies are appropriate.
170         if (poa.servant_activator != null)
171           poa.etherealizeAll();
172       }
173   }
174 
175   /**
176    * Turns the associated POAs into discaring state. In this state, the POAs
177    * discard the incoming requests. This mode is used in situations when
178    * the server is flooded with requests. The client receives remote exception
179    * ({@link org.omg.CORBA.TRANSIENT}, minor code 1).
180    *
181    * @param wait_for_completion if true, the method call suspends the current
182    * thread till POAs complete the requests they are currently processing. If
183    * false, the method returns immediately.
184 
185    * @throws AdapterInactive if the POAs are in the inactive state.
186    */
discard_requests(boolean wait_for_completion)187   public void discard_requests(boolean wait_for_completion)
188                         throws AdapterInactive
189   {
190     if (state != State.INACTIVE)
191       state = State.DISCARDING;
192     else
193       throw new AdapterInactive();
194 
195     notifyInterceptors(state.value());
196 
197     if (wait_for_completion)
198       waitForIdle();
199   }
200 
201   /**
202    * Suspend the current thread while at least one of the associated POA is
203    * actively processing some requests. The method assumes that the POAs
204    * are not accepting the <i>new</i> requests due manager state.
205    *
206    * @throws BAD_INV_ORDER if the POAs are in the active state.
207    */
waitForIdle()208   public void waitForIdle()
209   {
210     if (state == State.ACTIVE)
211       throw new BAD_INV_ORDER("The state is active");
212 
213     gnuPOA poa;
214     Iterator iter = POAs.iterator();
215 
216     while (iter.hasNext())
217       {
218         poa = (gnuPOA) iter.next();
219         poa.waitWhileRunning();
220       }
221   }
222 
223   /**
224    * Add the POA that will be controlled by this manager.
225    *
226    * @param poa the POA.
227    */
addPoa(gnuPOA poa)228   public void addPoa(gnuPOA poa)
229   {
230     POAs.add(poa);
231   }
232 
233   /**
234    * Remove the POA, releasing it from the control of this manager.
235    * Called in POA finaliser.
236    *
237    * @param poa the POA to remove.
238    */
removePOA(gnuPOA poa)239   public void removePOA(gnuPOA poa)
240   {
241     POAs.remove(poa);
242   }
243 
244   /**
245    * This method is called when POA is destryed. The interceptors are
246    * notified.
247    */
poaDestroyed(gnuPOA poa)248   public void poaDestroyed(gnuPOA poa)
249   {
250     notifyInterceptors(NON_EXISTENT.value);
251   }
252 
253   /**
254    * Notify CORBA 3.0 interceptors about the status change.
255    */
notifyInterceptors(int new_state)256   public synchronized void notifyInterceptors(int new_state)
257   {
258     gnuPOA poa;
259     Iterator iter = POAs.iterator();
260 
261     // The System.identityHashCode is also called in gnuIorInfo.
262     while (iter.hasNext())
263       {
264         poa = (gnuPOA) iter.next();
265         if (poa.m_orb.iIor != null)
266           {
267             poa.m_orb.iIor.adapter_manager_state_changed(
268               System.identityHashCode(this), (short) new_state);
269           }
270       }
271   }
272 }
273