001: package org.jacorb.orb.giop;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.io.IOException;
024:
025: import org.apache.avalon.framework.logger.Logger;
026: import org.jacorb.orb.ORB;
027: import org.jacorb.orb.SystemExceptionHelper;
028: import org.omg.CORBA.MARSHAL;
029: import org.omg.GIOP.LocateStatusType_1_2;
030: import org.omg.GIOP.MsgType_1_1;
031: import org.omg.GIOP.ReplyStatusType_1_0;
032: import org.omg.GIOP.ReplyStatusType_1_2;
033:
034: /**
035: * @author Gerald Brose
036: * @version $Id: ReplyOutputStream.java,v 1.23 2006/06/28 12:41:43 alphonse.bendt Exp $
037: *
038: */
039: public class ReplyOutputStream extends
040: ServiceContextTransportingOutputStream {
041: private final boolean is_locate_reply;
042: private final Logger logger;
043:
044: public ReplyOutputStream(int request_id,
045: ReplyStatusType_1_2 reply_status, int giop_minor,
046: boolean is_locate_reply, Logger logger) {
047: this (null, request_id, reply_status, giop_minor,
048: is_locate_reply, logger);
049: }
050:
051: public ReplyOutputStream(ORB orb, int request_id,
052: ReplyStatusType_1_2 reply_status, int giop_minor,
053: boolean is_locate_reply, Logger logger) {
054: super (orb);
055:
056: this .logger = logger;
057: this .is_locate_reply = is_locate_reply;
058:
059: setGIOPMinor(giop_minor);
060:
061: writeGIOPMsgHeader(MsgType_1_1._Reply, giop_minor);
062:
063: switch (giop_minor) {
064: case 0: {
065: // GIOP 1.0 Reply == GIOP 1.1 Reply, fall through
066: }
067: case 1: {
068: //Technically, GIOP.idl only allows either
069: //ReplyStatusType_1_0 or ReplyStatusType_1_2, but not
070: //both. We go around this by compiling GIOP.idl two
071: //times
072:
073: //GIOP 1.1
074: // ReplyHeader_1_0 repl_hdr =
075: // new ReplyHeader_1_0( alignment_ctx,
076: // request_id,
077: // ReplyStatusType_1_0.from_int( reply_status.value() ));
078: // ReplyHeader_1_0Helper.write( this, repl_hdr );
079:
080: // inlining for performance
081:
082: org.omg.IOP.ServiceContextListHelper.write(this ,
083: Messages.service_context);
084: write_ulong(request_id);
085: org.omg.GIOP.ReplyStatusType_1_0Helper.write(this ,
086: ReplyStatusType_1_0.from_int(reply_status.value()));
087:
088: break;
089: }
090: case 2: {
091: //GIOP 1.2
092: // ReplyHeader_1_2 repl_hdr =
093: // new ReplyHeader_1_2( request_id,
094: // reply_status,
095: // alignment_ctx );
096:
097: // ReplyHeader_1_2Helper.write( this, repl_hdr );
098:
099: // more inlining
100:
101: write_ulong(request_id);
102: org.omg.GIOP.ReplyStatusType_1_2Helper.write(this ,
103: reply_status);
104:
105: org.omg.IOP.ServiceContextListHelper.write(this ,
106: Messages.service_context);
107:
108: markHeaderEnd(); //use padding if minor 2
109:
110: break;
111: }
112: default: {
113: throw new MARSHAL("Unknown GIOP minor: " + giop_minor);
114: }
115: }
116: }
117:
118: public void write_to(GIOPConnection conn) throws IOException {
119: if (is_locate_reply) {
120: final ReplyInputStream in = new ReplyInputStream(null,
121: getBufferCopy());
122: try {
123: final LocateReplyOutputStream out = getLocateReplyOutputStream(in);
124: try {
125: out.write_to(conn);
126: } finally {
127: out.close();
128: }
129: } finally {
130: in.close();
131: }
132: } else {
133: super .write_to(conn);
134: }
135: }
136:
137: private LocateReplyOutputStream getLocateReplyOutputStream(
138: ReplyInputStream replyInputStream) {
139: final LocateReplyOutputStream result;
140:
141: if (replyInputStream.getGIOPMinor() < 2) {
142: //GIOP 1.0 or 1.1
143: switch (replyInputStream.rep_hdr.reply_status.value()) {
144: case ReplyStatusType_1_2._NO_EXCEPTION: {
145: int status;
146:
147: //_non_existent?
148: if (replyInputStream.read_boolean()) {
149: //_non_existent == true
150: status = LocateStatusType_1_2._UNKNOWN_OBJECT;
151: } else {
152: //_non_existent == false
153: status = LocateStatusType_1_2._OBJECT_HERE;
154: }
155:
156: result = new LocateReplyOutputStream(
157: replyInputStream.rep_hdr.request_id, status,
158: replyInputStream.getGIOPMinor());
159:
160: break;
161: }
162: case ReplyStatusType_1_2._USER_EXCEPTION: {
163: //fall through
164: }
165: case ReplyStatusType_1_2._SYSTEM_EXCEPTION: {
166: //uh oh, can't reply with exception
167: if (logger.isErrorEnabled()) {
168: logger
169: .error("Received an exception when processing a LocateRequest");
170: }
171:
172: // GIOP prior to 1.2 doesn't have the status
173: // LOC_SYSTEM_EXCEPTION, so we have to return
174: // OBJECT_UNKNOWN (even if it may not be unknown)
175: result = new LocateReplyOutputStream(
176: replyInputStream.rep_hdr.request_id,
177: LocateStatusType_1_2._UNKNOWN_OBJECT,
178: replyInputStream.getGIOPMinor());
179: break;
180: }
181: case ReplyStatusType_1_2._LOCATION_FORWARD: {
182:
183: result = new LocateReplyOutputStream(
184: replyInputStream.rep_hdr.request_id,
185: LocateStatusType_1_2._OBJECT_FORWARD,
186: replyInputStream.getGIOPMinor());
187:
188: //FIXME: it would be more efficient to copy
189: //the body part of this buffer to the new
190: //buffer
191: result.write_IOR(org.omg.IOP.IORHelper
192: .read(replyInputStream));
193:
194: break;
195: }
196: default:
197: throw new IllegalArgumentException(
198: "ReplyStatus is invalid");
199: }
200: } else {
201: //GIOP 1.2
202: switch (replyInputStream.rep_hdr.reply_status.value()) {
203: case ReplyStatusType_1_2._NO_EXCEPTION: {
204: int status;
205:
206: //_non_existent?
207: if (replyInputStream.read_boolean()) {
208: //_non_existent == true
209: status = LocateStatusType_1_2._UNKNOWN_OBJECT;
210: } else {
211: //_non_existent == false
212: status = LocateStatusType_1_2._OBJECT_HERE;
213: }
214:
215: result = new LocateReplyOutputStream(
216: replyInputStream.rep_hdr.request_id, status,
217: replyInputStream.getGIOPMinor());
218:
219: break;
220: }
221: case ReplyStatusType_1_2._USER_EXCEPTION: {
222: //uh oh, can't reply with user exception
223: if (logger.isErrorEnabled()) {
224: logger
225: .error("Received an exception when processing a LocateRequest - mapping to UNKNOWN system exception");
226: }
227:
228: result = new LocateReplyOutputStream(
229: replyInputStream.rep_hdr.request_id,
230: LocateStatusType_1_2._LOC_SYSTEM_EXCEPTION,
231: replyInputStream.getGIOPMinor());
232:
233: SystemExceptionHelper.write(result,
234: new org.omg.CORBA.UNKNOWN());
235: break;
236: }
237: case ReplyStatusType_1_2._SYSTEM_EXCEPTION: {
238:
239: result = new LocateReplyOutputStream(
240: replyInputStream.rep_hdr.request_id,
241: LocateStatusType_1_2._LOC_SYSTEM_EXCEPTION,
242: replyInputStream.getGIOPMinor());
243:
244: //FIXME: inefficient, use copying
245: SystemExceptionHelper.write(result,
246: SystemExceptionHelper.read(replyInputStream));
247:
248: break;
249: }
250: case ReplyStatusType_1_2._LOCATION_FORWARD: {
251:
252: result = new LocateReplyOutputStream(
253: replyInputStream.rep_hdr.request_id,
254: LocateStatusType_1_2._OBJECT_FORWARD,
255: replyInputStream.getGIOPMinor());
256:
257: //FIXME: it would be more efficient to copy
258: //the body part of this buffer to the new
259: //buffer
260: result.write_IOR(org.omg.IOP.IORHelper
261: .read(replyInputStream));
262:
263: break;
264: }
265: default:
266: throw new IllegalArgumentException(
267: "ReplyStatus is invalid");
268: }
269: }
270: return result;
271: }
272: }
|