001: package org.jacorb.orb.dii;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2006 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 org.omg.CORBA.Any;
024: import org.omg.CORBA.INTERNAL;
025: import org.omg.CORBA.NVList;
026: import org.omg.CORBA.NamedValue;
027: import org.omg.CORBA.TCKind;
028: import org.omg.CORBA.portable.*;
029:
030: import org.apache.avalon.framework.logger.Logger;
031: import org.jacorb.orb.ORB;
032: import org.jacorb.orb.portableInterceptor.*;
033: import org.jacorb.orb.giop.*;
034:
035: import java.util.Iterator;
036:
037: /**
038: * DII requests
039: *
040: * @author Gerald Brose, FU Berlin
041: * @version $Id: Request.java,v 1.27 2006/07/26 08:02:25 alphonse.bendt Exp $
042: */
043: public class Request extends org.omg.CORBA.Request {
044: public final org.omg.CORBA.Object target;
045: public final ClientConnection connection;
046: public final byte[] object_key;
047: public final NVList arguments;
048: public final String operation;
049: public final org.omg.CORBA.Environment env = new Environment();
050:
051: private final org.jacorb.orb.NamedValue result_value;
052: private final org.omg.CORBA.ExceptionList exceptions;
053: private final org.jacorb.orb.ORB orb;
054:
055: // TODO need to remove some logging statements again or wrap them in isDebugEnabled
056: // added the extra log statements to trace a spurious test failure.
057: private final Logger logger;
058:
059: private final org.omg.CORBA.ContextList contexts = new ContextListImpl();
060: private org.omg.CORBA.Context context;
061: private Caller deferred_caller;
062: private org.omg.CORBA.portable.InputStream reply;
063:
064: /* state of request object */
065: private boolean immediate = false;
066: private boolean deferred = false;
067: private boolean finished = false;
068:
069: private ClientRequestInfoImpl info = null;
070:
071: public Request(org.omg.CORBA.Object target, ORB orb,
072: ClientConnection connection, byte[] obj_key,
073: String operationName) {
074: this (target, orb, connection, obj_key, operationName, orb
075: .create_list(10), null, createVoidResultValue(orb));
076: }
077:
078: private static final NamedValue createVoidResultValue(ORB orb) {
079: Any any = orb.create_any();
080: any.type(orb.get_primitive_tc(TCKind.tk_void));
081: org.jacorb.orb.NamedValue namedValue = new org.jacorb.orb.NamedValue(
082: 1);
083: namedValue.set_value(any);
084: return namedValue;
085: }
086:
087: public Request(org.omg.CORBA.Object target, ORB orb,
088: ClientConnection connection, byte[] obj_key, String op,
089: org.omg.CORBA.NVList args, org.omg.CORBA.Context context,
090: org.omg.CORBA.NamedValue result) {
091: super ();
092:
093: this .target = target;
094: this .orb = orb;
095: this .connection = connection;
096: this .object_key = obj_key;
097: this .operation = op;
098: exceptions = new ExceptionList();
099:
100: this .arguments = args;
101: this .context = context;
102: result_value = (org.jacorb.orb.NamedValue) result;
103:
104: logger = orb.getConfiguration().getNamedLogger(
105: "jacorb.dii.request");
106: }
107:
108: public org.omg.CORBA.Object target() {
109: return target;
110: }
111:
112: public java.lang.String operation() {
113: return operation;
114: }
115:
116: public org.omg.CORBA.NVList arguments() {
117: return arguments;
118: }
119:
120: public org.omg.CORBA.NamedValue result() {
121: return result_value;
122: }
123:
124: public org.omg.CORBA.Environment env() {
125: return env;
126: }
127:
128: public org.omg.CORBA.ExceptionList exceptions() {
129: return exceptions;
130: }
131:
132: public org.omg.CORBA.ContextList contexts() {
133: return contexts;
134: }
135:
136: public org.omg.CORBA.Context ctx() {
137: return context;
138: }
139:
140: public void ctx(org.omg.CORBA.Context ctx) {
141: this .context = ctx;
142: }
143:
144: public Any add_in_arg() {
145: NamedValue nv = arguments.add(org.omg.CORBA.ARG_IN.value);
146: ((org.jacorb.orb.NamedValue) nv).set_value(orb.create_any());
147: return nv.value();
148: }
149:
150: public Any add_named_in_arg(java.lang.String name) {
151: NamedValue nv = arguments.add_item(name,
152: org.omg.CORBA.ARG_IN.value);
153: ((org.jacorb.orb.NamedValue) nv).set_value(orb.create_any());
154: return nv.value();
155: }
156:
157: public Any add_inout_arg() {
158: NamedValue nv = arguments.add(org.omg.CORBA.ARG_INOUT.value);
159: ((org.jacorb.orb.NamedValue) nv).set_value(orb.create_any());
160: return nv.value();
161: }
162:
163: public Any add_named_inout_arg(java.lang.String name) {
164: NamedValue nv = arguments.add_item(name,
165: org.omg.CORBA.ARG_INOUT.value);
166: ((org.jacorb.orb.NamedValue) nv).set_value(orb.create_any());
167: return nv.value();
168: }
169:
170: public Any add_out_arg() {
171: NamedValue nv = arguments.add(org.omg.CORBA.ARG_OUT.value);
172: ((org.jacorb.orb.NamedValue) nv).set_value(orb.create_any());
173: return nv.value();
174: }
175:
176: public Any add_named_out_arg(java.lang.String name) {
177: NamedValue nv = arguments.add_item(name,
178: org.omg.CORBA.ARG_OUT.value);
179: ((org.jacorb.orb.NamedValue) nv).set_value(orb.create_any());
180: return nv.value();
181: }
182:
183: /**
184: * default return type is void
185: */
186:
187: public void set_return_type(org.omg.CORBA.TypeCode tc) {
188: result_value.value().type(tc);
189: }
190:
191: public Any return_value() {
192: return result_value.value();
193: }
194:
195: private void _read_result() {
196: if (result_value.value().type().kind() != org.omg.CORBA.TCKind.tk_void) {
197: result_value.value().read_value(reply,
198: result_value.value().type());
199: }
200:
201: /** get out/inout parameters if any */
202: for (Iterator e = ((org.jacorb.orb.NVList) arguments)
203: .iterator(); e.hasNext();) {
204: org.jacorb.orb.NamedValue nv = (org.jacorb.orb.NamedValue) e
205: .next();
206: if (nv.flags() != org.omg.CORBA.ARG_IN.value) {
207: nv.receive(reply);
208: }
209: }
210: }
211:
212: private void _invoke(boolean response_expected) {
213: while (true) {
214: org.jacorb.orb.Delegate delegate = (org.jacorb.orb.Delegate) ((org.omg.CORBA.portable.ObjectImpl) target)
215: ._get_delegate();
216:
217: final RequestOutputStream out = (RequestOutputStream) delegate
218: .request(target, operation, response_expected);
219:
220: try {
221: out.setRequest(this );
222:
223: for (Iterator it = ((org.jacorb.orb.NVList) arguments)
224: .iterator(); it.hasNext();) {
225: org.jacorb.orb.NamedValue namedValue = (org.jacorb.orb.NamedValue) it
226: .next();
227: if (namedValue.flags() != org.omg.CORBA.ARG_OUT.value) {
228: namedValue.send(out);
229: }
230: }
231:
232: try {
233: logger.debug("delegate.invoke(...)");
234: reply = delegate.invoke(target, out);
235:
236: if (response_expected) {
237: _read_result();
238:
239: if (info != null) {
240: info.setResult(result_value.value());
241: InterceptorManager manager = orb
242: .getInterceptorManager();
243: info.setCurrent(manager.getCurrent());
244:
245: try {
246: delegate
247: .invokeInterceptors(
248: info,
249: ClientInterceptorIterator.RECEIVE_REPLY);
250: } catch (RemarshalException e) {
251: //not allowed to happen here anyway
252: throw new INTERNAL("should not happen");
253: }
254: info = null;
255: }
256: }
257: } catch (RemarshalException e) {
258: logger.debug("RemarshalException", e);
259: // Try again
260: continue;
261: } catch (ApplicationException e) {
262: logger.debug("ApplicationException", e);
263:
264: org.omg.CORBA.Any any;
265: org.omg.CORBA.TypeCode typeCode;
266: String id = e.getId();
267: int count = exceptions.count();
268:
269: logger.debug("exceptions.count: " + count);
270:
271: for (int i = 0; i < count; i++) {
272: try {
273: typeCode = exceptions.item(i);
274:
275: logger.debug(typeCode + " == " + id + "?");
276:
277: if (id.equals(typeCode.id())) {
278: logger.debug("YES");
279: any = orb.create_any();
280: any.read_value(e.getInputStream(),
281: typeCode);
282: env
283: .exception(new org.omg.CORBA.UnknownUserException(
284: any));
285: break;
286: }
287: } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) // NOPMD
288: {
289: // Ignored
290: } catch (org.omg.CORBA.Bounds ex) {
291: break;
292: }
293: }
294:
295: break;
296: } catch (Exception e) {
297: logger.debug("Exception", e);
298: env.exception(e);
299: break;
300: }
301:
302: break;
303: } finally {
304: out.close();
305: }
306: }
307: }
308:
309: public void setInfo(ClientRequestInfoImpl info) {
310: this .info = info;
311: }
312:
313: public void invoke() {
314: start();
315: _invoke(true);
316: finish();
317: }
318:
319: public void send_oneway() {
320: start();
321: _invoke(false);
322: finish();
323: }
324:
325: private static class Caller extends Thread {
326: private final Request request;
327: private boolean active = true;
328:
329: public Caller(Request client) {
330: request = client;
331: }
332:
333: public void run() {
334: request._invoke(true);
335: request.finish();
336:
337: synchronized (request) {
338: active = false;
339: request.notifyAll();
340: }
341: }
342:
343: public void joinWithCaller() {
344: synchronized (request) {
345: while (active) {
346: try {
347: request.wait();
348: } catch (InterruptedException e) // NOPMD
349: {
350: // ignored
351: }
352: }
353: }
354: }
355: }
356:
357: public synchronized void send_deferred() {
358: defer();
359: orb.addRequest(this );
360: deferred_caller = new Caller(this );
361: deferred_caller.start();
362: }
363:
364: public synchronized void get_response() {
365: if (!immediate && !deferred) {
366: throw new org.omg.CORBA.BAD_INV_ORDER(11,
367: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
368: }
369: if (immediate) {
370: throw new org.omg.CORBA.BAD_INV_ORDER(13,
371: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
372: }
373:
374: if (deferred_caller != null) {
375: deferred_caller.joinWithCaller();
376: deferred_caller = null;
377: orb.removeRequest(this );
378: }
379: }
380:
381: public synchronized boolean poll_response() {
382: if (!immediate && !deferred) {
383: throw new org.omg.CORBA.BAD_INV_ORDER(11,
384: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
385: }
386: if (immediate) {
387: throw new org.omg.CORBA.BAD_INV_ORDER(13,
388: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
389: }
390: if (deferred_caller == null) {
391: throw new org.omg.CORBA.BAD_INV_ORDER(12,
392: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
393: }
394: return finished;
395: }
396:
397: private synchronized void start()
398: throws org.omg.CORBA.BAD_INV_ORDER {
399: if (immediate || deferred) {
400: throw new org.omg.CORBA.BAD_INV_ORDER(10,
401: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
402: }
403: immediate = true;
404: }
405:
406: private synchronized void defer()
407: throws org.omg.CORBA.BAD_INV_ORDER {
408: if (immediate || deferred) {
409: throw new org.omg.CORBA.BAD_INV_ORDER(10,
410: org.omg.CORBA.CompletionStatus.COMPLETED_NO);
411: }
412: deferred = true;
413: }
414:
415: private synchronized void finish() {
416: finished = true;
417: }
418: }
|