Source for gnu.CORBA.Poa.LocalDelegate

   1: /* LocalDelegate.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.CDR.AbstractCdrOutput;
  42: import gnu.CORBA.IOR;
  43: import gnu.CORBA.IorProvider;
  44: import gnu.CORBA.StreamBasedRequest;
  45: 
  46: import org.omg.CORBA.ARG_INOUT;
  47: import org.omg.CORBA.Bounds;
  48: import org.omg.CORBA.Context;
  49: import org.omg.CORBA.ContextList;
  50: import org.omg.CORBA.ExceptionList;
  51: import org.omg.CORBA.NO_IMPLEMENT;
  52: import org.omg.CORBA.NVList;
  53: import org.omg.CORBA.NamedValue;
  54: import org.omg.CORBA.OBJECT_NOT_EXIST;
  55: import org.omg.CORBA.ORB;
  56: import org.omg.CORBA.Request;
  57: import org.omg.CORBA.TypeCodePackage.BadKind;
  58: import org.omg.CORBA.UnknownUserException;
  59: import org.omg.CORBA.portable.ApplicationException;
  60: import org.omg.CORBA.portable.InputStream;
  61: import org.omg.CORBA.portable.InvokeHandler;
  62: import org.omg.CORBA.portable.ObjectImpl;
  63: import org.omg.CORBA.portable.OutputStream;
  64: import org.omg.CORBA.portable.RemarshalException;
  65: import org.omg.PortableServer.ServantLocatorPackage.CookieHolder;
  66: 
  67: import java.util.Arrays;
  68: 
  69: /**
  70:  * A local delegate, transferring all object requests to the locally available
  71:  * servant. This class is involved in handling the method invocations on the
  72:  * local object, obtained by POA.create_reference_with_id.
  73:  *
  74:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  75:  */
  76: public class LocalDelegate
  77:   extends org.omg.CORBA_2_3.portable.Delegate
  78:   implements IorProvider
  79: {
  80:   /**
  81:    * The same servant as an invocation handler.
  82:    */
  83:   gnuServantObject object;
  84: 
  85:   String operation;
  86: 
  87:   public final gnuPOA poa;
  88: 
  89:   final byte[] Id;
  90: 
  91:   /**
  92:    * Create a local delegate, forwarding requests to the servant that must also
  93:    * be an invocation handler.
  94:    */
  95:   public LocalDelegate(gnuServantObject an_object, gnuPOA a_poa, byte[] an_id)
  96:   {
  97:     object = an_object;
  98:     poa = a_poa;
  99:     Id = an_id;
 100:   }
 101: 
 102:   /**
 103:    * Get the IOR of the connected object.
 104:    */
 105:   public IOR getIor()
 106:   {
 107:     return object.getIor();
 108:   }
 109: 
 110:   public Request request(org.omg.CORBA.Object target, String method)
 111:   {
 112:     operation = method;
 113: 
 114:     LocalRequest rq = new LocalRequest(object, poa, Id);
 115:     rq.setOperation(method);
 116:     rq.setORB(orb(target));
 117:     return rq;
 118:   }
 119: 
 120:   public void release(org.omg.CORBA.Object target)
 121:   {
 122:   }
 123: 
 124:   public boolean is_equivalent(org.omg.CORBA.Object target,
 125:     org.omg.CORBA.Object other)
 126:   {
 127:     if (target == other)
 128:       return true;
 129:     else if (target instanceof ObjectImpl && other instanceof ObjectImpl)
 130:       {
 131:         org.omg.CORBA.portable.Delegate a = null;
 132:         org.omg.CORBA.portable.Delegate b = null;
 133:         try
 134:           {
 135:             a = ((ObjectImpl) target)._get_delegate();
 136:             b = ((ObjectImpl) other)._get_delegate();
 137:           }
 138:         catch (Exception ex)
 139:           {
 140:             // Unable to get one of the delegates.
 141:             return false;
 142:           }
 143:         if (a instanceof LocalDelegate && b instanceof LocalDelegate)
 144:           {
 145:             byte[] k1 = ((LocalDelegate) a).Id;
 146:             byte[] k2 = ((LocalDelegate) b).Id;
 147:             return Arrays.equals(k1, k2);
 148:           }
 149:         else
 150:           return false;
 151:       }
 152:     else
 153:       return false;
 154:   }
 155: 
 156:   /**
 157:    * Always return false.
 158:    */
 159:   public boolean non_existent(org.omg.CORBA.Object target)
 160:   {
 161:     return false;
 162:   }
 163: 
 164:   /**
 165:    * Get hash code.
 166:    */
 167:   public int hash(org.omg.CORBA.Object target, int maximum)
 168:   {
 169:     return hashCode() % maximum;
 170:   }
 171: 
 172:   /**
 173:    * Check if this object could be named by the given repository id.
 174:    *
 175:    * @param idl_id the repository id to check.
 176:    *
 177:    * @return true if it is one of the possible repository ids of this object.
 178:    */
 179:   public boolean is_a(org.omg.CORBA.Object a_servant, String idl_id)
 180:   {
 181:     String[] maybe = object._ids();
 182:     for (int i = 0; i < maybe.length; i++)
 183:       {
 184:         if (maybe[i].equals(idl_id))
 185:           return true;
 186:       }
 187:     return false;
 188:   }
 189: 
 190:   /**
 191:    * Return <code>this</code>.
 192:    */
 193:   public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object target)
 194:   {
 195:     return target;
 196:   }
 197: 
 198:   /**
 199:    * Create request for using with DII.
 200:    */
 201:   public Request create_request(org.omg.CORBA.Object target, Context context,
 202:     String method, NVList parameters, NamedValue returns,
 203:     ExceptionList exceptions, ContextList ctx_list)
 204:   {
 205:     operation = method;
 206: 
 207:     LocalRequest rq = new LocalRequest(object, poa, Id);
 208:     rq.setOperation(method);
 209:     rq.set_args(parameters);
 210:     rq.set_result(returns);
 211:     rq.set_exceptions(exceptions);
 212:     rq.set_context_list(ctx_list);
 213:     return rq;
 214:   }
 215: 
 216:   /**
 217:    * Create request for using with DII.
 218:    */
 219:   public Request create_request(org.omg.CORBA.Object target, Context context,
 220:     String method, NVList parameters, NamedValue returns)
 221:   {
 222:     operation = method;
 223: 
 224:     LocalRequest rq = new LocalRequest(object, poa, Id);
 225:     rq.setOperation(method);
 226:     rq.set_args(parameters);
 227:     rq.set_result(returns);
 228:     return rq;
 229:   }
 230: 
 231:   /**
 232:    * Not in use.
 233:    */
 234:   public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object target)
 235:   {
 236:     throw new NO_IMPLEMENT();
 237:   }
 238: 
 239:   /**
 240:    * Create a request to invoke the method of this CORBA object.
 241:    *
 242:    * @param operation the name of the method to invoke.
 243:    * @param response_expected specifies if this is one way message or the
 244:    * response to the message is expected.
 245:    *
 246:    * @return the stream where the method arguments should be written.
 247:    */
 248:   public org.omg.CORBA.portable.OutputStream request(
 249:     org.omg.CORBA.Object target, String method, boolean response_expected)
 250:   {
 251:     operation = method;
 252: 
 253:     // Check if the object is not explicitly deactivated.
 254:     AOM.Obj e = poa.aom.get(Id);
 255:     if (e != null && e.isDeactiveted())
 256:       {
 257:         if (poa.servant_activator != null || poa.servant_locator != null)
 258:           {
 259:             // This will force the subsequent activation.
 260:             object.setServant(null);
 261:             e.setServant(null);
 262:             e.setDeactivated(false);
 263:           }
 264:         else
 265:           throw new OBJECT_NOT_EXIST("Deactivated");
 266:       }
 267: 
 268:     LocalRequest rq = new LocalRequest(object, poa, Id);
 269:     rq.setOperation(method);
 270:     rq.setORB(orb(target));
 271:     return rq.getParameterStream();
 272:   }
 273: 
 274:   /**
 275:    * Return the associated invocation handler.
 276:    */
 277:   public InvokeHandler getHandler(String method, CookieHolder cookie)
 278:   {
 279:     return object.getHandler(method, cookie, false);
 280:   }
 281: 
 282:   /**
 283:    * Return the ORB of the associated POA. The parameter is not in use.
 284:    */
 285:   public ORB orb(org.omg.CORBA.Object target)
 286:   {
 287:     return poa.orb();
 288:   }
 289: 
 290:   /**
 291:    * Make an invocation.
 292:    *
 293:    * @param target not in use.
 294:    * @param output the stream request that should be returned by
 295:    * {@link #m_request} in this method.
 296:    * @throws ApplicationException if the use exception is thrown by the servant
 297:    * method.
 298:    */
 299:   public InputStream invoke(org.omg.CORBA.Object target, OutputStream output)
 300:     throws ApplicationException
 301:   {
 302:     try
 303:       {
 304:         StreamBasedRequest sr = (StreamBasedRequest) output;
 305: 
 306:         LocalRequest lr = (LocalRequest) sr.request;
 307:         InvokeHandler handler = lr.object.getHandler(lr.operation(), lr.cookie,
 308:           false);
 309: 
 310:         if (handler instanceof DynamicImpHandler)
 311:           {
 312:             // The local request known how to handle it, but the different
 313:             // method must be called.
 314:             lr.invoke();
 315: 
 316:             // The encapsulation will inherit orb, endian, charsets, etc.
 317:             AbstractCdrOutput buf = sr.createEncapsulation();
 318: 
 319:             // Write all request parameters to the buffer stream.
 320:             if (lr.env().exception() != null)
 321:               {
 322:                 try
 323:                   {
 324:                     UnknownUserException uex = (UnknownUserException) lr.env().exception();
 325:                     throw new ApplicationException(uex.except.type().id(),
 326:                       uex.except.create_input_stream());
 327:                   }
 328:                 catch (BadKind ex)
 329:                   {
 330:                     InternalError ierr = new InternalError();
 331:                     ierr.initCause(ex);
 332:                     throw ierr;
 333:                   }
 334:               }
 335:             if (lr.return_value() != null)
 336:               lr.return_value().write_value(buf);
 337: 
 338:             NamedValue a;
 339:             try
 340:               {
 341:                 for (int i = 0; i < lr.arguments().count(); i++)
 342:                   {
 343:                     a = lr.arguments().item(i);
 344:                     if (a.flags() == ARG_INOUT.value
 345:                       || a.flags() == ARG_INOUT.value)
 346:                       {
 347:                         a.value().write_value(buf);
 348:                       }
 349:                   }
 350:               }
 351:             catch (Bounds ex)
 352:               {
 353:                 InternalError ierr = new InternalError();
 354:                 ierr.initCause(ex);
 355:                 throw ierr;
 356:               }
 357: 
 358:             return buf.create_input_stream();
 359:           }
 360:         else
 361:           {
 362:             LocalRequest lrq = (LocalRequest) sr.request;
 363:             return lrq.s_invoke(handler);
 364:           }
 365:       }
 366:     catch (gnuForwardRequest f)
 367:       {
 368:         try
 369:           {
 370:             return ((ObjectImpl) f.forward_reference)._invoke(f.forward_reference._request(
 371:               operation, true));
 372:           }
 373:         catch (RemarshalException e)
 374:           {
 375:             // Never thrown in this place by Classpath implementation.
 376:             throw new NO_IMPLEMENT();
 377:           }
 378:       }
 379:   }
 380: 
 381:   public void releaseReply(org.omg.CORBA.Object target, InputStream input)
 382:   {
 383:     release(target);
 384:   }
 385: }