KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quartz > jobs > ee > ejb > EJBInvokerJob


1 /*
2  * Copyright 2004-2005 OpenSymphony
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy
6  * of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  *
16  */

17
18 /*
19  * Previously Copyright (c) 2001-2004 James House
20  */

21 package org.quartz.jobs.ee.ejb;
22
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25 import java.rmi.RemoteException JavaDoc;
26 import java.util.Hashtable JavaDoc;
27
28 import javax.ejb.EJBHome JavaDoc;
29 import javax.ejb.EJBMetaData JavaDoc;
30 import javax.ejb.EJBObject JavaDoc;
31 import javax.naming.Context JavaDoc;
32 import javax.naming.InitialContext JavaDoc;
33 import javax.naming.NamingException JavaDoc;
34 import javax.rmi.PortableRemoteObject JavaDoc;
35
36 import org.quartz.Job;
37 import org.quartz.JobDataMap;
38 import org.quartz.JobDetail;
39 import org.quartz.JobExecutionContext;
40 import org.quartz.JobExecutionException;
41
42 /**
43  * <p>
44  * A <code>Job</code> that invokes a method on an EJB.
45  * </p>
46  *
47  * <p>
48  * Expects the properties corresponding to the following keys to be in the
49  * <code>JobDataMap</code> when it executes:
50  * <ul>
51  * <li><code>EJB_JNDI_NAME_KEY</code>- the JNDI name (location) of the
52  * EJB's home interface.</li>
53  * <li><code>EJB_METHOD_KEY</code>- the name of the method to invoke on the
54  * EJB.</li>
55  * <li><code>EJB_ARGS_KEY</code>- an Object[] of the args to pass to the
56  * method (optional, if left out, there are no arguments).</li>
57  * <li><code>EJB_ARG_TYPES_KEY</code>- an Class[] of the types of the args to
58  * pass to the method (optional, if left out, the types will be derived by
59  * calling getClass() on each of the arguments).</li>
60  * </ul>
61  * <br/>
62  * The following keys can also be used at need:
63  * <ul>
64  * <li><code>INITIAL_CONTEXT_FACTORY</code> - the context factory used to
65  * build the context.</li>
66  * <li><code>PROVIDER_URL</code> - the name of the environment property
67  * for specifying configuration information for the service provider to use.
68  * </li>
69  * </ul>
70  * </p>
71  *
72  * <p>
73  * The result of the EJB method invocation will be available to
74  * <code>Job/TriggerListener</code>s via
75  * <code>{@link org.quartz.JobExecutionContext#getResult()}</code>.
76  * </p>
77  *
78  * @author Andrew Collins
79  * @author James House
80  * @author Joel Shellman
81  * @author <a HREF="mailto:bonhamcm@thirdeyeconsulting.com">Chris Bonham</a>
82  */

83 public class EJBInvokerJob implements Job {
84
85     /*
86      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87      *
88      * Constants.
89      *
90      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91      */

92
93     public static final String JavaDoc EJB_JNDI_NAME_KEY = "ejb";
94
95     public static final String JavaDoc EJB_METHOD_KEY = "method";
96
97     public static final String JavaDoc EJB_ARG_TYPES_KEY = "argTypes";
98
99     public static final String JavaDoc EJB_ARGS_KEY = "args";
100     
101     public static final String JavaDoc INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";
102     
103     public static final String JavaDoc PROVIDER_URL = "java.naming.provider.url";
104
105     public static final String JavaDoc PRINCIPAL = "java.naming.security.principal";
106
107     public static final String JavaDoc CREDENTIALS = "java.naming.security.credentials";
108
109
110     /*
111      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112      *
113      * Constructors.
114      *
115      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116      */

117
118     public EJBInvokerJob() {
119         // nothing
120
}
121
122     /*
123      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124      *
125      * Interface.
126      *
127      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128      */

129
130     public void execute(JobExecutionContext context)
131         throws JobExecutionException {
132         JobDetail detail = context.getJobDetail();
133
134         JobDataMap dataMap = context.getMergedJobDataMap();
135
136         String JavaDoc ejb = dataMap.getString(EJB_JNDI_NAME_KEY);
137         String JavaDoc method = dataMap.getString(EJB_METHOD_KEY);
138         Object JavaDoc[] arguments = (Object JavaDoc[]) dataMap.get(EJB_ARGS_KEY);
139         if (arguments == null) {
140             arguments = new Object JavaDoc[0];
141         }
142
143         if (ejb == null) {
144             // must specify remote home
145
throw new JobExecutionException();
146         }
147
148         InitialContext JavaDoc jndiContext = null;
149
150         // get initial context
151
try {
152             jndiContext = getInitialContext(dataMap);
153         } catch (NamingException JavaDoc ne) {
154             throw new JobExecutionException(ne);
155         }
156              
157         try {
158             Object JavaDoc value = null;
159             
160             // locate home interface
161
try {
162                 value = jndiContext.lookup(ejb);
163             } catch (NamingException JavaDoc ne) {
164                 throw new JobExecutionException(ne);
165             }
166     
167             // get home interface
168
EJBHome JavaDoc ejbHome = (EJBHome JavaDoc) PortableRemoteObject.narrow(value,
169                     EJBHome JavaDoc.class);
170     
171             // get meta data
172
EJBMetaData JavaDoc metaData = null;
173     
174             try {
175                 metaData = ejbHome.getEJBMetaData();
176             } catch (RemoteException JavaDoc re) {
177                 throw new JobExecutionException(re);
178             }
179     
180             // get home interface class
181
Class JavaDoc homeClass = metaData.getHomeInterfaceClass();
182     
183             // get remote interface class
184
Class JavaDoc remoteClass = metaData.getRemoteInterfaceClass();
185     
186             // get home interface
187
ejbHome = (EJBHome JavaDoc) PortableRemoteObject.narrow(ejbHome, homeClass);
188     
189             Method JavaDoc methodCreate = null;
190     
191             try {
192                 // create method 'create()' on home interface
193
methodCreate = homeClass.getMethod("create", ((Class JavaDoc[])null));
194             } catch (NoSuchMethodException JavaDoc nsme) {
195                 throw new JobExecutionException(nsme);
196             }
197     
198             // create remote object
199
EJBObject JavaDoc remoteObj = null;
200     
201             try {
202                 // invoke 'create()' method on home interface
203
remoteObj = (EJBObject JavaDoc) methodCreate.invoke(ejbHome, ((Object JavaDoc[])null));
204             } catch (IllegalAccessException JavaDoc iae) {
205                 throw new JobExecutionException(iae);
206             } catch (InvocationTargetException JavaDoc ite) {
207                 throw new JobExecutionException(ite);
208             }
209     
210             // execute user-specified method on remote object
211
Method JavaDoc methodExecute = null;
212     
213             try {
214                 // create method signature
215

216                 Class JavaDoc[] argTypes = (Class JavaDoc[]) dataMap.get(EJB_ARG_TYPES_KEY);
217                 if (argTypes == null) {
218                     argTypes = new Class JavaDoc[arguments.length];
219                     for (int i = 0; i < arguments.length; i++) {
220                         argTypes[i] = arguments[i].getClass();
221                     }
222                 }
223     
224                 // get method on remote object
225
methodExecute = remoteClass.getMethod(method, argTypes);
226             } catch (NoSuchMethodException JavaDoc nsme) {
227                 throw new JobExecutionException(nsme);
228             }
229     
230             try {
231                 // invoke user-specified method on remote object
232
Object JavaDoc returnObj = methodExecute.invoke(remoteObj, arguments);
233                 
234                 // Return any result in the JobExecutionContext so it will be
235
// available to Job/TriggerListeners
236
context.setResult(returnObj);
237             } catch (IllegalAccessException JavaDoc iae) {
238                 throw new JobExecutionException(iae);
239             } catch (InvocationTargetException JavaDoc ite) {
240                 throw new JobExecutionException(ite);
241             }
242         } finally {
243             // Don't close jndiContext until after method execution because
244
// WebLogic requires context to be open to keep the user credentials
245
// available. See JIRA Issue: QUARTZ-401
246
if (jndiContext != null) {
247                 try {
248                     jndiContext.close();
249                 } catch (NamingException JavaDoc e) {
250                     // Ignore any errors closing the initial context
251
}
252             }
253         }
254     }
255
256     private InitialContext JavaDoc getInitialContext(JobDataMap jobDataMap)
257         throws NamingException JavaDoc {
258         Hashtable JavaDoc params = new Hashtable JavaDoc(2);
259         
260         String JavaDoc initialContextFactory =
261             jobDataMap.getString(INITIAL_CONTEXT_FACTORY);
262         if (initialContextFactory != null) {
263             params.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
264         }
265         
266         String JavaDoc providerUrl = jobDataMap.getString(PROVIDER_URL);
267         if (providerUrl != null) {
268             params.put(Context.PROVIDER_URL, providerUrl);
269         }
270
271         String JavaDoc principal = jobDataMap.getString(PRINCIPAL);
272         if ( principal != null ) {
273             params.put( Context.SECURITY_PRINCIPAL, principal );
274         }
275
276         String JavaDoc credentials = jobDataMap.getString(CREDENTIALS);
277         if ( credentials != null ) {
278             params.put( Context.SECURITY_CREDENTIALS, credentials );
279         }
280
281         return (params.size() == 0) ? new InitialContext JavaDoc() : new InitialContext JavaDoc(params);
282     }
283 }
Popular Tags