00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package org.objectweb.david.libs.protocols.giop;
00030
00031 import org.objectweb.jonathan.apis.kernel.Context;
00032 import org.objectweb.jonathan.apis.kernel.ClassPathFinder;
00033 import org.objectweb.jonathan.apis.kernel.Component;
00034 import org.objectweb.jonathan.apis.binding.Identifier;
00035 import org.objectweb.jonathan.apis.kernel.JonathanException;
00036 import org.objectweb.jonathan.apis.kernel.InternalException;
00037 import org.objectweb.jonathan.apis.binding.NamingContext;
00038 import org.objectweb.jonathan.apis.resources.Scheduler;
00039 import org.objectweb.jonathan.apis.resources.Chunk;
00040 import org.objectweb.jonathan.apis.resources.ChunkFactory;
00041 import org.objectweb.jonathan.apis.presentation.*;
00042 import org.objectweb.jonathan.apis.binding.*;
00043 import org.objectweb.jonathan.apis.protocols.*;
00044
00045 import org.objectweb.david.apis.services.handler.ServicesHandler;
00046
00047 import org.objectweb.david.libs.helpers.CORBAHelpers;
00048
00049 import org.omg.IOP.ServiceContext;
00050 import org.omg.GIOP.MsgType_1_0;
00051 import org.omg.GIOP.ReplyStatusType_1_0;
00052 import org.omg.GIOP.LocateStatusType_1_0;
00053 import org.omg.CORBA.SystemException;
00054 import org.omg.CORBA.UNKNOWN;
00055 import org.omg.CORBA.CompletionStatus;
00056 import org.omg.CORBA.portable.UnknownException;
00057
00058 import java.io.IOException;
00059 import java.io.InputStream;
00060 import java.util.Properties;
00061
00065 final public class GIOPProtocol implements Protocol {
00066
00068 static final public String corba_prefix = "IDL:CORBA/";
00069
00070 static final ServiceContext[] no_context = new ServiceContext[0];
00071
00078 public boolean verbose;
00079
00083 private boolean tryTcpIp = true;
00084
00086 static byte[] header = { (byte) 'G', (byte) 'I', (byte) 'O', (byte) 'P', 1, 0 };
00087
00088 ChunkFactory chunk_factory;
00089 MarshallerFactory marshaller_factory;
00090 Scheduler scheduler;
00092 ClassPathFinder finder;
00093
00094
00096 ReplyHolder[] table = new ReplyHolder[17];
00098 ReplyHolder reusable;
00100 int size = 0;
00102 int id = 0;
00103
00104
00106 NamingContext adapter;
00107 ClientSession_Low client_session_low = new ClientSession_Low();;
00108 ServerSession_Low server_session_low = new ServerSession_Low();
00109
00111 ServicesHandler services_handler;
00112
00148 public GIOPProtocol(Context _c,Scheduler scheduler,
00149 MarshallerFactory marshaller_factory,
00150 ChunkFactory chunk_factory,
00151 NamingContext adapter,
00152 ServicesHandler services_handler)
00153 throws JonathanException {
00154
00155 this.scheduler = scheduler;
00156 this.adapter = adapter;
00157 this.services_handler = services_handler;
00158 finder = (ClassPathFinder) _c.getValue("/classpath_finder",'/');
00159 this.marshaller_factory = marshaller_factory;
00160 this.chunk_factory = chunk_factory;
00161 Object prop = _c.getValue("/david/giop/verbose",'/');
00162 if (prop != Context.NO_VALUE) {
00163 verbose = ((Boolean) prop).booleanValue();
00164 } else {
00165 verbose = false;
00166 }
00167
00168 Object prop2 = _c.getValue("/jonathan/HTTP Tunneling/try with tcpip", '/');
00169 if (prop2 != Context.NO_VALUE) {
00170 tryTcpIp = ((Boolean)prop2).booleanValue();
00171 }
00172 }
00173
00178 public boolean isAnInvocationProtocol() {
00179 return true;
00180 }
00181
00189 public ProtocolGraph newProtocolGraph(ProtocolGraph next) {
00190 return new GIOPProtocolGraph(next);
00191 }
00192
00204 public ProtocolGraph newProtocolGraph(ProtocolGraph next_one, ProtocolGraph next_two) {
00205 return new GIOPProtocolGraph(next_one, next_two);
00206 }
00207
00215 public GIOPSessionIdentifier newSessionIdentifier(byte[] object_key,
00216 SessionIdentifier next) {
00217
00218 return new GIOPCltSessionIdentifier(object_key,next);
00219 }
00220
00229 public GIOPSessionIdentifier newSessionIdentifier(byte[] object_key,
00230 SessionIdentifier next_one,
00231 SessionIdentifier next_two) {
00232 return new GIOPCltSessionIdentifier(object_key, next_one, next_two);
00233 }
00234
00235 void sendError(Session_High sender) {
00236 try {
00237 if (verbose) {
00238 System.err.println("GIOP message error: bad magic bytes." +
00239 " " + Thread.currentThread());
00240 }
00241 Marshaller marshaller = marshaller_factory.newMarshaller();
00242 sender.prepare(marshaller);
00243 marshaller.writeByteArray(header,0,6);
00244 marshaller.writeBoolean(marshaller.isLittleEndian());
00245 marshaller.writeByte((byte) MsgType_1_0._MessageError);
00246 marshaller.writeInt(0);
00247 sender.send(marshaller);
00248 } catch (Exception ignored) {}
00249 sender.close();
00250 }
00251
00252 ServiceContext[] decodeServices(UnMarshaller unmarshaller)
00253 throws JonathanException {
00254 ServiceContext[] contexts = no_context;
00255 int seq_length = unmarshaller.readInt();
00256
00257 if (seq_length != 0) {
00258
00259
00260
00261 int len;
00262 contexts = new ServiceContext[seq_length];
00263 int context_id;
00264 byte[] context_data;
00265 for (int i = 0; i < seq_length; i++) {
00266 context_id = unmarshaller.readInt();
00267 len = unmarshaller.readInt();
00268 context_data = new byte[len];
00269 unmarshaller.readByteArray(context_data,0,len);
00270 contexts[i] = new ServiceContext(context_id,context_data);
00271 }
00272 }
00273 return contexts;
00274 }
00275
00276
00277 void encodeRequestServices(Marshaller marshaller,int rq_id,
00278 boolean response_expected, byte[] object_key)
00279 throws JonathanException {
00280 ServiceContext[] contexts = null;
00281 if (services_handler != null) {
00282 contexts =
00283 services_handler.getRequestContexts(rq_id,response_expected,object_key,
00284 marshaller.getContext());
00285 }
00286 encodeServices(contexts,marshaller);
00287 }
00288
00289 void encodeReplyServices(Marshaller marshaller,int rq_id)
00290 throws JonathanException {
00291
00292 ServiceContext[] contexts = null;
00293 if (services_handler != null) {
00294 contexts = services_handler.getReplyContexts(rq_id, marshaller.getContext());
00295 }
00296 encodeServices(contexts,marshaller);
00297 }
00298
00299
00300 void encodeServices(ServiceContext[] contexts, Marshaller marshaller)
00301 throws JonathanException {
00302 if (contexts != null) {
00303 int seq_length = contexts.length;
00304 int len;
00305 byte[] context_data;
00306 marshaller.writeInt(seq_length);
00307 for (int i = 0; i < seq_length; i++) {
00308 marshaller.writeInt(contexts[i].context_id);
00309 context_data = contexts[i].context_data;
00310 len = context_data.length;
00311 marshaller.writeInt(len);
00312 marshaller.writeByteArray(context_data,0,len);
00313 }
00314 } else {
00315 marshaller.writeInt(0);
00316 }
00317 }
00318
00319
00320 synchronized ReplyHolder registerHolder(Session_High lower) {
00321 ReplyHolder holder;
00322 if (reusable == null) {
00323 holder = new ReplyHolder(lower);
00324 id++;
00325 holder.id = id;
00326 } else {
00327 holder = reusable;
00328 holder.lower = lower;
00329 reusable = reusable.next;
00330 }
00331 int len = table.length;
00332 int index = (holder.id & 0x7FFFFFFF) % len;
00333 holder.next = table[index];
00334 table[index] = holder;
00335 size++;
00336 if (size > len / 2) {
00337 rehash(len);
00338 }
00339 return holder;
00340 }
00341
00346 synchronized void removeHolder(int id) {
00347 int index = (id & 0x7FFFFFFF) % table.length;
00348 ReplyHolder first = table[index];
00349 ReplyHolder holder = first;
00350 ReplyHolder prev = null;
00351 while (holder.id != id) {
00352 prev = holder;
00353 holder = holder.next;
00354 }
00355 if (holder != null) {
00356 size--;
00357 if (prev != null) {
00358 prev.next = holder.next;
00359 } else {
00360 table[index] = holder.next;
00361 }
00362 holder.next = reusable;
00363 holder.lower = null;
00364 reusable = holder;
00365 }
00366 }
00367
00373 synchronized ReplyHolder getHolder(int id) {
00374 int index = (id & 0x7FFFFFFF) % table.length;
00375 ReplyHolder holder = table[index];
00376 while (! (holder == null || holder.id == id)) {
00377 holder = holder.next;
00378 }
00379 return holder;
00380 }
00381
00382 void rehash(int len) {
00383 int new_len = 2 * len + 1;
00384 int index;
00385 ReplyHolder holder, next_holder;
00386 ReplyHolder[] new_table = new ReplyHolder[new_len];
00387 for (int i = 0; i < len; i++) {
00388 holder = table[i];
00389 while (holder != null) {
00390 next_holder = holder.next;
00391
00392 index = (holder.id & 0x7FFFFFFF) % new_len;
00393 holder.next = new_table[index];
00394 new_table[index] = holder;
00395
00396 holder = next_holder;
00397 }
00398 }
00399 table = new_table;
00400 }
00401
00402 synchronized void forwardException(JonathanException e, Session_High lower) {
00403 int len = table.length;
00404 ReplyHolder holder;
00405 for (int i = 0; i < len; i++) {
00406 holder = table[i];
00407 while (holder != null) {
00408 if (holder.lower == lower) {
00409 holder.sendReply(e);
00410 }
00411 holder = holder.next;
00412 }
00413 }
00414 }
00415
00416 class GIOPProtocolGraph implements ProtocolGraph {
00417 ProtocolGraph next;
00418 ProtocolGraph next_two;
00419
00420 public GIOPProtocolGraph(ProtocolGraph next) {
00421 this.next = next;
00422 this.next_two = null;
00423 }
00424
00425 public GIOPProtocolGraph(ProtocolGraph next_one, ProtocolGraph next_two) {
00426 this.next = next_one;
00427 this.next_two = next_two;
00428 }
00429
00430 public boolean equals(Object o) {
00431 if (o instanceof GIOPProtocolGraph) {
00432 GIOPProtocolGraph p_graph = (GIOPProtocolGraph) o;
00433 boolean one = false, two = false;
00434 if (next != null) {
00435 one = next.equals(p_graph.next);
00436 } else {
00437 one = p_graph.next == null;
00438 }
00439
00440 if (next_two != null) {
00441 two = next_two.equals(p_graph.next_two);
00442 } else {
00443 two = p_graph.next_two == null;
00444 }
00445
00446 return one && two;
00447 }
00448 return false;
00449 }
00450
00451
00452 public int hashCode() {
00453 if (next != null) {
00454 return next.hashCode();
00455 } else {
00456 return 0;
00457 }
00458 }
00459
00460 public SessionIdentifier export(Session_Low ignored)
00461 throws JonathanException {
00462 if (next == null) {
00463 throw new ExportException("Badly specified participants");
00464 }
00465 return next_two != null ? new GIOPSrvSessionIdentifier(next.export(server_session_low), next_two.export(server_session_low)) : new GIOPSrvSessionIdentifier(next.export(server_session_low));
00466 }
00467 }
00468
00469 class GIOPSrvSessionIdentifier implements GIOPSessionIdentifier {
00470 SessionIdentifier next;
00471 SessionIdentifier next_two;
00472
00473 public GIOPSrvSessionIdentifier(SessionIdentifier next) {
00474 this.next = next;
00475 this.next_two = null;
00476 }
00477
00478 public GIOPSrvSessionIdentifier(SessionIdentifier next_one, SessionIdentifier next_two) {
00479 this.next = next_one;
00480 this.next_two = next_two;
00481 }
00482
00483 public Session_High bind(Session_Low ignored)
00484 throws JonathanException {
00485 throw new BindException("Bad session identifier type");
00486 }
00487
00488 public void unexport() {
00489 next.unexport();
00490 if (next_two != null) next_two.unexport();
00491 }
00492
00493 public Protocol getProtocol() {
00494 return GIOPProtocol.this;
00495 }
00496
00497 public SessionIdentifier next() {
00498 return next;
00499 }
00500
00501 public SessionIdentifier next_two() {
00502 return next_two;
00503 }
00504
00505 public boolean equals(Object o) {
00506 if (o instanceof GIOPSrvSessionIdentifier) {
00507 GIOPSrvSessionIdentifier session_id = (GIOPSrvSessionIdentifier) o;
00508
00509 boolean one = false, two = false;
00510 if (next != null) {
00511 one = next.equals(session_id.next);
00512 } else {
00513 one = session_id.next == null;
00514 }
00515
00516 if (next_two != null) {
00517 two = next_two.equals(session_id.next_two);
00518 } else {
00519 two = session_id.next_two == null;
00520 }
00521 return one && two;
00522
00523 }
00524 return false;
00525 }
00526
00527 public int hashCode() {
00528 if (next != null) {
00529 return next.hashCode();
00530 } else {
00531 return 0;
00532 }
00533 }
00534 }
00535
00536 class GIOPCltSessionIdentifier extends GIOPSrvSessionIdentifier {
00537 byte[] object_key;
00538
00539 public GIOPCltSessionIdentifier(byte[] object_key,SessionIdentifier next) {
00540
00541 super(next);
00542 this.object_key = object_key;
00543 }
00544 public GIOPCltSessionIdentifier(byte[] object_key, SessionIdentifier next_one, SessionIdentifier next_two) {
00545
00546 super(next_one, next_two);
00547 this.object_key = object_key;
00548 }
00549
00550 public Session_High bind(Session_Low ignored)
00551 throws JonathanException {
00552 if (next == null && next_two == null) {
00553 throw new BindException("Badly specified participants");
00554 }
00555 try {
00556
00557
00558 if (tryTcpIp) {
00559 return new ClientSession_High(object_key,next.bind(client_session_low));
00560 } else {
00561 throw new JonathanException("escape!");
00562 }
00563 } catch (JonathanException e) {
00564 if (next_two != null) {
00565
00566 return new ClientSession_High(object_key,next_two.bind(client_session_low));
00567 } else {
00568
00569 throw e;
00570 }
00571 }
00572 }
00573
00574 public void unexport() {}
00575
00576 public boolean equals(Object o) {
00577 if (o instanceof GIOPCltSessionIdentifier) {
00578 GIOPCltSessionIdentifier session_id = (GIOPCltSessionIdentifier) o;
00579 int len = object_key.length;
00580 byte[] other_key = session_id.object_key;
00581 if (other_key.length == len) {
00582 for (int i = 0; i < len; i++) {
00583 if (other_key[i] != object_key[i]) {
00584 return false;
00585 }
00586 }
00587 return super.equals(session_id);
00588 }
00589 }
00590 return false;
00591 }
00592
00593 public int hashCode() {
00594 int hash = 0;
00595 int len = object_key.length;
00596 for (int i = 0; i < len; i++) {
00597 hash += (object_key[i] << (i % 32));
00598 }
00599 return hash + super.hashCode();
00600 }
00601
00602 public String toString() {
00603 String str = "GIOPCltSessionIdentifier[key[";
00604 if (object_key.length > 0) {
00605 str = str + object_key[0];
00606 }
00607 for (int i = 1; i < object_key.length; i++) {
00608 str = str + "," + object_key[i];
00609 }
00610 if (next_two != null) {
00611 str = str + "],"+ next + ", " + next_two + "]";
00612 } else {
00613 str = str + "]," + next + "]";
00614 }
00615 return str;
00616 }
00617 }
00618
00619 final class ClientSession_Low implements Session_Low {
00620
00621 ClientSession_Low() {}
00622
00623 public void send(UnMarshaller unmarshaller,Session_High sender)
00624 throws JonathanException {
00625
00626
00627 int msg_type, msg_size;
00628 boolean little_endian;
00629 try {
00630 if (unmarshaller.readByte() != 'G' ||
00631 unmarshaller.readByte() != 'I' ||
00632 unmarshaller.readByte() != 'O' ||
00633 unmarshaller.readByte() != 'P') {
00634 unmarshaller.close();
00635 sendError(sender);
00636 return;
00637 }
00638 byte major = unmarshaller.readByte();
00639 byte minor = unmarshaller.readByte();
00640 little_endian = unmarshaller.readByte() == 0 ? false : true;
00641 msg_type = unmarshaller.readByte();
00642 unmarshaller.setByteOrder(little_endian);
00643 msg_size = unmarshaller.readInt();
00644 unmarshaller.setSize(msg_size);
00645 switch (msg_type) {
00646 case MsgType_1_0._Reply:
00647 ServiceContext[] contexts = decodeServices(unmarshaller);
00648 int rq_id = unmarshaller.readInt();
00649 if (services_handler != null) {
00650 services_handler.handleReplyContexts(contexts,rq_id,
00651 unmarshaller.getContext());
00652 }
00653 ReplyHolder reply = getHolder(rq_id);
00654 if (reply == null) {
00655
00656 unmarshaller.close();
00657 if (verbose) {
00658 System.err.println("Request #" + rq_id + " not found.");
00659 }
00660 } else {
00661 Component component =
00662 scheduler.getCurrent().getContext().
00663 getComponent("UnknownException",(char) 0);
00664 if (component != null) {
00665 unmarshaller.getContext().addElement("UnknownException",component,(char) 0);
00666 }
00667 reply.sendReply(unmarshaller);
00668 }
00669 return;
00670 case MsgType_1_0._CloseConnection:
00671 unmarshaller.close();
00672 return;
00673 case MsgType_1_0._MessageError:
00674 unmarshaller.close();
00675 throw new InternalException("GIOP Message error.");
00676 case MsgType_1_0._LocateReply:
00677 default:
00678 unmarshaller.close();
00679 sendError(sender);
00680 return;
00681 }
00682 } catch (JonathanException e) {
00683 unmarshaller.close();
00684 send(e,sender);
00685 }
00686 }
00687
00688 public void send(JonathanException e, Session_High sender) {
00689 forwardException(e,sender);
00690 }
00691 }
00692
00693 final class ServerSession_Low implements Session_Low {
00694
00695 ServerSession_Low() {}
00696
00697 public void send(UnMarshaller unmarshaller,Session_High sender)
00698 throws JonathanException {
00699
00700
00701 int msg_type, msg_size;
00702 boolean little_endian;
00703 boolean unmarshaller_opened = true;
00704 try {
00705 if (unmarshaller.readByte() != 'G' ||
00706 unmarshaller.readByte() != 'I' ||
00707 unmarshaller.readByte() != 'O' ||
00708 unmarshaller.readByte() != 'P') {
00709 if (verbose) {
00710 System.err.println("GIOP message error: bad magic bytes.");
00711 }
00712 unmarshaller.close();
00713 sendError(sender);
00714 return;
00715 }
00716 byte major = unmarshaller.readByte();
00717 byte minor = unmarshaller.readByte();
00718 little_endian = unmarshaller.readByte() == 0 ? false : true;
00719 msg_type = unmarshaller.readByte();
00720 unmarshaller.setByteOrder(little_endian);
00721 msg_size = unmarshaller.readInt();
00722 unmarshaller.setSize(msg_size);
00723
00724 int rq_id, len;
00725 switch (msg_type) {
00726 case MsgType_1_0._Request:
00727
00728 ServiceContext[] contexts = decodeServices(unmarshaller);
00729
00730 rq_id = unmarshaller.readInt();
00731 boolean response_expected = unmarshaller.readBoolean();
00732 RequestSession request_session = null;
00733 try {
00734 len = unmarshaller.readInt();
00735 byte[] object_key = new byte[len];
00736 unmarshaller.readByteArray(object_key,0,len);
00737 if (services_handler != null) {
00738 services_handler.handleRequestContexts(contexts,
00739 rq_id,
00740 response_expected,
00741 object_key,
00742 unmarshaller.getContext());
00743 }
00744 Identifier id = adapter.decode(object_key,0,len);
00745 request_session = (RequestSession) id.bind(null,null);
00746 if (request_session != null) {
00747
00748
00749 ServerSession_High reply_session = response_expected ?
00750 new ServerSession_High(sender, rq_id) : null;
00751 request_session.send(unmarshaller,reply_session);
00752 return;
00753 }
00754 unmarshaller_opened = false;
00755 unmarshaller.close();
00756 if (response_expected) {
00757 Object fwd = id.resolve();
00758 if (fwd != null) {
00759
00760 Marshaller marshaller =
00761 prepareReplyMessage(rq_id,MsgType_1_0._Reply,
00762 ReplyStatusType_1_0._LOCATION_FORWARD);
00763 marshaller.writeReference(fwd);
00764 sendMessage(marshaller,sender);
00765 sender.close();
00766 return;
00767 } else {
00768
00769
00770 sendSystemException(corba_prefix +
00771 "OBJECT_NOT_EXIST:1.0",
00772 0,
00773 CompletionStatus.COMPLETED_NO,
00774 rq_id,
00775 sender);
00776 }
00777 }
00778 } catch (UnknownException e) {
00779 if (verbose) {
00780 System.err.println("Exception caught in GIOP");
00781 e.originalEx.printStackTrace();
00782 }
00783 if (unmarshaller_opened) {
00784 unmarshaller.close();
00785 }
00786 if (response_expected) {
00787 scheduler.getCurrent().getContext().
00788 addElement("UnknownException",Throwable.class,
00789 e.originalEx,(char) 0);
00790 sendSystemException(corba_prefix + "UNKNOWN:1.0",
00791 e.minor,
00792 e.completed,
00793 rq_id,
00794 sender);
00795 }
00796 } catch (SystemException e) {
00797 if (verbose) {
00798 System.err.println("Exception caught in GIOP");
00799 e.printStackTrace();
00800 }
00801 if (unmarshaller_opened) {
00802 unmarshaller.close();
00803 }
00804 if (response_expected) {
00805 sendSystemException(e,rq_id,sender);
00806 }
00807 } catch (Exception e) {
00808 if (verbose) {
00809 System.err.println("Exception caught in GIOP");
00810 e.printStackTrace();
00811 }
00812 if (unmarshaller_opened) {
00813 unmarshaller.close();
00814 }
00815 if (response_expected) {
00816 CompletionStatus completed;
00817 if (request_session != null) {
00818 completed = CompletionStatus.COMPLETED_MAYBE;
00819 } else {
00820 completed = CompletionStatus.COMPLETED_NO;
00821 }
00822 SystemException sexp =
00823 CORBAHelpers.systemException(e,completed);
00824 if (sexp instanceof UNKNOWN) {
00825 if (e instanceof JonathanException) {
00826 e = ((JonathanException) e).represents();
00827 }
00828 scheduler.getCurrent().getContext().
00829 addElement("UnknownException",Throwable.class,
00830 e,(char) 0);
00831 sendSystemException(corba_prefix + "UNKNOWN:1.0",
00832 sexp.minor,
00833 sexp.completed,
00834 rq_id,
00835 sender);
00836 } else {
00837 sendSystemException(sexp,rq_id,sender);
00838 }
00839 }
00840 }
00841 return;
00842 case MsgType_1_0._CancelRequest:
00843 rq_id = unmarshaller.readInt();
00844 unmarshaller_opened = false;
00845 unmarshaller.close();
00846 return;
00847 case MsgType_1_0._LocateRequest:
00848 rq_id = unmarshaller.readInt();
00849 len = unmarshaller.readInt();
00850 byte[] object_key = new byte[len];
00851 unmarshaller.readByteArray(object_key,0,len);
00852 unmarshaller_opened = false;
00853 unmarshaller.close();
00854
00855
00856 Identifier id = adapter.decode(object_key,0,len);
00857 Marshaller marshaller = null;
00858 if (id.isValid()) {
00859 Object fwd = id.resolve();
00860 if (fwd != null) {
00861 marshaller =
00862 prepareReplyMessage(rq_id,MsgType_1_0._LocateReply,
00863 LocateStatusType_1_0._OBJECT_FORWARD);
00864 marshaller.writeReference(fwd);
00865 } else {
00866 marshaller =
00867 prepareReplyMessage(rq_id,MsgType_1_0._LocateReply,
00868 LocateStatusType_1_0._OBJECT_HERE);
00869 }
00870 } else {
00871 marshaller =
00872 prepareReplyMessage(rq_id,MsgType_1_0._LocateReply,
00873 LocateStatusType_1_0._UNKNOWN_OBJECT);
00874 }
00875 sendMessage(marshaller,sender);
00876 sender.close();
00877 return;
00878 case MsgType_1_0._MessageError:
00879 unmarshaller_opened = false;
00880 unmarshaller.close();
00881 sender.close();
00882 throw new InternalException("GIOP Message error.");
00883 default:
00884 unmarshaller_opened = false;
00885 unmarshaller.close();
00886 if (verbose) {
00887 System.err.println("Sending error to sender. Bad message tag: " + msg_type);
00888 }
00889 sendError(sender);
00890 return;
00891 }
00892 } catch (JonathanException e) {
00893 if (verbose) {
00894 e.printStackTrace();
00895
00896
00897 }
00898 if (unmarshaller_opened) {
00899 unmarshaller.close();
00900 }
00901 sender.close();
00902 }
00903 }
00904
00905 public void send(JonathanException e, Session_High sender) {
00906 if (verbose) {
00907 System.err.println("Caught exception related to " + sender);
00908 e.printStackTrace();
00909 }
00910 sender.close();
00911 }
00912
00913 void sendSystemException(SystemException e,
00914 int rq_id,
00915 Session_High session) {
00916 String name = e.getClass().getName();
00917 int begin = name.lastIndexOf('.') + 1;
00918 name = name.substring(begin);
00919 sendSystemException(corba_prefix + name + ":1.0",
00920 e.minor,
00921 e.completed,
00922 rq_id,
00923 session);
00924 }
00925
00926 void sendSystemException(String id, int minor, CompletionStatus status,
00927 int rq_id,
00928 Session_High session) {
00929 try {
00930 Marshaller marshaller =
00931 prepareReplyMessage(rq_id,MsgType_1_0._Reply,
00932 ReplyStatusType_1_0._SYSTEM_EXCEPTION);
00933 marshaller.writeString8(id);
00934 marshaller.writeInt(minor);
00935 marshaller.writeInt(status.value());
00936 sendMessage(marshaller,session);
00937 } catch (Exception ignored) {
00938 } finally {
00939 session.close();
00940 }
00941 }
00942 }
00943
00944
00945 class ClientSession_High extends GIOPSession_High implements Session_High {
00946 byte[] object_key;
00947
00948
00953 ClientSession_High(byte[] object_key,Session_High lower) {
00954 super(lower);
00955 this.object_key = object_key;
00956 }
00957
00958 public ReplyInterface prepareInvocation(Marshaller marshaller)
00959 throws JonathanException {
00960 marshaller.writeByteArray(header,0,6);
00961 marshaller.writeBoolean(marshaller.isLittleEndian());
00962 marshaller.writeByte((byte) MsgType_1_0._Request);
00963 marshaller.writeInt(0);
00964 ReplyHolder reply = registerHolder(lower);
00965 encodeRequestServices(marshaller,reply.id,true,object_key);
00966 marshaller.writeInt(reply.id);
00967 marshaller.writeBoolean(true);
00968 int len = object_key.length;
00969 marshaller.writeInt(len);
00970 marshaller.writeByteArray(object_key,0,len);
00971 return reply;
00972 }
00973
00974 public void prepare(Marshaller marshaller)
00975 throws JonathanException {
00976 marshaller.writeByteArray(header,0,6);
00977 marshaller.writeBoolean(marshaller.isLittleEndian());
00978 marshaller.writeByte((byte) MsgType_1_0._Request);
00979 marshaller.writeInt(0);
00980 encodeRequestServices(marshaller,0,false,object_key);
00981 marshaller.writeInt(0);
00982 marshaller.writeBoolean(false);
00983 int len = object_key.length;
00984 marshaller.writeInt(len);
00985 marshaller.writeByteArray(object_key,0,len);
00986 }
00987 }
00988
00989 Marshaller prepareReplyMessage(int rq_id,int msg_type,int reply_type)
00990 throws JonathanException {
00991 Marshaller marshaller = marshaller_factory.newMarshaller();
00992 marshaller.writeByteArray(header,0,6);
00993 marshaller.writeBoolean(marshaller.isLittleEndian());
00994 marshaller.writeByte((byte) msg_type);
00995 marshaller.writeInt(0);
00996 if (msg_type == MsgType_1_0._Reply) {
00997 encodeReplyServices(marshaller,rq_id);
00998 }
00999 marshaller.writeInt(rq_id);
01000 marshaller.writeInt(reply_type);
01001 return marshaller;
01002 }
01003
01004 class ServerSession_High extends GIOPSession_High implements ReplySession {
01005 int rq_id;
01006
01007 public ServerSession_High(Session_High lower,int rq_id) {
01008 super(lower);
01009 this.rq_id = rq_id;
01010 }
01011
01012 public Marshaller prepareReply()
01013 throws JonathanException {
01014
01015 return prepareReplyMessage(rq_id,MsgType_1_0._Reply,
01016 ReplyStatusType_1_0._NO_EXCEPTION);
01017 }
01018
01019 public Marshaller prepareExceptionReply()
01020 throws JonathanException {
01021 return prepareReplyMessage(rq_id,MsgType_1_0._Reply,
01022 ReplyStatusType_1_0._USER_EXCEPTION);
01023 }
01024 }
01025
01026 void sendMessage(Marshaller marshaller,Session_High lower)
01027 throws JonathanException {
01028 Chunk first = marshaller.getState();
01029 Chunk c = first;
01030 int size = 0;
01031 while (c != null) {
01032 size += c.top - c.offset;
01033 c = c.next;
01034 }
01035 int offset = marshaller.getOffset();
01036 marshaller.setOffset(8);
01037 marshaller.writeInt(size - 12);
01038 marshaller.setOffset(offset);
01039 if (lower.direct()) {
01040 lower.send(marshaller);
01041 } else {
01042 Marshaller m = marshaller_factory.newMarshaller();
01043 lower.prepare(m);
01044 m.write(marshaller.getState());
01045 marshaller.reset();
01046 lower.send(m);
01047 }
01048 }
01049
01050 class GIOPSession_High {
01051 Session_High lower;
01052
01053 GIOPSession_High(Session_High lower) {
01054 this.lower = lower;
01055 }
01056
01057 public boolean direct() {
01058 return false;
01059 }
01060
01061 public void send(Marshaller marshaller) throws JonathanException {
01062 sendMessage(marshaller,lower);
01063 }
01064
01065 public void close() {
01066 lower.close();
01067 }
01068 }
01069
01070 class ReplyHolder implements ReplyInterface {
01071 Object reply;
01073 int id;
01075 ReplyHolder next;
01076 Session_High lower;
01077
01078 ReplyHolder(Session_High lower) {
01079 super();
01080 this.lower = lower;
01081 }
01082
01083 public synchronized UnMarshaller listen() throws JonathanException {
01084 try {
01085 while (reply == null) {
01086 scheduler.wait(this);
01087 }
01088 UnMarshaller message = (UnMarshaller) reply;
01089 int reply_status = message.readInt();
01090 switch (reply_status) {
01091 case ReplyStatusType_1_0._NO_EXCEPTION:
01092 return message;
01093 case ReplyStatusType_1_0._USER_EXCEPTION:
01094 throw new ServerException(message);
01095 case ReplyStatusType_1_0._SYSTEM_EXCEPTION:
01096 try {
01097 SystemException sys_excep = null;
01098 String str = message.readString8();
01099 Object server_ex =
01100 message.getContext().getValue("UnknownException",(char) 0);
01101 if (server_ex != Context.NO_VALUE) {
01102 sys_excep = new GIOPUnknownException((Throwable) server_ex);
01103 } else {
01104 int begin = str.lastIndexOf('/') + 1;
01105 int end = str.lastIndexOf(':');
01106 if (begin < 0 || end < begin) {
01107 throw new JonathanException("Bad repository id " + str);
01108 }
01109 str = str.substring(begin,end);
01110 str = "org.omg.CORBA." + str;
01111 sys_excep = (SystemException)
01112 finder.findClass(str).newInstance();
01113 }
01114 sys_excep.minor = message.readInt();
01115 sys_excep.completed =
01116 CompletionStatus.from_int(message.readInt());
01117 throw sys_excep;
01118 } catch (Exception e) {
01119 throw new JonathanException(e);
01120 } finally {
01121 message.close();
01122 }
01123 case ReplyStatusType_1_0._LOCATION_FORWARD:
01124 try {
01125 Object ref = message.readReference();
01126 throw new ForwardException(ref);
01127 } finally {
01128 message.close();
01129 }
01130 default:
01131
01132 return null;
01133 }
01134 } catch (InterruptedException e) {
01135 throw new JonathanException(e);
01136 } catch (ClassCastException e) {
01137 throw (JonathanException) reply;
01138
01139
01140
01141
01142
01143
01144 } finally {
01145 reply = null;
01146 removeHolder(id);
01147 }
01148 }
01149
01150 public synchronized boolean available() {
01151 return reply != null;
01152 }
01153
01154 final synchronized void sendReply(Object reply) {
01155 this.reply = reply;
01156 scheduler.notify(this);
01157 }
01158 }
01159
01160 static class GIOPUnknownException extends UnknownException {
01161 GIOPUnknownException(Throwable ex) {
01162 super(ex);
01163 }
01164
01165 public String toString() {
01166 if (originalEx != null) {
01167 return "Unknown Server Exception : " + originalEx;
01168 } else {
01169 return super.toString();
01170 }
01171 }
01172 }
01173 }