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.PortableInterceptor.ObjectReferenceTemplate;
  45: import org.omg.PortableServer.POAManager;
  46: import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
  47: import org.omg.PortableServer.POAManagerPackage.State;
  48: 
  49: import java.util.HashSet;
  50: import java.util.Iterator;
  51: 
  52: /**
  53:  * The implementation of the POA manager. The manager is a controlled
  54:  * switch that can change its states in response to the method calls
  55:  * and throw exceptions if the requested change is invalid. It is possible
  56:  * to check the state this switch. It does not do anything else.
  57:  *
  58:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  59:  */
  60: public class gnuPOAManager
  61:   extends LocalObject
  62:   implements POAManager
  63: {
  64:   /** 
  65:    * Use serialVersionUID for interoperability. 
  66:    */
  67:   private static final long serialVersionUID = 1;
  68:   
  69:   /**
  70:    * The POAs, controlled by this manager.
  71:    */
  72:   private HashSet POAs = new HashSet();
  73: 
  74:   /**
  75:    * The state of the manager. The newly created manager is always
  76:    * in the holding state.
  77:    */
  78:   State state = State.HOLDING;
  79:   
  80:   /**
  81:    * Get the state of the POA manager.
  82:    */
  83:   public State get_state()
  84:   {
  85:     return state;
  86:   }
  87: 
  88:   /**
  89:    * Turns the associated POAs into active state, allowing them to receive
  90:    * and process requests.
  91:    *
  92:    * @throws if the POAs are in the inactive state. If once inactivated,
  93:    * the POA cannot be activated again. This method can only be called
  94:    * to leave the holding or discarding state.
  95:    */
  96:   public void activate()
  97:                 throws AdapterInactive
  98:   {
  99:     if (state != State.INACTIVE)
 100:       state = State.ACTIVE;
 101:     else
 102:       throw new AdapterInactive();
 103:     
 104:     notifyInterceptors(state.value());    
 105:   }
 106: 
 107:   /**
 108:    * Turns the associated POAs into holding state. In this state, the POAs
 109:    * queue incoming requests but do not process them.
 110:    *
 111:    * @param wait_for_completion if true, the method call suspends the current
 112:    * thread till POAs complete the requests they are currently processing. If
 113:    * false, the method returns immediately.
 114: 
 115:    * @throws AdapterInactive if the POAs are in the inactive state.
 116:    */
 117:   public void hold_requests(boolean wait_for_completion)
 118:                      throws AdapterInactive
 119:   {
 120:     if (state != State.INACTIVE)
 121:       state = State.HOLDING;
 122:     else
 123:       throw new AdapterInactive();
 124:     
 125:     notifyInterceptors(state.value());
 126:     
 127:     if (wait_for_completion)
 128:       waitForIdle();
 129:   }
 130: 
 131:   /**
 132:    *
 133:    * Turns the asociated POAs into inactive state. The POAs in the incative
 134:    * state will reject new requests. If the POA is once inactivated, it
 135:    * cannot be activated again. The operation is used when
 136:    * the associated POAs are to be shut down.
 137:    *
 138:    * @param etherealize_objects if true, the servant managers of the
 139:    * associated POAs, having RETAIN and USE_SERVANT_MANAGER policies,
 140:    * will receive a call of {@link ServantActivatorOperations#etherealize}.
 141:    *
 142:    * @param wait_for_completion if true, the method call suspends the current
 143:    * thread till POAs complete the requests they are currently processing. If
 144:    * false, the method returns immediately.
 145:    *
 146:    * @throws AdapterInactive if the POAs are already in the inactive state.
 147:    *
 148:    * @see POAOperations#destroy
 149:    */
 150:   public void deactivate(boolean etherealize_objects,
 151:                          boolean wait_for_completion
 152:                         )
 153:                   throws AdapterInactive
 154:   {
 155:     if (state == State.INACTIVE)
 156:       throw new AdapterInactive("Repetetive inactivation");
 157:     state = State.INACTIVE;
 158:     
 159:     notifyInterceptors(state.value());    
 160:     
 161:     if (wait_for_completion)
 162:       waitForIdle();
 163: 
 164:     Iterator iter = POAs.iterator();
 165:     while (iter.hasNext())
 166:       {
 167:         gnuPOA poa = (gnuPOA) iter.next();
 168: 
 169:         // If the servant activator is non null, this means it has been
 170:         // set - hence the policies are appropriate.
 171:         if (poa.servant_activator != null)
 172:           poa.etherealizeAll();
 173:       }
 174:   }
 175: 
 176:   /**
 177:    * Turns the associated POAs into discaring state. In this state, the POAs
 178:    * discard the incoming requests. This mode is used in situations when
 179:    * the server is flooded with requests. The client receives remote exception
 180:    * ({@link org.omg.CORBA.TRANSIENT}, minor code 1).
 181:    *
 182:    * @param wait_for_completion if true, the method call suspends the current
 183:    * thread till POAs complete the requests they are currently processing. If
 184:    * false, the method returns immediately.
 185: 
 186:    * @throws AdapterInactive if the POAs are in the inactive state.
 187:    */
 188:   public void discard_requests(boolean wait_for_completion)
 189:                         throws AdapterInactive
 190:   {
 191:     if (state != State.INACTIVE)
 192:       state = State.DISCARDING;
 193:     else
 194:       throw new AdapterInactive();
 195:     
 196:     notifyInterceptors(state.value());    
 197:     
 198:     if (wait_for_completion)
 199:       waitForIdle();
 200:   }
 201: 
 202:   /**
 203:    * Suspend the current thread while at least one of the associated POA is
 204:    * actively processing some requests. The method assumes that the POAs
 205:    * are not accepting the <i>new</i> requests due manager state.
 206:    *
 207:    * @throws BAD_INV_ORDER if the POAs are in the active state.
 208:    */
 209:   public void waitForIdle()
 210:   {
 211:     if (state == State.ACTIVE)
 212:       throw new BAD_INV_ORDER("The state is active");
 213:      
 214:     gnuPOA poa;
 215:     Iterator iter = POAs.iterator();
 216:     
 217:     while (iter.hasNext())
 218:       {
 219:         poa = (gnuPOA) iter.next();
 220:         poa.waitWhileRunning();
 221:       }
 222:   }
 223: 
 224:   /**
 225:    * Add the POA that will be controlled by this manager.
 226:    *
 227:    * @param poa the POA.
 228:    */
 229:   public void addPoa(gnuPOA poa)
 230:   {
 231:     POAs.add(poa);
 232:   }
 233: 
 234:   /**
 235:    * Remove the POA, releasing it from the control of this manager.
 236:    * Called in POA finaliser.
 237:    *
 238:    * @param poa the POA to remove.
 239:    */
 240:   public void removePOA(gnuPOA poa)
 241:   {
 242:     POAs.remove(poa);
 243:   }
 244:   
 245:   /**
 246:    * This method is called when POA is destryed. The interceptors are
 247:    * notified.
 248:    */
 249:   public void poaDestroyed(gnuPOA poa)
 250:   {
 251:     notifyInterceptors(NON_EXISTENT.value); 
 252:   }
 253:   
 254:   /**
 255:    * Notify CORBA 3.0 interceptors about the status change.
 256:    */
 257:   public synchronized void notifyInterceptors(int new_state)
 258:   {
 259:     gnuPOA poa;
 260:     Iterator iter = POAs.iterator();
 261: 
 262:     // The System.identityHashCode is also called in gnuIorInfo.
 263:     while (iter.hasNext())
 264:       {
 265:         poa = (gnuPOA) iter.next();
 266:         if (poa.m_orb.iIor != null)
 267:           {
 268:             poa.m_orb.iIor.adapter_manager_state_changed(
 269:               System.identityHashCode(this), (short) new_state);
 270:           }
 271:       }
 272:   }