Source for gnu.java.rmi.server.ActivatableServerRef

   1: /* ActivatableServerRef.java -- The activatable server reference
   2:    Copyright (C) 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 gnu.java.rmi.server;
  40: 
  41: import java.io.IOException;
  42: import java.io.ObjectInput;
  43: import java.io.ObjectOutput;
  44: import java.rmi.Remote;
  45: import java.rmi.RemoteException;
  46: import java.rmi.activation.ActivationID;
  47: import java.rmi.server.ObjID;
  48: import java.rmi.server.RMIServerSocketFactory;
  49: import java.rmi.server.RemoteStub;
  50: import java.rmi.server.Skeleton;
  51: 
  52: /**
  53:  * The activatable server reference works like UnicastServerReference, but it
  54:  * additionally activates the associated object on demand, during the first
  55:  * incoming call. When UnicastServerReference takes the working reference,
  56:  * the ActivatableServerRef takes the activation id instead.
  57:  *
  58:  * @author Audrius Meskauskas (Audriusa@Bioinformatics.org)
  59:  */
  60: public class ActivatableServerRef extends UnicastServerRef
  61: {
  62:   /**
  63:    * Use SVUID for interoperability
  64:    */
  65:   private static final long serialVersionUID = 1;
  66: 
  67:   /**
  68:    * The object activation id.
  69:    */
  70:   public ActivationID actId;
  71: 
  72:   /**
  73:    * Used by serialization only
  74:    */
  75:   public ActivatableServerRef()
  76:   {
  77:     super();
  78:   }
  79: 
  80:   /**
  81:    * Create the new activatable server reference that will activate object on
  82:    * the first call using the given activation id.
  83:    */
  84:   public ActivatableServerRef(ObjID id, ActivationID anId, int aPort,
  85:                               RMIServerSocketFactory ssFactory)
  86:       throws RemoteException
  87:   {
  88:     super(id, aPort, ssFactory);
  89:     actId = anId;
  90: 
  91:     // The object ID will be placed in the object map and should deliver
  92:     // incoming call to {@link #incommingMessageCall}. The object itself
  93:     // is currently null.
  94:     UnicastServer.exportActivatableObject(this);
  95:   }
  96: 
  97:   /**
  98:    * Inactivate the object (stop the server).
  99:    */
 100:   public void inactivate()
 101:   {
 102:     manager.stopServer();
 103:   }
 104: 
 105:   /**
 106:    * Activate the object (normally during the first call).
 107:    */
 108:   protected void activate() throws RemoteException
 109:   {
 110:     try
 111:       {
 112:         Remote self = actId.activate(false);
 113: 
 114:         // This will call UnicastServer.exportObject, replacing null by
 115:         // the activated object (self) in the object map.
 116:         exportObject(self);
 117:       }
 118:     catch (RemoteException rex)
 119:       {
 120:         throw rex;
 121:       }
 122:     catch (Exception exc)
 123:       {
 124:         RemoteException rx = new RemoteException("Activation failed.");
 125:         rx.detail = exc;
 126:         throw rx;
 127:       }
 128:   }
 129: 
 130:   /**
 131:    * If the object is not active, activate it first.
 132:    */
 133:   public Object incomingMessageCall(UnicastConnection conn, int method,
 134:                                     long hash) throws Exception
 135:   {
 136:     if (myself == null)
 137:       activate();
 138:     return super.incomingMessageCall(conn, method, hash);
 139:   }
 140: 
 141:   /**
 142:    * Export object and ensure it is present in the server activation table
 143:    * as well.
 144:    */
 145:   public Remote exportObject(Remote obj) throws RemoteException
 146:   {
 147:     Remote r = super.exportObject(obj);
 148:     UnicastServer.registerActivatable(this);
 149:     return r;
 150:   }
 151: 
 152:   /**
 153:    * Export object and ensure it is present in the server activation table as
 154:    * well.
 155:    *
 156:    * @param aClass the class being exported, must implement Remote.
 157:    */
 158:   public Remote exportClass(Class aClass) throws RemoteException
 159:   {
 160:     if (!Remote.class.isAssignableFrom(aClass))
 161:       throw new InternalError(aClass.getName()+" must implement Remote");
 162: 
 163:         String ignoreStubs;
 164: 
 165:         ClassLoader loader =aClass.getClassLoader();
 166: 
 167:         // Stubs are always searched for the bootstrap classes that may have
 168:         // obsolete pattern and may still need also skeletons.
 169:         if (loader==null)
 170:           ignoreStubs = "false";
 171:         else
 172:           ignoreStubs = System.getProperty("java.rmi.server.ignoreStubClasses",
 173:                                            "false");
 174: 
 175:         if (! ignoreStubs.equals("true"))
 176:           {
 177:             // Find and install the stub
 178:             Class cls = aClass;
 179: 
 180:             // where ist the _Stub? (check superclasses also)
 181:             Class expCls = findStubSkelClass(cls);
 182: 
 183:             if (expCls != null)
 184:               {
 185:                 stub = (RemoteStub) getHelperClass(expCls, "_Stub");
 186:                 // Find and install the skeleton (if there is one)
 187:                 skel = (Skeleton) getHelperClass(expCls, "_Skel");
 188:               }
 189:           }
 190: 
 191:         if (stub == null)
 192:           stub = createProxyStub(aClass, this);
 193: 
 194:         // Build hash of methods which may be called.
 195:         buildMethodHash(aClass, true);
 196: 
 197:     UnicastServer.registerActivatable(this);
 198:     return stub;
 199:   }
 200: 
 201:   /**
 202:    * Get the referencing class.
 203:    */
 204:   public String getRefClass(ObjectOutput out)
 205:   {
 206:     return "ActivatableRef";
 207:   }
 208: 
 209:   /**
 210:    * Read the content from the input stream.
 211:    */
 212:   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
 213:   {
 214:     super.readExternal(in);
 215:     actId = (ActivationID) in.readObject();
 216:   }
 217: 
 218:   /**
 219:    * Write the content to the output stream.
 220:    */
 221:   public void writeExternal(ObjectOutput out) throws IOException
 222:   {
 223:     super.writeExternal(out);
 224:     out.writeObject(actId);
 225:   }
 226: 
 227: }