Source for gnu.CORBA.Poa.gnuPOAManager

   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:    */
  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:    */
  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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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: }