Source for gnu.CORBA.IorDelegate

   1: /* gnuDelegate.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;
  40: 
  41: import gnu.CORBA.CDR.BufferredCdrInput;
  42: import gnu.CORBA.GIOP.ReplyHeader;
  43: 
  44: import org.omg.CORBA.CompletionStatus;
  45: import org.omg.CORBA.Context;
  46: import org.omg.CORBA.ContextList;
  47: import org.omg.CORBA.ExceptionList;
  48: import org.omg.CORBA.MARSHAL;
  49: import org.omg.CORBA.NVList;
  50: import org.omg.CORBA.NamedValue;
  51: import org.omg.CORBA.ORB;
  52: import org.omg.CORBA.Request;
  53: import org.omg.CORBA.portable.ApplicationException;
  54: import org.omg.CORBA.portable.InputStream;
  55: import org.omg.CORBA.portable.OutputStream;
  56: import org.omg.CORBA.portable.RemarshalException;
  57: import org.omg.PortableInterceptor.ForwardRequest;
  58: 
  59: import java.io.IOException;
  60: 
  61: import java.net.Socket;
  62: 
  63: /**
  64:  * The Classpath implementation of the {@link Delegate} functionality in the
  65:  * case, when the object was constructed from an IOR object. The IOR can be
  66:  * constructed from the stringified object reference.
  67:  *
  68:  * There is an different instance of this delegate for each CORBA object.
  69:  *
  70:  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
  71:  */
  72: public class IorDelegate extends SimpleDelegate
  73: {
  74:   /**
  75:    * Contructs an instance of object using the given IOR.
  76:    */
  77:   public IorDelegate(ORB an_orb, IOR an_ior)
  78:   {
  79:     super(an_orb, an_ior);
  80:   }
  81: 
  82:   /**
  83:    * Creates the request to invoke the method on this object.
  84:    *
  85:    * @param target the object, for that the operation must be invoked.
  86:    * @param context context (null allowed)
  87:    * @param operation the method name
  88:    * @param parameters the method parameters
  89:    * @param returns the return value holder
  90:    * @param exceptions the exceptions that can be thrown by the method
  91:    * @param ctx_list the context list (null allowed)
  92:    *
  93:    * @return the created request.
  94:    */
  95:   public Request create_request(org.omg.CORBA.Object target, Context context,
  96:     String operation, NVList parameters, NamedValue returns
  97:   )
  98:   {
  99:     gnuRequest request = getRequestInstance(target);
 100: 
 101:     request.setIor(getIor());
 102:     request.set_target(target);
 103: 
 104:     request.setOperation(operation);
 105:     request.set_args(parameters);
 106:     request.m_context = context;
 107:     request.set_result(returns);
 108:     request.setORB(orb);
 109: 
 110:     return request;
 111:   }
 112: 
 113:   /**
 114:    * Creates the request to invoke the method on this object.
 115:    *
 116:    * @param target the object, for that the operation must be invoked.
 117:    * @param context context (null allowed)
 118:    * @param operation the method name
 119:    * @param parameters the method parameters
 120:    * @param returns the return value holder
 121:    *
 122:    * @return the created request.
 123:    */
 124:   public Request create_request(org.omg.CORBA.Object target, Context context,
 125:     String operation, NVList parameters, NamedValue returns,
 126:     ExceptionList exceptions, ContextList ctx_list
 127:   )
 128:   {
 129:     gnuRequest request = getRequestInstance(target);
 130: 
 131:     request.setIor(ior);
 132:     request.set_target(target);
 133: 
 134:     request.setOperation(operation);
 135:     request.set_args(parameters);
 136:     request.m_context = context;
 137:     request.set_result(returns);
 138:     request.set_exceptions(exceptions);
 139:     request.set_context_list(ctx_list);
 140:     request.setORB(orb);
 141: 
 142:     return request;
 143:   }
 144: 
 145:   /**
 146:    * Get the instance of request.
 147:    */
 148:   protected gnuRequest getRequestInstance(org.omg.CORBA.Object target)
 149:   {
 150:     return new gnuRequest();
 151:   }
 152: 
 153:   /**
 154:    * Invoke operation on the given object, als handling temproray and permanent
 155:    * redirections. The ReplyHeader.LOCATION_FORWARD will cause to resend the
 156:    * request to the new direction. The ReplyHeader.LOCATION_FORWARD_PERM will
 157:    * cause additionally to remember the new location by this delegate, so
 158:    * subsequent calls will be immediately delivered to the new target.
 159:    * 
 160:    * @param target the target object.
 161:    * @param output the output stream, previously returned by
 162:    * {@link #request(org.omg.CORBA.Object, String, boolean)}.
 163:    * 
 164:    * @return the input stream, to read the response from or null for a one-way
 165:    * request.
 166:    * 
 167:    * @throws SystemException if the SystemException has been thrown on the
 168:    * remote side (the exact type and the minor code matches the data of the
 169:    * remote exception that has been thrown).
 170:    * 
 171:    * @throws org.omg.CORBA.portable.ApplicationException as specified.
 172:    * @throws org.omg.CORBA.portable.RemarshalException as specified.
 173:    */
 174:   public InputStream invoke(org.omg.CORBA.Object target, OutputStream output)
 175:     throws ApplicationException, RemarshalException
 176:   {
 177:     StreamBasedRequest request = (StreamBasedRequest) output;
 178:     Forwardings: while (true)
 179:       {
 180:         try
 181:           {
 182:             if (request.response_expected)
 183:               {
 184:                 RawReply response = request.request.submit();
 185: 
 186:                 // Read reply header.
 187:                 ReplyHeader rh = response.header.create_reply_header();
 188:                 BufferredCdrInput input = response.getStream();
 189:                 input.setOrb(orb);
 190:                 rh.read(input);
 191:                 request.request.m_rph = rh;
 192: 
 193:                 boolean moved_permanently = false;
 194: 
 195:                 switch (rh.reply_status)
 196:                   {
 197:                     case ReplyHeader.NO_EXCEPTION:
 198:                       if (request.request.m_interceptor != null)
 199:                         request.request.m_interceptor.receive_reply(request.request.m_info);
 200:                       if (response.header.version.since_inclusive(1, 2))
 201:                         input.align(8);
 202:                       return input;
 203: 
 204:                     case ReplyHeader.SYSTEM_EXCEPTION:
 205:                       if (response.header.version.since_inclusive(1, 2))
 206:                         input.align(8);
 207:                       showException(request, input);
 208: 
 209:                       throw ObjectCreator.readSystemException(input,
 210:                         rh.service_context);
 211: 
 212:                     case ReplyHeader.USER_EXCEPTION:
 213:                       if (response.header.version.since_inclusive(1, 2))
 214:                         input.align(8);
 215:                       showException(request, input);
 216: 
 217:                       throw new ApplicationException(
 218:                         request.request.m_exception_id, input);
 219: 
 220:                     case ReplyHeader.LOCATION_FORWARD_PERM:
 221:                       moved_permanently = true;
 222: 
 223:                     case ReplyHeader.LOCATION_FORWARD:
 224:                       if (response.header.version.since_inclusive(1, 2))
 225:                         input.align(8);
 226: 
 227:                       IOR forwarded = new IOR();
 228:                       try
 229:                         {
 230:                           forwarded._read_no_endian(input);
 231:                         }
 232:                       catch (IOException ex)
 233:                         {
 234:                           MARSHAL t = new MARSHAL("Cant read forwarding info",
 235:                             5102, CompletionStatus.COMPLETED_NO);
 236:                           t.initCause(ex);
 237:                           throw t;
 238:                         }
 239: 
 240:                       gnuRequest prev = request.request;
 241:                       gnuRequest r = getRequestInstance(target);
 242: 
 243:                       r.m_interceptor = prev.m_interceptor;
 244:                       r.m_slots = prev.m_slots;
 245: 
 246:                       r.m_args = prev.m_args;
 247:                       r.m_context = prev.m_context;
 248:                       r.m_context_list = prev.m_context_list;
 249:                       r.m_environment = prev.m_environment;
 250:                       r.m_exceptions = prev.m_exceptions;
 251:                       r.m_operation = prev.m_operation;
 252:                       r.m_parameter_buffer = prev.m_parameter_buffer;
 253:                       r.m_parameter_buffer.request = r;
 254:                       r.m_result = prev.m_result;
 255:                       r.m_target = prev.m_target;
 256:                       r.oneWay = prev.oneWay;
 257:                       r.m_forward_ior = forwarded;
 258: 
 259:                       if (r.m_interceptor != null)
 260:                         r.m_interceptor.receive_other(r.m_info);
 261: 
 262:                       r.setIor(forwarded);
 263: 
 264:                       IorObject it = new IorObject(orb,
 265:                         forwarded);
 266: 
 267:                       r.m_target = it;
 268: 
 269:                       request.request = r;
 270: 
 271:                       IOR prev_ior = getIor();
 272: 
 273:                       setIor(forwarded);
 274: 
 275:                       try
 276:                         {
 277:                           return invoke(it, request);
 278:                         }
 279:                       finally
 280:                         {
 281:                           if (!moved_permanently)
 282:                             setIor(prev_ior);
 283:                         }
 284: 
 285:                     default:
 286:                       throw new MARSHAL("Unknow reply status: "
 287:                         + rh.reply_status, 8000 + rh.reply_status,
 288:                         CompletionStatus.COMPLETED_NO);
 289:                   }
 290:               }
 291:             else
 292:               {
 293:                 request.request.send_oneway();
 294:                 return null;
 295:               }
 296:           }
 297:         catch (ForwardRequest forwarded)
 298:           {
 299:             ForwardRequest fw = forwarded;
 300:             Forwarding2: while (true)
 301:               {
 302:                 try
 303:                   {
 304:                     gnuRequest prev = request.request;
 305:                     gnuRequest r = getRequestInstance(target);
 306: 
 307:                     r.m_interceptor = prev.m_interceptor;
 308:                     r.m_args = prev.m_args;
 309:                     r.m_context = prev.m_context;
 310:                     r.m_context_list = prev.m_context_list;
 311:                     r.m_environment = prev.m_environment;
 312:                     r.m_exceptions = prev.m_exceptions;
 313:                     r.m_operation = prev.m_operation;
 314:                     r.m_parameter_buffer = prev.m_parameter_buffer;
 315:                     r.m_parameter_buffer.request = r;
 316:                     r.m_result = prev.m_result;
 317:                     r.m_target = prev.m_target;
 318:                     r.oneWay = prev.oneWay;
 319: 
 320:                     r.m_forwarding_target = fw.forward;
 321: 
 322:                     if (r.m_interceptor != null)
 323:                       r.m_interceptor.receive_other(r.m_info);
 324: 
 325:                     r.m_target = fw.forward;
 326:                     request.request = r;
 327:                     break Forwarding2;
 328:                   }
 329:                 catch (ForwardRequest e)
 330:                   {
 331:                     forwarded = e;
 332:                   }
 333:               }
 334:           }
 335:       }
 336:   }
 337: 
 338:   /**
 339:    * Show exception to interceptor.
 340:    */
 341:   void showException(StreamBasedRequest request, BufferredCdrInput input)
 342:     throws ForwardRequest
 343:   {
 344:     input.mark(2048);
 345:     request.request.m_exception_id = input.read_string();
 346:     input.reset();
 347: 
 348:     if (request.request.m_interceptor != null)
 349:       request.request.m_interceptor.receive_exception(request.request.m_info);
 350:   }
 351: 
 352:   /**
 353:    * Create a request to invoke the method of this CORBA object.
 354:    *
 355:    * @param target the CORBA object, to that this operation must be applied.
 356:    * @param operation the name of the method to invoke.
 357:    *
 358:    * @return the request.
 359:    */
 360:   public Request request(org.omg.CORBA.Object target, String operation)
 361:   {
 362:     gnuRequest request = getRequestInstance(target);
 363: 
 364:     request.setIor(ior);
 365:     request.set_target(target);
 366: 
 367:     request.setOperation(operation);
 368:     request.setORB(orb);
 369: 
 370:     return request;
 371:   }
 372: 
 373:   /**
 374:    * Create a request to invoke the method of this CORBA object.
 375:    *
 376:    * @param target the CORBA object, to that this operation must be applied.
 377:    * @param operation the name of the method to invoke.
 378:    * @param response_expected specifies if this is one way message or the
 379:    * response to the message is expected.
 380:    *
 381:    * @return the stream where the method arguments should be written.
 382:    */
 383:   public OutputStream request(org.omg.CORBA.Object target, String operation,
 384:     boolean response_expected
 385:   )
 386:   {
 387:     gnuRequest request = getRequestInstance(target);
 388: 
 389:     request.setIor(ior);
 390:     request.set_target(target);
 391:     request.setOperation(operation);
 392: 
 393:     StreamBasedRequest out = request.getParameterStream();
 394:     out.response_expected = response_expected;
 395:     request.setORB(orb);
 396:     out.setOrb(orb);
 397: 
 398:     return out;
 399:   }
 400: 
 401:   /**
 402:    * If there is an opened cache socket to access this object, close that
 403:    * socket.
 404:    *
 405:    * @param target The target is not used, this delegate requires a single
 406:    * instance per object.
 407:    */
 408:   public void release(org.omg.CORBA.Object target)
 409:   {
 410:     // Do nothing here.
 411:   }
 412: 
 413:   /**
 414:    * Reset the remote_ior flag, forcing to check if the object is local on the
 415:    * next getRequestInstance call.
 416:    */
 417:   public void setIor(IOR an_ior)
 418:   {
 419:     super.setIor(an_ior);
 420:   }
 421: 
 422:   /**
 423:    * Checks if the ior is local so far it is easy.
 424:    */
 425:   public boolean is_local(org.omg.CORBA.Object self)
 426:   {
 427:     return false;
 428:   }