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