KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > proxy > ejb > EjbHomeCorbaServant


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.proxy.ejb;
23
24 import java.security.Principal JavaDoc;
25 import java.util.Map JavaDoc;
26 import javax.ejb.HomeHandle JavaDoc;
27 import javax.management.MBeanException JavaDoc;
28 import javax.management.MBeanServer JavaDoc;
29 import javax.management.ObjectName JavaDoc;
30 import javax.transaction.Transaction JavaDoc;
31
32 import org.omg.CORBA.BAD_OPERATION JavaDoc;
33 import org.omg.CORBA.InterfaceDef JavaDoc;
34 import org.omg.CORBA.ORBPackage.InvalidName JavaDoc;
35 import org.omg.CORBA.portable.InvokeHandler JavaDoc;
36 import org.omg.CORBA.portable.InputStream JavaDoc;
37 import org.omg.CORBA.portable.OutputStream JavaDoc;
38 import org.omg.CORBA.portable.ResponseHandler JavaDoc;
39 import org.omg.PortableServer.POA JavaDoc;
40
41 import org.jboss.iiop.CorbaORB;
42 import org.jboss.iiop.csiv2.SASCurrent;
43 import org.jboss.iiop.rmi.RmiIdlUtil;
44 import org.jboss.iiop.rmi.marshal.strategy.SkeletonStrategy;
45 import org.jboss.invocation.Invocation;
46 import org.jboss.invocation.InvocationKey;
47 import org.jboss.invocation.InvocationType;
48 import org.jboss.invocation.PayloadKey;
49 import org.jboss.invocation.iiop.ServantWithMBeanServer;
50 import org.jboss.logging.Logger;
51 import org.jboss.tm.iiop.TxServerInterceptor;
52 import org.jboss.security.SimplePrincipal;
53
54 /**
55  * CORBA servant class for an <code>EJBHome</code>. An instance of this class
56  * "implements" a single <code>EJBHome</code> by forwarding to the bean
57  * container all IIOP invocations on the bean home. Such invocations are routed
58  * through the JBoss <code>MBean</code> server, which delivers them to the
59  * target container.
60  *
61  * @author <a HREF="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
62  * @version $Revision: 37459 $
63  */

64 public class EjbHomeCorbaServant
65       extends ServantWithMBeanServer
66       implements InvokeHandler JavaDoc, LocalIIOPInvoker {
67
68    /**
69     * The <code>MBean</code> name of this servant's container.
70     */

71    private final ObjectName JavaDoc containerName;
72
73    /**
74     * The classloader of this servant's container.
75     */

76    private final ClassLoader JavaDoc containerClassLoader;
77
78    /**
79     * Mapping from home methods to <code>SkeletonStrategy</code> instances.
80     */

81    private final Map JavaDoc methodInvokerMap;
82
83    /**
84     * CORBA repository ids of the RMI-IDL interfaces implemented by the bean's
85     * home (<code>EJBHome</code> instance).
86     */

87    private final String JavaDoc[] repositoryIds;
88
89    /**
90     * CORBA reference to an IR object representing the bean's home interface.
91     */

92    private final InterfaceDef JavaDoc interfaceDef;
93
94    /**
95     * This servant's logger.
96     */

97    private final Logger logger;
98
99    /**
100     * True is the trace logging level is enabled.
101     */

102    private final boolean traceEnabled;
103
104    /**
105     * <code>HomeHandle</code> for the <code>EJBHome</code>
106     * implemented by this servant.
107     */

108    private HomeHandle JavaDoc homeHandle = null;
109
110    /**
111     * A reference to the JBoss <code>MBean</code> server.
112     */

113    private MBeanServer JavaDoc mbeanServer;
114
115    /**
116     * A reference to the SASCurrent, or null if the SAS interceptors are not
117     * installed.
118     */

119    private SASCurrent sasCurrent;
120
121    /**
122     * Constructs an <code>EjbHomeCorbaServant></code>.
123     */

124    public EjbHomeCorbaServant(ObjectName JavaDoc containerName,
125                               ClassLoader JavaDoc containerClassLoader,
126                               Map JavaDoc methodInvokerMap,
127                               String JavaDoc[] repositoryIds,
128                               InterfaceDef JavaDoc interfaceDef,
129                               Logger logger)
130    {
131       this.containerName = containerName;
132       this.containerClassLoader = containerClassLoader;
133       this.methodInvokerMap = methodInvokerMap;
134       this.repositoryIds = repositoryIds;
135       this.interfaceDef = interfaceDef;
136       this.logger = logger;
137       this.traceEnabled = logger.isTraceEnabled();
138       try
139       {
140          this.sasCurrent = (SASCurrent)
141             CorbaORB.getInstance().resolve_initial_references("SASCurrent");
142       }
143       catch (InvalidName JavaDoc invalidName)
144       {
145          this.sasCurrent = null;
146       }
147    }
148
149    public void setHomeHandle(HomeHandle JavaDoc homeHandle)
150    {
151       this.homeHandle = homeHandle;
152    }
153
154    // Implementation of method declared as abstract in the superclass ------
155

156    /**
157     * Sets this servant's <code>MBeanServer</code>.
158     */

159    public void setMBeanServer(MBeanServer JavaDoc mbeanServer)
160    {
161       this.mbeanServer = mbeanServer;
162    }
163    
164    // This method overrides the one in org.omg.PortableServer.Servant ------
165

166    /**
167     * Returns an IR object describing the bean's home interface.
168     */

169    public org.omg.CORBA.Object JavaDoc _get_interface_def()
170    {
171       if (interfaceDef != null)
172          return interfaceDef;
173       else
174          return super._get_interface_def();
175    }
176    
177    // Implementation of org.omg.CORBA.portable.InvokeHandler ---------------
178

179    /**
180     * Returns an array with the CORBA repository ids of the RMI-IDL
181     * interfaces implemented by the container's <code>EJBHome</code>.
182     */

183    public String JavaDoc[] _all_interfaces(POA JavaDoc poa, byte[] objectId)
184    {
185       return (String JavaDoc[])repositoryIds.clone();
186    }
187    
188    /**
189     * Receives IIOP requests to an <code>EJBHome</code> and forwards them to
190     * its container, through the JBoss <code>MBean</code> server.
191     */

192    public OutputStream JavaDoc _invoke(String JavaDoc opName,
193                                InputStream JavaDoc in,
194                                ResponseHandler JavaDoc handler)
195    {
196       if (traceEnabled) {
197          logger.trace("EJBHome invocation: " + opName);
198       }
199       
200       ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
201       Thread.currentThread().setContextClassLoader(containerClassLoader);
202       
203       try {
204          
205          SkeletonStrategy op = (SkeletonStrategy) methodInvokerMap.get(opName);
206          if (op == null) {
207             logger.debug("Unable to find opname '" + opName + "' valid operations:" + methodInvokerMap.keySet());
208             throw new BAD_OPERATION JavaDoc(opName);
209          }
210
211          org.omg.CORBA_2_3.portable.OutputStream JavaDoc out;
212          try {
213             Object JavaDoc retVal;
214             
215             // The EJBHome method getHomeHandle() receives special
216
// treatment because the container does not implement it.
217
// The remaining EJBObject methods (getEJBMetaData,
218
// remove(java.lang.Object), and remove(javax.ejb.Handle))
219
// are forwarded to the container.
220

221             if (opName.equals("_get_homeHandle"))
222             {
223                retVal = homeHandle;
224             }
225             else
226             {
227                Transaction JavaDoc tx = TxServerInterceptor.getCurrentTransaction();
228                SimplePrincipal principal = null;
229                char[] password = null;
230                if (sasCurrent != null)
231                {
232                   byte[] username = sasCurrent.get_incoming_username();
233                   byte[] credential = sasCurrent.get_incoming_password();
234                   String JavaDoc name = new String JavaDoc(username, "UTF-8");
235                   int domainIndex = name.indexOf('@');
236                   if (domainIndex > 0)
237                      name = name.substring(0, domainIndex);
238                   if (name.length() == 0)
239                   {
240                      byte[] incomingName =
241                         sasCurrent.get_incoming_principal_name();
242                      if (incomingName.length > 0)
243                      {
244                         name = new String JavaDoc(incomingName, "UTF-8");
245                         domainIndex = name.indexOf('@');
246                         if (domainIndex > 0)
247                            name = name.substring(0, domainIndex);
248                         principal = new SimplePrincipal(name);
249                         // username==password is a hack until
250
// we have a real way to establish trust
251
password = name.toCharArray();
252                      }
253                   }
254                   else
255                   {
256                      principal = new SimplePrincipal(name);
257                      password = new String JavaDoc(credential, "UTF-8").toCharArray();
258                   }
259                }
260
261                Object JavaDoc[] params = op.readParams(
262                                   (org.omg.CORBA_2_3.portable.InputStream JavaDoc)in);
263                Invocation inv = new Invocation(null,
264                                                op.getMethod(),
265                                                params,
266                                                tx,
267                                                principal, /* identity */
268                                                password /* credential*/);
269                inv.setValue(InvocationKey.INVOKER_PROXY_BINDING,
270                             "iiop",
271                             PayloadKey.AS_IS);
272                inv.setType(InvocationType.HOME);
273                retVal = mbeanServer.invoke(containerName,
274                                            "invoke",
275                                            new Object JavaDoc[] {inv},
276                                            Invocation.INVOKE_SIGNATURE);
277             }
278             out = (org.omg.CORBA_2_3.portable.OutputStream JavaDoc)
279                handler.createReply();
280             if (op.isNonVoid()) {
281                op.writeRetval(out, retVal);
282             }
283          }
284          catch (Exception JavaDoc e) {
285             if (traceEnabled) {
286                logger.trace("Exception in EJBHome invocation", e);
287             }
288             if (e instanceof MBeanException JavaDoc) {
289                e = ((MBeanException JavaDoc)e).getTargetException();
290             }
291             RmiIdlUtil.rethrowIfCorbaSystemException(e);
292             out = (org.omg.CORBA_2_3.portable.OutputStream JavaDoc)
293                handler.createExceptionReply();
294             op.writeException(out, e);
295          }
296          return out;
297       }
298       finally {
299          Thread.currentThread().setContextClassLoader(oldCl);
300       }
301    }
302    
303    // Implementation of the interface LocalIIOPInvoker ---------------------
304

305    /**
306     * Receives intra-VM requests to an <code>EJBHome</code> and forwards them
307     * to its container (through the JBoss <code>MBean</code> server).
308     */

309    public Object JavaDoc invoke(String JavaDoc opName,
310                         Object JavaDoc[] arguments,
311                         Transaction JavaDoc tx,
312                         Principal JavaDoc identity,
313                         Object JavaDoc credential)
314       throws Exception JavaDoc
315    {
316       if (traceEnabled) {
317          logger.trace("EJBHome local invocation: " + opName);
318       }
319       
320       ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
321       Thread.currentThread().setContextClassLoader(containerClassLoader);
322       
323       try {
324          SkeletonStrategy op =
325             (SkeletonStrategy) methodInvokerMap.get(opName);
326          if (op == null) {
327             throw new BAD_OPERATION JavaDoc(opName);
328          }
329          
330          Invocation inv = new Invocation(null,
331                                          op.getMethod(),
332                                          arguments,
333                                          tx,
334                                          null, /* identity */
335                                          null /* credential */);
336          inv.setValue(InvocationKey.INVOKER_PROXY_BINDING,
337                       "iiop",
338                       PayloadKey.AS_IS);
339          inv.setType(InvocationType.HOME);
340          return mbeanServer.invoke(containerName,
341                                    "invoke",
342                                    new Object JavaDoc[] {inv},
343                                    Invocation.INVOKE_SIGNATURE);
344       }
345       catch (MBeanException JavaDoc e) {
346          throw e.getTargetException();
347       }
348       finally {
349          Thread.currentThread().setContextClassLoader(oldCl);
350       }
351    }
352    
353 }
354
Popular Tags