001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JonasHandler.java 7823 2005-12-19 16:25:53Z sauthieg $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.ws.axis;
025:
026: import javax.naming.Context;
027: import javax.naming.InitialContext;
028: import javax.naming.NamingException;
029:
030: import org.apache.axis.AxisFault;
031: import org.apache.axis.Handler;
032: import org.apache.axis.MessageContext;
033: import org.apache.axis.handlers.BasicHandler;
034:
035: import org.objectweb.jonas_ejb.container.JServiceEndpointHome;
036:
037: import org.objectweb.jonas_lib.I18n;
038:
039: import org.objectweb.jonas.common.Log;
040: import org.objectweb.jonas.security.ws.SecurityContextHelper;
041:
042: import org.objectweb.util.monolog.api.BasicLevel;
043: import org.objectweb.util.monolog.api.Logger;
044:
045: /**
046: * This handler is called before all application specific handlers It allows to
047: * process some jonas specific stuff like setting the bean environment for
048: * example.
049: *
050: * @author Philippe Durieux
051: */
052: public class JonasHandler extends BasicHandler {
053:
054: /**
055: * MC property : service.endpoint.home
056: */
057: private static final String SE_HOME = "service.endpoint.home";
058:
059: /**
060: * MC property : service.endpoint.context
061: */
062: private static final String SE_CONTEXT = "service.endpoint.context";
063:
064: /**
065: * logger
066: */
067: private static Logger logger = Log
068: .getLogger(Log.JONAS_WS_EJBPROVIDER_PREFIX);
069:
070: /**
071: * i18n instance
072: */
073: private static I18n i18n = I18n.getInstance(JonasHandler.class);
074:
075: /**
076: * cached initial context
077: */
078: private static InitialContext cachedContext;
079:
080: /**
081: * Thread local storage used for locating the active message context. This
082: * information is only valid for the lifetime of this request.
083: */
084: private static ThreadLocal currentMessageContext = new ThreadLocal();
085:
086: /**
087: * Set the active message context.
088: *
089: * @param mc the new active message context.
090: */
091: protected static void setCurrentMessageContext(MessageContext mc) {
092: currentMessageContext.set(mc);
093: }
094:
095: /**
096: * Get the active message context.
097: *
098: * @return the current active message context
099: */
100: public static MessageContext getCurrentMessageContext() {
101: return (MessageContext) currentMessageContext.get();
102: }
103:
104: /**
105: * Called on reply if a fault occured.
106: *
107: * @param msgContext MessageContext
108: */
109: public void onFault(MessageContext msgContext) {
110: logger.log(BasicLevel.ERROR, "*------* Fault");
111:
112: // save previous context
113: MessageContext previousContext = getCurrentMessageContext();
114:
115: try {
116: // set active context
117: setCurrentMessageContext(msgContext);
118:
119: JServiceEndpointHome sehome = getJServiceEndpointHome(msgContext);
120: Context savedCtx = getSavedContext(msgContext);
121: if (sehome != null) {
122: logger.log(BasicLevel.DEBUG, "*--* Fault");
123: sehome.resetCompCtx(savedCtx);
124: if (savedCtx != null) {
125: String msg = i18n
126: .getMessage(
127: "JonasHandler.onFault.settingNonNullContext",
128: savedCtx);
129: logger.log(BasicLevel.ERROR, msg);
130: }
131: unsetJServiceEndpointHome(msgContext);
132: unsetSavedContext(msgContext);
133: }
134: } finally {
135: // restore previous state
136: setCurrentMessageContext(previousContext);
137: }
138: }
139:
140: /**
141: * @param msgContext the MC which store the context
142: */
143: private void unsetSavedContext(MessageContext msgContext) {
144: msgContext.removeProperty(SE_CONTEXT);
145: }
146:
147: /**
148: * @param msgContext the MC which store the home
149: */
150: private void unsetJServiceEndpointHome(MessageContext msgContext) {
151: msgContext.removeProperty(SE_HOME);
152: }
153:
154: /**
155: * @param msgContext the MC to explore
156: * @return Returns the Context stored inside msgContext
157: */
158: private Context getSavedContext(MessageContext msgContext) {
159: return (Context) msgContext.getProperty(SE_CONTEXT);
160: }
161:
162: /**
163: * @param msgContext the MC to explore
164: * @return Returns the JServiceEndpointHome stored inside msgContext
165: */
166: private JServiceEndpointHome getJServiceEndpointHome(
167: MessageContext msgContext) {
168: return (JServiceEndpointHome) msgContext.getProperty(SE_HOME);
169: }
170:
171: /**
172: * Called on request and then on reply if no fault occured.
173: *
174: * @param msgContext
175: * MessageContext
176: * @throws AxisFault
177: * if the handler cannot get the service endpoint home
178: */
179: public void invoke(MessageContext msgContext) throws AxisFault {
180:
181: // save previous context
182: MessageContext previousContext = getCurrentMessageContext();
183:
184: try {
185: // set active context
186: setCurrentMessageContext(msgContext);
187:
188: if (msgContext.getPastPivot()) {
189: // Response
190: // ---------------------------------------------------
191: logger.log(BasicLevel.DEBUG, "*------* Response");
192: JServiceEndpointHome sehome = getJServiceEndpointHome(msgContext);
193: Context savedCtx = getSavedContext(msgContext);
194: if (sehome != null) {
195: logger.log(BasicLevel.DEBUG, "*--* Response");
196: sehome.resetCompCtx(savedCtx);
197: unsetJServiceEndpointHome(msgContext);
198: }
199: // ----------------------------------------------------
200: // /Response
201: } else {
202: // Request
203: // ---------------------------------------------------
204: logger.log(BasicLevel.DEBUG, "*------* Request");
205:
206: // Get the service class name
207: Handler service = msgContext.getService();
208: String clsName = (String) service
209: .getOption(JOnASEJBProvider.OPTION_SEINTERFACENAME);
210: if (clsName == null) {
211: // We are not in the case of jonas ejb call: do nothing.
212: return;
213: }
214: logger.log(BasicLevel.DEBUG, "*--* Request");
215:
216: // Get ServiceEndpointHome in JNDI
217: String jndiName = (String) service
218: .getOption(JOnASEJBProvider.OPTION_SEJNDINAME);
219: if (jndiName == null) {
220: String msg = i18n.getMessage(
221: "JonasHandler.invoke.noSEJNDI",
222: JOnASEJBProvider.OPTION_SEJNDINAME);
223: logger.log(BasicLevel.ERROR, msg);
224: throw new AxisFault(msg);
225: }
226: JServiceEndpointHome sehome = null;
227: try {
228: InitialContext ic = getCachedContext();
229: sehome = (JServiceEndpointHome) ic.lookup(jndiName);
230: setJServiceEndpointHome(msgContext, sehome);
231: } catch (NamingException ne) {
232: String msg = i18n.getMessage(
233: "JonasHandler.invoke.cannotLookupHome",
234: jndiName);
235: logger.log(BasicLevel.ERROR, msg, ne);
236: throw new AxisFault(msg, ne);
237: }
238:
239: // add the security context
240: String username = msgContext.getUsername();
241: if (username != null) {
242: // Do not forget to initialize the security context
243: SecurityContextHelper.getInstance().login(username,
244: msgContext.getPassword());
245: // Check the security and throw exception if user is not
246: // authorized
247: // to access the EJB before lauching handlers
248: sehome.checkSecurity(msgContext);
249: }
250:
251: // Switch Context on the context of the target bean
252: // (java:comp/env)
253: Context savedCtx = sehome.setCompCtx();
254: setSavedContext(msgContext, savedCtx);
255: if (savedCtx != null) {
256: String msg = i18n.getMessage(
257: "JonasHandler.invoke.savingNonNullCtx",
258: savedCtx);
259: logger.log(BasicLevel.WARN, msg);
260: }
261: // ---------------------------------------------------
262: // /Request
263: }
264: } finally {
265: // restore previous state
266: setCurrentMessageContext(previousContext);
267: }
268: }
269:
270: /**
271: * @param msgContext the MC which will store the Context
272: * @param savedCtx Context to store
273: */
274: private void setSavedContext(MessageContext msgContext,
275: Context savedCtx) {
276: msgContext.setProperty(SE_CONTEXT, savedCtx);
277: }
278:
279: /**
280: * @param msgContext the MC which will store the EndpointHome
281: * @param sehome JServiceEndpointHome to be stored
282: */
283: private void setJServiceEndpointHome(MessageContext msgContext,
284: JServiceEndpointHome sehome) {
285: msgContext.setProperty(SE_HOME, sehome);
286: }
287:
288: /**
289: * @return Returns the cached InitialContext (or created a new one)
290: * @throws javax.naming.NamingException
291: * when InitialContext creation fails
292: */
293: private static InitialContext getCachedContext()
294: throws javax.naming.NamingException {
295: if (cachedContext == null) {
296: cachedContext = new InitialContext();
297: }
298: return cachedContext;
299: }
300: }
|