001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.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: TomcatENCInterceptor.java 1970 2007-10-16 11:49:25Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.naming.interceptors;
025:
026: import java.lang.reflect.InvocationTargetException;
027: import java.lang.reflect.Method;
028:
029: import javax.naming.Context;
030: import javax.naming.NamingException;
031:
032: import org.ow2.easybeans.api.EasyBeansInvocationContext;
033: import org.ow2.easybeans.api.naming.NamingInterceptor;
034:
035: /**
036: * Interceptor used when EasyBeans is integrated in Tomcat. As the java:
037: * namespace is managed by Tomcat, EasyBeans needs to call Tomcat objects in
038: * order to set java: context.
039: * @author Florent Benoit
040: */
041: public class TomcatENCInterceptor implements NamingInterceptor {
042:
043: /**
044: * Tomcat's class for naming.
045: */
046: protected static final String TOMCAT_NAMING_CLASS = "org.apache.naming.ContextBindings";
047:
048: /**
049: * Method used to bind the name associated to a component context for the current thread on the Tomcat naming.
050: */
051: private static Method bindThreadMethod = null;
052:
053: /**
054: * Method used to get the context's name associated to the current thread on the Tomcat naming.
055: */
056: private static Method getThreadNameMethod = null;
057:
058: /**
059: * Method used to unbind the name associated to a context for the current thread on the Tomcat naming.
060: */
061: private static Method unbindThreadMethod = null;
062:
063: /**
064: * Method used to bind the component context for the current thread on the Tomcat naming.
065: */
066: private static Method bindContextMethod = null;
067:
068: /**
069: * Method used to unbind the component context for the current thread on the Tomcat naming.
070: */
071: private static Method unbindContextMethod = null;
072:
073: /**
074: * Default constructor. Gets a reference on the tomcat's naming methods
075: */
076: public TomcatENCInterceptor() {
077: // Get reference on naming manager and its methods.
078: if (bindThreadMethod == null) {
079: String errMsg = "Check that EasyBeans is embedded in Tomcat web server.";
080: Class namingClass = null;
081: try {
082: namingClass = Thread.currentThread()
083: .getContextClassLoader().loadClass(
084: TOMCAT_NAMING_CLASS);
085: } catch (ClassNotFoundException e) {
086: throw new IllegalStateException(
087: "Cannot load the Tomcat naming class '"
088: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
089: e);
090: }
091: // get method (bindThread)
092: try {
093: bindThreadMethod = namingClass.getMethod("bindThread",
094: new Class[] { Object.class });
095: } catch (SecurityException e) {
096: throw new IllegalStateException(
097: "Cannot get bindThread() method on the Tomcat naming class '"
098: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
099: e);
100: } catch (NoSuchMethodException e) {
101: throw new IllegalStateException(
102: "Cannot get bindThread() method on the Tomcat naming class '"
103: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
104: e);
105: }
106:
107: // get method (getThreadName)
108: try {
109: getThreadNameMethod = namingClass.getDeclaredMethod(
110: "getThreadName", new Class[] {});
111: } catch (SecurityException e) {
112: throw new IllegalStateException(
113: "Cannot get getThreadName() method on the Tomcat naming class '"
114: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
115: e);
116: } catch (NoSuchMethodException e) {
117: throw new IllegalStateException(
118: "Cannot get getThreadName() method on the Tomcat naming class '"
119: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
120: e);
121: }
122: getThreadNameMethod.setAccessible(true);
123:
124: // get method (unbindThread)
125: try {
126: unbindThreadMethod = namingClass.getMethod(
127: "unbindThread", new Class[] { Object.class });
128: } catch (SecurityException e) {
129: throw new IllegalStateException(
130: "Cannot get unbindThread() method on the Tomcat naming class '"
131: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
132: e);
133: } catch (NoSuchMethodException e) {
134: throw new IllegalStateException(
135: "Cannot get unbindThread() method on the Tomcat naming class '"
136: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
137: e);
138: }
139:
140: // get method (bindContext)
141: try {
142: bindContextMethod = namingClass.getMethod(
143: "bindContext", new Class[] { Object.class,
144: Context.class });
145: } catch (SecurityException e) {
146: throw new IllegalStateException(
147: "Cannot get bindContext() method on the Tomcat naming class '"
148: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
149: e);
150: } catch (NoSuchMethodException e) {
151: throw new IllegalStateException(
152: "Cannot get bindContext() method on the Tomcat naming class '"
153: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
154: e);
155: }
156:
157: // get method (unbindContext)
158: try {
159: unbindContextMethod = namingClass.getMethod(
160: "unbindContext", new Class[] { Object.class });
161: } catch (SecurityException e) {
162: throw new IllegalStateException(
163: "Cannot get unbindContext() method on the Tomcat naming class '"
164: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
165: e);
166: } catch (NoSuchMethodException e) {
167: throw new IllegalStateException(
168: "Cannot get unbindContext() method on the Tomcat naming class '"
169: + TOMCAT_NAMING_CLASS + "'. " + errMsg,
170: e);
171: }
172:
173: }
174: }
175:
176: /**
177: * Sets JOnAS ENC context.
178: * @param invocationContext context with useful attributes on the current
179: * invocation.
180: * @return result of the next invocation (to chain interceptors).
181: * @throws Exception needs for signature of interceptor.
182: */
183: public Object intercept(
184: final EasyBeansInvocationContext invocationContext)
185: throws Exception {
186:
187: // Current context name associated to this thread
188: Object name = null;
189: try {
190: name = getThreadNameMethod.invoke((Object[]) null);
191: } catch (InvocationTargetException e) {
192: // NamingException if no context is set on this thread
193: if (!(e.getTargetException() instanceof NamingException)) {
194: throw e;
195: }
196: }
197:
198: // Bind the new context name to the current thread
199: bindThreadMethod.invoke(null, invocationContext.getFactory()
200: .getId());
201: try {
202: return invocationContext.proceed();
203: } finally {
204: // Reset
205: if (name != null) {
206: // bind with the previous context name (reset to previous value)
207: bindThreadMethod.invoke(null, name);
208: } else {
209: // unbind value if no previous context name
210: unbindThreadMethod.invoke(null, invocationContext
211: .getFactory().getId());
212: }
213: }
214: }
215:
216: /**
217: * Init the context for the given name.
218: * @param id the id.
219: * @param context the context associated to a factory's id.
220: */
221: public void initContext(final String id, final Context context) {
222: try {
223: bindContextMethod.invoke(null, id, context);
224: } catch (IllegalArgumentException e) {
225: throw new IllegalStateException(
226: "Cannot init the context for the given id '" + id
227: + "'.", e);
228: } catch (IllegalAccessException e) {
229: throw new IllegalStateException(
230: "Cannot init the context for the given id '" + id
231: + "'.", e);
232: } catch (InvocationTargetException e) {
233: throw new IllegalStateException(
234: "Cannot init the context for the given id '" + id
235: + "'.", e);
236: }
237: }
238:
239: /**
240: * Remove the context associated to a given id.
241: * @param id the id.
242: */
243: public void removeContext(final String id) {
244: try {
245: unbindContextMethod.invoke(null, id);
246: } catch (IllegalArgumentException e) {
247: throw new IllegalStateException(
248: "Cannot remove the context for the id '" + id
249: + "'.", e);
250: } catch (IllegalAccessException e) {
251: throw new IllegalStateException(
252: "Cannot remove the context for the id '" + id
253: + "'.", e);
254: } catch (InvocationTargetException e) {
255: throw new IllegalStateException(
256: "Cannot remove the context for the id '" + id
257: + "'.", e);
258: }
259: }
260:
261: }
|