KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > logic > J2EEControllerManager


1 /*
2  * Copyright (c) 2005 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: J2EEControllerManager.java,v 1.11 2007/01/07 06:15:14 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.logic;
23
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.rmi.RemoteException JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30
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.opensubsystems.core.error.OSSException;
37 import org.opensubsystems.core.error.OSSInternalErrorException;
38 import org.opensubsystems.core.util.Log;
39
40 /**
41  * Class responsible for instantiation of j2ee controllers. This class determines
42  * what controller should be used based on currently used component model,
43  * creates the j2ee controller instance if it wasn't created yet and caches created
44  * instances. This of course assumes that the j2ee controllers are implemented to
45  * be stateless and reentrant.
46  *
47  * @version $Id: J2EEControllerManager.java,v 1.11 2007/01/07 06:15:14 bastafidli Exp $
48  * @author Julo Legeny
49  * @code.reviewer Miro Halas
50  * @code.reviewed 1.9 2005/03/01 23:10:47 jlegeny
51  */

52 public class J2EEControllerManager extends ControllerManager
53 {
54    // Cached values ////////////////////////////////////////////////////////////
55

56    /**
57     * Cache where controller classes from processed lookup will be cached.
58     */

59    protected Map JavaDoc m_mpControllerLookupCache = new HashMap JavaDoc();
60
61    /**
62     * Logger for this class
63     */

64    private static Logger JavaDoc s_logger = Log.getInstance(J2EEControllerManager.class);
65
66    // Business logic ///////////////////////////////////////////////////////////
67

68    /**
69     * {@inheritDoc}
70     */

71    public Object JavaDoc getControllerInstance(
72       Class JavaDoc controller
73    ) throws OSSException
74    {
75       Object JavaDoc controlHome = null;
76       Object JavaDoc controlRet = null;
77
78       // Get current name of controller class. This name will be used as the key
79
// to the cached map.
80
StringBuffer JavaDoc currControllerName = new StringBuffer JavaDoc();
81       currControllerName.append(controller.getName());
82
83       // If name of the current controller is contained in the cached map, do not
84
// lookup again, because of performance. In the other case lookup it
85
// and update cached map.
86
controlHome = m_mpControllerLookupCache.get(currControllerName);
87       if (controlHome == null)
88       {
89          synchronized (m_mpControllerLookupCache)
90          {
91             // The home inteface is not cached yet so try to figure out what
92
// home/remote interface to use by trying to look it up
93
StringBuffer JavaDoc sbHomeClassName = new StringBuffer JavaDoc();
94             Class JavaDoc homeClass = null;
95             Context JavaDoc context = null;
96             Object JavaDoc lookupObject = null;
97
98             // TODO: Configure: Right now we always look first local and then remote
99
// but we should make it configurable to always lookup the one we need
100

101             // Prepare construction for the home class name
102
sbHomeClassName.append(currControllerName);
103             sbHomeClassName.insert(sbHomeClassName.lastIndexOf("."), ".impl");
104             // First try to lookup particular JNDI controller name
105
try
106             {
107                context = new InitialContext JavaDoc();
108                // First try local interface since the JNDI name is equals to
109
// the name of the controller interface class
110
lookupObject = context.lookup(currControllerName.toString());
111                // Local lookup was successful, construct name of the LOCAL home
112
// class that will be used for casting
113
sbHomeClassName.append("Home");
114             }
115             catch (NamingException JavaDoc nExc)
116             {
117                // Do not log as WARNING since it may print too much information
118
s_logger.log(Level.FINE,
119                             "Local home of controller is not available at JNDI " +
120                             "location [" + currControllerName.toString() + "]",
121                             nExc);
122
123                // Now try to lookup for remote interface since we couldn't find
124
// the local one (for example for JOnAS at this time we don't know
125
// how to setup local JNDI using xdoclet)
126
try
127                {
128                   // Change JNDI controller name, remote interface has 'Remote'
129
// at the end
130
currControllerName.append("Remote");
131
132                   // By default JNDI names for local interface are suffixed by an _L and you
133
// could see it in jonasAdmin or with : "jonas admin -j" command.
134
// TODO: For Julo: Change this when JOnAS JNDI names for local home interfaces
135
// will be resolved
136
/*
137                   if (J2EEUtils.getJ2EEServerType() == J2EEUtils.J2EE_SERVER_JONAS)
138                   {
139                      currControllerName.append("_L");
140                   }
141                   */

142                   context = new InitialContext JavaDoc();
143                   lookupObject = context.lookup(currControllerName.toString());
144                   // Remote lookup was successful, construct name of the REMOTE
145
// home class that will be used for casting
146
sbHomeClassName.append("RemoteHome");
147                }
148                catch (NamingException JavaDoc nExc1)
149                {
150                   // Do not log as WARNING since it may print too much information
151
s_logger.log(Level.FINE,
152                                "Remote home of controller is not available at JNDI " +
153                                "location [" + currControllerName.toString() + "]",
154                                nExc1);
155
156                   // There is a possibility we are running WAR application and
157
// no EJBs are deployed (they are only present in EAR application).
158
// In this case we just log this exception and we will call
159
// getControllerInstance from the base class to instantiate
160
// controller as POJO
161
controlRet = super.getControllerInstance(controller);
162                }
163             }
164             finally
165             {
166                try
167                {
168                   if (context != null)
169                   {
170                      context.close();
171                   }
172                }
173                catch (NamingException JavaDoc nExc)
174                {
175                   // Do not log as WARNING since it may print too much information
176
s_logger.log(Level.FINE,
177                                "Unable to close context for controller manager",
178                                nExc);
179                }
180             }
181             if (lookupObject != null)
182             {
183                // 2. try to check if home class name is available on the classpath
184
try
185                {
186                   // check if home class exists, this class will be used
187
// to the narrow() method
188
homeClass = Class.forName(sbHomeClassName.toString());
189                }
190                catch (ClassNotFoundException JavaDoc cnfExc)
191                {
192                   // If we could lookup but cannot find class, this is weird
193
// so log it as warning
194
s_logger.log(Level.WARNING,
195                                "Cannot found class for home interface[" +
196                                sbHomeClassName.toString() + "]", cnfExc);
197                }
198
199                if (homeClass != null)
200                {
201                   // 3. call narrow and cache home object from lookup for
202
// potential later usage
203
controlHome = PortableRemoteObject.narrow(lookupObject, homeClass);
204                   m_mpControllerLookupCache.put(currControllerName, controlHome);
205                }
206                else
207                {
208                   // If the EJB classes are not available, we just call
209
// getControllerInstance from the base class to instantiate
210
// controller as POJO
211
controlRet = super.getControllerInstance(controller);
212                }
213             }
214          }
215       }
216
217       // If we are returning controller as EJB, always create new instance
218
if (controlHome != null)
219       {
220          try
221          {
222             // Call create() method of the home interface to create the controller
223
// We have to call it dynamically since we cannot cast to the
224
// appropriate type of the home interface
225
controlRet = controlHome.getClass(
226                             ).getMethod("create", null).invoke(controlHome, null);
227          }
228          catch (NoSuchMethodException JavaDoc nsmExc)
229          {
230             throw new OSSInternalErrorException(
231                          "Cannot found method create() in home interface.", nsmExc);
232          }
233          catch (InvocationTargetException JavaDoc itExc)
234          {
235             throw new OSSInternalErrorException(
236                          "Cannot invoke method create() in home interface.", itExc);
237          }
238          catch (IllegalAccessException JavaDoc iaExc)
239          {
240             throw new OSSInternalErrorException(
241                          "Cannot access method create() in home interface.", iaExc);
242          }
243          try
244          {
245             ((StatelessController)controlRet).constructor();
246          }
247          catch (RemoteException JavaDoc rExc)
248          {
249             // We cannot propagate this exception otherwise XDoclet would generate
250
// the local interface incorrectly since it would include the declared
251
// RemoteException in it (to propagate we would have to declare it)
252
throw new OSSInternalErrorException("Remote error occured", rExc);
253          }
254       }
255
256       return controlRet;
257    }
258 }
259
Popular Tags