Source for gnu.CORBA.Poa.ForwardedServant

   1: /* ForwardedServant.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 gnu.CORBA.IOR;
  42: import gnu.CORBA.IorDelegate;
  43: import gnu.CORBA.IorObject;
  44: import gnu.CORBA.Minor;
  45: 
  46: import org.omg.CORBA.BAD_PARAM;
  47: import org.omg.CORBA.CompletionStatus;
  48: import org.omg.CORBA.MARSHAL;
  49: import org.omg.CORBA.ORB;
  50: import org.omg.CORBA.SystemException;
  51: import org.omg.CORBA.portable.ApplicationException;
  52: import org.omg.CORBA.portable.Delegate;
  53: import org.omg.CORBA.portable.InputStream;
  54: import org.omg.CORBA.portable.InvokeHandler;
  55: import org.omg.CORBA.portable.ObjectImpl;
  56: import org.omg.CORBA.portable.OutputStream;
  57: import org.omg.CORBA.portable.RemarshalException;
  58: import org.omg.CORBA.portable.ResponseHandler;
  59: import org.omg.PortableServer.POA;
  60: import org.omg.PortableServer.Servant;
  61: 
  62: import java.io.IOException;
  63: 
  64: /**
  65:  * A "virtual servant", delegating all invocation to the wrapped
  66:  * object (usually remote). Used in cases when it is necessary to
  67:  * handle the request forwarding.
  68:  *
  69:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  70:  */
  71: public class ForwardedServant
  72:   extends Servant
  73:   implements InvokeHandler
  74: {
  75:   /**
  76:    * The reference object, handling requests.
  77:    */
  78:   public final ObjectImpl ref;
  79: 
  80:   /**
  81:    * Create an instance, forwarding requests to the given object.
  82:    */
  83:   ForwardedServant(ObjectImpl a_ref)
  84:   {
  85:     ref = a_ref;
  86:   }
  87: 
  88:   /**
  89:    * Create an instance of the forwarded servant.
  90:    *
  91:    * @param a_ref a reference where request should be forwarded.
  92:    *
  93:    * @return a created forwarded servant or null if the parameter
  94:    * forwards request to itself. Returning null will force to find
  95:    * a right servant in one of many possible ways, depending on
  96:    * policies.
  97:    */
  98:   public static Servant create(org.omg.CORBA.Object a_ref)
  99:   {
 100:     try
 101:       {
 102:         ObjectImpl fto = (ObjectImpl) a_ref;
 103: 
 104:         // Check maybe the remote side forwarded back to our local object.
 105:         if (fto instanceof IorObject)
 106:           {
 107:             IorObject iref = (IorObject) fto;
 108: 
 109:             // Check maybe the IOR is local.
 110:             ORB t_orb = iref._orb();
 111:             if (t_orb instanceof ORB_1_4)
 112:               {
 113:                 ORB_1_4 orb = (ORB_1_4) t_orb;
 114:                 Delegate d = iref._get_delegate();
 115:                 if (d instanceof IorDelegate)
 116:                   {
 117:                     IorDelegate ird = (IorDelegate) iref._get_delegate();
 118:                     IOR ior = ird.getIor();
 119:                     if (orb.LOCAL_HOST.equalsIgnoreCase(ior.Internet.host))
 120:                       {
 121:                         AOM.Obj rx = orb.rootPOA.findIorKey(ior.key);
 122:                         if (rx != null)
 123:                           {
 124:                             if (rx.object == fto ||
 125:                                 rx.object._is_equivalent(fto)
 126:                                )
 127:                               return rx.primary_servant;
 128:                             else
 129:                               fto = (ObjectImpl) rx.object;
 130:                           }
 131:                       }
 132:                   }
 133:               }
 134:           }
 135:         return new ForwardedServant(fto);
 136:       }
 137:     catch (ClassCastException ex)
 138:       {
 139:         throw new BAD_PARAM("ObjectImpl required but " + a_ref + " passed ",
 140:                             0x5005, CompletionStatus.COMPLETED_NO
 141:                            );
 142:       }
 143:   }
 144: 
 145:   /**
 146:    * Forward the call to the wrapped object.
 147:    */
 148:   public OutputStream _invoke(String method, InputStream input,
 149:                               ResponseHandler handler
 150:                              )
 151:                        throws SystemException
 152:   {
 153:     org.omg.CORBA.portable.InputStream in = null;
 154:     org.omg.CORBA.portable.OutputStream out = null;
 155:     try
 156:       {
 157:         try
 158:           {
 159:             out = ref._request(method, true);
 160: 
 161:             // Transfer request information.
 162:             int b;
 163:             while ((b = input.read()) >= 0)
 164:               {
 165:                 out.write(b);
 166:               }
 167:             in = ref._invoke(out);
 168: 
 169:             // Read the returned data.
 170:             out = handler.createReply();
 171:             while ((b = in.read()) >= 0)
 172:               {
 173:                 out.write(b);
 174:               }
 175:           }
 176:         catch (IOException io_ex)
 177:           {
 178:             MARSHAL m = new MARSHAL();
 179:             m.minor = Minor.Forwarding;
 180:             m.initCause(io_ex);
 181:             throw m;
 182:           }
 183:       }
 184:     catch (ApplicationException ex)
 185:       {
 186:         in = ex.getInputStream();
 187: 
 188:         String _id = ex.getId();
 189:         throw new MARSHAL(_id, 5101, CompletionStatus.COMPLETED_NO);
 190:       }
 191:     catch (RemarshalException remarsh)
 192:       {
 193:         _invoke(method, input, handler);
 194:       }
 195:     finally
 196:       {
 197:         ref._releaseReply(in);
 198:       }
 199:     return out;
 200:   }
 201: 
 202:   /**
 203:    * Delegates to the wrapped object.
 204:    */
 205:   public String[] _all_interfaces(POA poa, byte[] key)
 206:   {
 207:     return ref._ids();
 208:   }
 209: }