/* * JacORB - a free Java ORB * * Copyright (C) 1999-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ package org.jacorb.orb.portableInterceptor; import java.util.HashMap; import java.util.Map; import org.jacorb.orb.Delegate; import org.jacorb.orb.Delegate.INVOCATION_KEY; import org.jacorb.orb.SystemExceptionHelper; import org.omg.CORBA.UserException; import org.omg.PortableInterceptor.ClientRequestInterceptor; import org.omg.PortableInterceptor.ForwardRequest; import org.omg.PortableInterceptor.Interceptor; import org.omg.PortableInterceptor.LOCATION_FORWARD; import org.omg.TimeBase.UtcT; import org.slf4j.Logger; /** * This class is an iterator over an array * of ClientRequestInterceptors. * * @author Nicolas Noffke */ public class ClientInterceptorIterator extends RequestInterceptorIterator { public static final short SEND_REQUEST = 0; public static final short SEND_POLL = 1; public static final short RECEIVE_REPLY = 2; public static final short RECEIVE_EXCEPTION = 3; public static final short RECEIVE_OTHER = 4; private ClientRequestInfoImpl info = null; private final Logger logger; public ClientInterceptorIterator(Logger logger, Interceptor[] interceptors) { super(interceptors); this.logger = logger; } public void iterate(ClientRequestInfoImpl info, short op) throws UserException { this.info = info; this.op = op; // ok, op <= SEND_POLL is more efficient but // less understandable setDirection((op == SEND_REQUEST) || (op == SEND_POLL)); /** * See RequestInterceptorIterator for full explanation * of this method. The client interceptor flow has no * intermediate points so this is always false. It has * been included for completeness. */ setIntermediatePoint (false); iterate(); //propagate last exception upwards if (interceptor_ex != null) { if (interceptor_ex instanceof ForwardRequest) { throw (ForwardRequest) interceptor_ex; } throw (org.omg.CORBA.SystemException) interceptor_ex; } } /** * Iterates over the enumeration, i.e. calls "op" on * nextElement() until !hasMoreElements(). */ protected void invoke(Interceptor interceptor) throws UserException { info.caller_op = op; HashMap<INVOCATION_KEY, UtcT> currentCtxt = new HashMap<INVOCATION_KEY, UtcT>(); try { /** * A new context is added for every interceptor call. This is * because the interceptor may perform a CORBA call and the * policies on the object it calls may be different to those on * the original object e.g. the original object could have a * timeout policy of 10 minutes whereas the object called by the * interceptor could have a timeout policy of 2 minutes. This * also follows that each interceptor could call a different * object with different timeout policies */ currentCtxt.put (INVOCATION_KEY.INTERCEPTOR_CALL, null); Delegate.getInvocationContext().push (currentCtxt); switch (op) { case SEND_REQUEST : ((ClientRequestInterceptor) interceptor).send_request(info); break; case SEND_POLL : ((ClientRequestInterceptor) interceptor).send_poll(info); break; case RECEIVE_REPLY : ((ClientRequestInterceptor) interceptor).receive_reply(info); break; case RECEIVE_EXCEPTION : ((ClientRequestInterceptor) interceptor).receive_exception(info); break; case RECEIVE_OTHER : ((ClientRequestInterceptor) interceptor).receive_other(info); } } catch (ForwardRequest _fwd) { reverseDirection(); op = RECEIVE_OTHER; info.reply_status = LOCATION_FORWARD.value; info.forward_reference = _fwd.forward; interceptor_ex = _fwd; } catch (org.omg.CORBA.SystemException _sysex) { reverseDirection(); op = RECEIVE_EXCEPTION; interceptor_ex = _sysex; SystemExceptionHelper.insert(info.received_exception, _sysex); try { info.received_exception_id = SystemExceptionHelper.type(_sysex).id(); } catch(org.omg.CORBA.TypeCodePackage.BadKind _bk) { logger.error("unexpected exception", _bk); } } finally { /** * Pop the invocation context on return from the interceptor call - whatever * happens */ Map<INVOCATION_KEY, UtcT> head = Delegate.getInvocationContext().peek (); if (head == currentCtxt) { Delegate.getInvocationContext().pop (); } } info.caller_op = op; } } // ClientInterceptorIterator