Source for java.rmi.activation.ActivationGroup

   1: /* ActivationGroup.java -- the RMI activation group.
   2:    Copyright (c) 1996, 1997, 1998, 1999, 2006 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 java.rmi.activation;
  40: 
  41: import gnu.java.rmi.activation.DefaultActivationGroup;
  42: import gnu.java.rmi.activation.DefaultActivationSystem;
  43: 
  44: import java.lang.reflect.Constructor;
  45: import java.rmi.MarshalledObject;
  46: import java.rmi.Remote;
  47: import java.rmi.RemoteException;
  48: import java.rmi.server.UnicastRemoteObject;
  49: 
  50: /**
  51:  * The entity that receives the request to activate object and activates it.
  52:  * Frequently there is one activation group per virtual machine.
  53:  *
  54:  * @author Audrius Meskauskas (audriusa@Bioinformatics.org) (from stub)
  55:  */
  56: public abstract class ActivationGroup
  57:     extends UnicastRemoteObject
  58:     implements ActivationInstantiator
  59: {
  60: 
  61:   /**
  62:    * Use the SVUID for interoperability.
  63:    */
  64:   static final long serialVersionUID = - 7696947875314805420L;
  65: 
  66:   /**
  67:    * The Id of the current group on this VM (null if none).
  68:    */
  69:   static ActivationGroupID currentGroupId = null;
  70: 
  71:   /**
  72:    * The groups identifier.
  73:    */
  74:   final ActivationGroupID groupId;
  75: 
  76:   /**
  77:    * The groups activation monitor.
  78:    */
  79:   ActivationMonitor monitor;
  80: 
  81:   /**
  82:    * The groups incarnation number.
  83:    */
  84:   long incarnation;
  85: 
  86:   /**
  87:    * The groups activation system.
  88:    */
  89:   static ActivationSystem system;
  90: 
  91:   /**
  92:    * Used during the group creation (required constructor).
  93:    */
  94:   static final Class[] cConstructorTypes = new Class[]
  95:                                                    {
  96:                                                     ActivationGroupID.class,
  97:                                                     MarshalledObject.class
  98:                                                    };
  99: 
 100:   /**
 101:    * Create the new activation group with the given group id.
 102:    *
 103:    * @param aGroupId the group Id.
 104:    *
 105:    * @throws RemoteException if the group export fails.
 106:    */
 107:   protected ActivationGroup(ActivationGroupID aGroupId) throws RemoteException
 108:   {
 109:     groupId = aGroupId;
 110:   }
 111: 
 112:   /**
 113:    * The method is called when the object is exported. The group must notify
 114:    * the activation monitor, if this was not already done before.
 115:    *
 116:    * @param id the object activation id
 117:    * @param obj the remote object implementation
 118:    *
 119:    * @throws ActivationException if the group is inactive
 120:    * @throws UnknownObjectException if such object is not known
 121:    * @throws RemoteException if the call to monitor fails
 122:    */
 123:   public abstract void activeObject(ActivationID id, Remote obj)
 124:       throws ActivationException, UnknownObjectException, RemoteException;
 125: 
 126:   /**
 127:    * Notifies the monitor about the object being inactivated.
 128:    *
 129:    * @param id the object being inactivated.
 130:    * @return true always (must be overridden to return other values).
 131:    * @throws ActivationException never
 132:    * @throws UnknownObjectException if the object is not known
 133:    * @throws RemoteException if the remote call to monitor fails
 134:    */
 135:   public boolean inactiveObject(ActivationID id) throws ActivationException,
 136:       UnknownObjectException, RemoteException
 137:   {
 138:     if (monitor != null)
 139:       monitor.inactiveObject(id);
 140:     return true;
 141:   }
 142: 
 143:   /**
 144:    * Create the new instance of the activation group, using the class name and
 145:    * location information, stored in the passed descriptor. The method expects
 146:    * the group class to have the two parameter constructor, the first parameter
 147:    * being the {@link ActivationGroupID} and the second the
 148:    * {@link MarshalledObject}. The group must be first be registered with the
 149:    * ActivationSystem. Once a group is created, the currentGroupID method
 150:    * returns the identifier for this group until the group becomes inactive.
 151:    *
 152:    * @param id the activation group id
 153:    * @param desc the group descriptor, providing the information, necessary to
 154:    *          create the group
 155:    * @param incarnation the incarnation number
 156:    * @return the created group instance
 157:    * @throws ActivationException if the activation fails due any reason
 158:    */
 159:   public static ActivationGroup createGroup(ActivationGroupID id,
 160:                                             ActivationGroupDesc desc,
 161:                                             long incarnation)
 162:       throws ActivationException
 163:   {
 164:     // If the activation system is not yet set, set it to the system.
 165:     // passed in the group id.
 166:     if (system == null)
 167:       system = id.system;
 168: 
 169:     ActivationGroup group = null;
 170: 
 171:     // TODO at the moment all groups are created on the current jre and the
 172:     // group class must be reachable via thread context class loader.
 173:     Class groupClass;
 174: 
 175:     if (desc.className != null)
 176:       {
 177:         try
 178:           {
 179:             ClassLoader loader = Thread.currentThread().getContextClassLoader();
 180:             groupClass = loader.loadClass(desc.className);
 181:           }
 182:         catch (ClassNotFoundException e)
 183:           {
 184:             ActivationException acex = new ActivationException(
 185:               "Cannot load " + desc.className);
 186:             acex.detail = e;
 187:             throw acex;
 188:           }
 189:       }
 190:     else
 191:       groupClass = DefaultActivationGroup.class;
 192: 
 193:     try
 194:       {
 195:         Constructor constructor = groupClass.getConstructor(cConstructorTypes);
 196:         group = (ActivationGroup) constructor.newInstance(
 197:           new Object[] { id, desc.data });
 198:       }
 199:     catch (Exception e)
 200:       {
 201:         ActivationException acex = new ActivationException(
 202:           "Cannot instantiate " + desc.className);
 203:         acex.detail = e;
 204:         throw acex;
 205:       }
 206: 
 207:     currentGroupId = id;
 208:     try
 209:       {
 210:         group.monitor = getSystem().activeGroup(id, group, incarnation);
 211:         return group;
 212:       }
 213:     catch (RemoteException e)
 214:       {
 215:         ActivationException acex = new ActivationException("createGroup");
 216:         acex.detail = e;
 217:         throw acex;
 218:       }
 219:   }
 220: 
 221:   /**
 222:    * Get the id of current activation group.
 223:    *
 224:    * @return the id of the current activation group or null if none exists.
 225:    */
 226:   public static ActivationGroupID currentGroupID()
 227:   {
 228:     try
 229:       {
 230:         if (currentGroupId==null)
 231:           {
 232:             // This will also assing the currentGroupId to the current
 233:             // (default) group of the default system.
 234:             setSystem(DefaultActivationSystem.get());
 235:           }
 236:       }
 237:     catch (ActivationException e)
 238:       {
 239:         InternalError ierr = new InternalError("Unable to activate AS");
 240:         ierr.initCause(e);
 241:         throw ierr;
 242:       }
 243: 
 244:     return currentGroupId;
 245:   }
 246: 
 247:   /**
 248:    * Set the activation system for this virtual machine. The system can only
 249:    * be set if no group is active.
 250:    *
 251:    * @param aSystem the system to set
 252:    *
 253:    * @throws ActivationException if some group is active now.
 254:    */
 255:   public static void setSystem(ActivationSystem aSystem)
 256:       throws ActivationException
 257:   {
 258:     if (currentGroupId!=null)
 259:       throw new ActivationException("Group active");
 260:     else
 261:       {
 262:         try
 263:           {
 264:             // Register the default transient activation system and group.
 265:             system = aSystem;
 266:             ActivationGroupDesc def = new ActivationGroupDesc(
 267:                DefaultActivationGroup.class.getName(),
 268:               "",
 269:               null,
 270:               null,
 271:               null);
 272:             currentGroupId = system.registerGroup(def);
 273:           }
 274:         catch (Exception ex)
 275:         {
 276:           InternalError ierr = new InternalError("Unable to start default AG");
 277:           ierr.initCause(ex);
 278:           throw ierr;
 279:         }
 280:       }
 281:   }
 282: 
 283:   /**
 284:    * Get the current activation system. If the system is not set via
 285:    * {@link #setSystem} method, the default system for this virtual machine is
 286:    * returned. The default system is first searched by name
 287:    * "java.rmi.activation.ActivationSystem" on the activation registry port. The
 288:    * default value of the activation registry port is
 289:    * {@link ActivationSystem#SYSTEM_PORT}, but it can be changed by putting the
 290:    * system property java.rmi.activation.port. Both activation system and
 291:    * activation registry are provided by the RMI daemon tool, RMID, if it is
 292:    * running on the local host. If the RMID is not running, the internal
 293:    * transient activation system will be created and returned. This internal
 294:    * system is highly limited in in capabilities and is not intended to be used
 295:    * anywhere apart automated testing.
 296:    *
 297:    * @return the activation system for this virtual machine
 298:    * @throws ActivationException
 299:    */
 300:   public static ActivationSystem getSystem() throws ActivationException
 301:   {
 302:     if (system == null)
 303:       system = DefaultActivationSystem.get();
 304:     return system;
 305:   }
 306: 
 307:   /**
 308:    * Makes the call back to the groups {@link ActivationMonitor}.
 309:    *
 310:    * @param id the id obj the object being activated
 311:    * @param mObject the marshalled object, contains the activated remote object
 312:    *          stub.
 313:    * @throws ActivationException on activation error
 314:    * @throws UnknownObjectException if such object is not registered
 315:    * @throws RemoteException on remote call (to monitor) error
 316:    */
 317:   protected void activeObject(ActivationID id,
 318:                               MarshalledObject<? extends Remote> mObject)
 319:       throws ActivationException, UnknownObjectException, RemoteException
 320:   {
 321:     if (monitor!=null)
 322:       monitor.activeObject(id, mObject);
 323: 
 324:     id.group = this;
 325:   }
 326: 
 327:   /**
 328:    * Makes the call back to the groups {@link ActivationMonitor} and sets
 329:    * the current group to null.
 330:    */
 331:   protected void inactiveGroup() throws UnknownGroupException, RemoteException
 332:   {
 333:     if (monitor!=null)
 334:       monitor.inactiveGroup(groupId, incarnation);
 335: 
 336:     if (currentGroupId!=null && currentGroupId.equals(groupId))
 337:       currentGroupId = null;
 338:   }
 339: 
 340: }