KickJava   Java API By Example, From Geeks To Geeks.

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


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.management.MBeanException JavaDoc;
27 import javax.management.MBeanServer JavaDoc;
28 import javax.management.ObjectName JavaDoc;
29 import javax.transaction.Transaction JavaDoc;
30
31 import org.omg.CORBA.BAD_OPERATION JavaDoc;
32 import org.omg.CORBA.InterfaceDef JavaDoc;
33 import org.omg.CORBA.ORBPackage.InvalidName JavaDoc;
34 import org.omg.CORBA.portable.InvokeHandler JavaDoc;
35 import org.omg.CORBA.portable.InputStream JavaDoc;
36 import org.omg.CORBA.portable.OutputStream JavaDoc;
37 import org.omg.CORBA.portable.ResponseHandler JavaDoc;
38 import org.omg.CORBA.portable.UnknownException JavaDoc;
39 import org.omg.PortableServer.Current JavaDoc;
40 import org.omg.PortableServer.POA JavaDoc;
41
42 import org.jboss.iiop.CorbaORB;
43 import org.jboss.iiop.csiv2.SASCurrent;
44 import org.jboss.iiop.rmi.RmiIdlUtil;
45 import org.jboss.iiop.rmi.marshal.strategy.SkeletonStrategy;
46 import org.jboss.invocation.Invocation;
47 import org.jboss.invocation.InvocationKey;
48 import org.jboss.invocation.InvocationType;
49 import org.jboss.invocation.PayloadKey;
50 import org.jboss.invocation.iiop.ReferenceData;
51 import org.jboss.invocation.iiop.ServantWithMBeanServer;
52 import org.jboss.logging.Logger;
53 import org.jboss.tm.iiop.TxServerInterceptor;
54 import org.jboss.security.SimplePrincipal;
55
56
57 /**
58  * CORBA servant class for the <code>EJBObject</code>s of a given bean. An
59  * instance of this class "implements" the bean's set of <code>EJBObject</code>
60  * instances by forwarding to the bean container all IIOP invocations on any
61  * of the bean's <code>EJBObject</code>s. Such invocations are routed through
62  * the JBoss <code>MBean</code> server, which delivers them to the target
63  * container.
64  *
65  * @author <a HREF="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
66  * @version $Revision: 37459 $
67  */

68 public class EjbObjectCorbaServant
69    extends ServantWithMBeanServer
70    implements InvokeHandler JavaDoc, LocalIIOPInvoker
71 {
72
73    /**
74     * The <code>MBean</code> name of this servant's container.
75     */

76    private final ObjectName JavaDoc containerName;
77
78    /**
79     * The classloader of this servant's container.
80     */

81    private final ClassLoader JavaDoc containerClassLoader;
82
83    /**
84     * Thread-local <code>Current</code> object from which we get the target oid
85     * in an incoming IIOP request.
86     */

87    private final Current JavaDoc poaCurrent;
88
89    /**
90     * Mapping from bean methods to <code>SkeletonStrategy</code> instances.
91     */

92    private final Map JavaDoc methodInvokerMap;
93
94    /**
95     * CORBA repository ids of the RMI-IDL interfaces implemented by the bean
96     * (<code>EJBObject</code> instance).
97     */

98    private final String JavaDoc[] repositoryIds;
99
100    /**
101     * CORBA reference to an IR object representing the bean's remote interface.
102     */

103    private final InterfaceDef JavaDoc interfaceDef;
104
105    /**
106     * This servant's logger.
107     */

108    private final Logger logger;
109
110    /**
111     * True is the trace logging level is enabled.
112     */

113    private final boolean traceEnabled;
114
115    /**
116     * A reference to the JBoss <code>MBean</code> server.
117     */

118    private MBeanServer JavaDoc mbeanServer;
119
120    /**
121     * A reference to the SASCurrent, or null if the SAS interceptors are not
122     * installed.
123     */

124    private SASCurrent sasCurrent;
125
126    /**
127     * Constructs an <code>EjbObjectCorbaServant></code>.
128     */

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

158    /**
159     * Sets this servant's <code>MBeanServer</code>.
160     */

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

168    /**
169     * Returns an IR object describing the bean's remote interface.
170     */

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

181    /**
182     * Returns an array with the CORBA repository ids of the RMI-IDL interfaces
183     * implemented by this servant's <code>EJBObject</code>s.
184     */

185    public String JavaDoc[] _all_interfaces(POA JavaDoc poa, byte[] objectId)
186    {
187       return (String JavaDoc[]) repositoryIds.clone();
188    }
189
190    /**
191     * Receives IIOP requests to this servant's <code>EJBObject</code>s
192     * and forwards them to the bean container, through the JBoss
193     * <code>MBean</code> server.
194     */

195    public OutputStream JavaDoc _invoke(String JavaDoc opName,
196       InputStream JavaDoc in,
197       ResponseHandler JavaDoc handler)
198    {
199
200       if (traceEnabled)
201       {
202          logger.trace("EJBObject invocation: " + opName);
203       }
204
205       ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
206       Thread.currentThread().setContextClassLoader(containerClassLoader);
207       try
208       {
209          SkeletonStrategy op = (SkeletonStrategy) methodInvokerMap.get(opName);
210          if (op == null)
211          {
212             logger.debug("Unable to find opname '" + opName + "' valid operations:" + methodInvokerMap.keySet());
213             throw new BAD_OPERATION JavaDoc(opName);
214          }
215
216          Object JavaDoc id;
217          try
218          {
219             id = ReferenceData.extractObjectId(poaCurrent.get_object_id());
220             if (traceEnabled && id != null)
221                logger.trace(" id class is "
222                   + id.getClass().getName());
223          }
224          catch (Exception JavaDoc e)
225          {
226             logger.error("Error getting EJBObject id", e);
227             throw new UnknownException JavaDoc(e);
228          }
229
230          org.omg.CORBA_2_3.portable.OutputStream JavaDoc out;
231          try
232          {
233             Object JavaDoc retVal;
234
235             if (opName.equals("_get_handle"))
236             {
237                retVal = new HandleImplIIOP(_this_object());
238             }
239             else
240             {
241                Transaction JavaDoc tx = TxServerInterceptor.getCurrentTransaction();
242                SimplePrincipal principal = null;
243                char[] password = null;
244                if (sasCurrent != null)
245                {
246                   byte[] username = sasCurrent.get_incoming_username();
247                   byte[] credential = sasCurrent.get_incoming_password();
248                   String JavaDoc name = new String JavaDoc(username, "UTF-8");
249                   int domainIndex = name.indexOf('@');
250                   if (domainIndex > 0)
251                      name = name.substring(0, domainIndex);
252                   if (name.length() == 0)
253                   {
254                      byte[] incomingName =
255                         sasCurrent.get_incoming_principal_name();
256                      if (incomingName.length > 0)
257                      {
258                         name = new String JavaDoc(incomingName, "UTF-8");
259                         domainIndex = name.indexOf('@');
260                         if (domainIndex > 0)
261                            name = name.substring(0, domainIndex);
262                         principal = new SimplePrincipal(name);
263                         // username==password is a hack until
264
// we have a real way to establish trust
265
password = name.toCharArray();
266                      }
267                   }
268                   else
269                   {
270                      principal = new SimplePrincipal(name);
271                      password = new String JavaDoc(credential, "UTF-8").toCharArray();
272                   }
273
274                }
275                Object JavaDoc[] params =
276                   op.readParams((org.omg.CORBA_2_3.portable.InputStream JavaDoc) in);
277                Invocation inv = new Invocation(id,
278                   op.getMethod(),
279                   params,
280                   tx,
281                   principal, /* identity */
282                   password /* credential */);
283                inv.setValue(InvocationKey.INVOKER_PROXY_BINDING,
284                   "iiop",
285                   PayloadKey.AS_IS);
286                inv.setType(InvocationType.REMOTE);
287                retVal = mbeanServer.invoke(containerName,
288                   "invoke",
289                   new Object JavaDoc[]{inv},
290                   Invocation.INVOKE_SIGNATURE);
291
292             }
293             out = (org.omg.CORBA_2_3.portable.OutputStream JavaDoc)
294                handler.createReply();
295             if (op.isNonVoid())
296             {
297                op.writeRetval(out, retVal);
298             }
299          }
300          catch (Exception JavaDoc e)
301          {
302             if (traceEnabled)
303             {
304                logger.trace("Exception in EJBObject invocation", e);
305             }
306             if (e instanceof MBeanException JavaDoc)
307             {
308                e = ((MBeanException JavaDoc) e).getTargetException();
309             }
310             RmiIdlUtil.rethrowIfCorbaSystemException(e);
311             out = (org.omg.CORBA_2_3.portable.OutputStream JavaDoc)
312                handler.createExceptionReply();
313             op.writeException(out, e);
314          }
315          return out;
316       }
317       finally
318       {
319          Thread.currentThread().setContextClassLoader(oldCl);
320       }
321    }
322    
323    // Implementation of the interface LocalIIOPInvoker ------------------------
324

325    /**
326     * Receives intra-VM invocations on this servant's <code>EJBObject</code>s
327     * and forwards them to the bean container, through the JBoss
328     * <code>MBean</code>
329     * server.
330     */

331    public Object JavaDoc invoke(String JavaDoc opName,
332       Object JavaDoc[] arguments,
333       Transaction JavaDoc tx,
334       Principal JavaDoc identity,
335       Object JavaDoc credential)
336       throws Exception JavaDoc
337    {
338       if (traceEnabled)
339       {
340          logger.trace("EJBObject local invocation: " + opName);
341       }
342
343       ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
344       Thread.currentThread().setContextClassLoader(containerClassLoader);
345
346       try
347       {
348          SkeletonStrategy op = (SkeletonStrategy) methodInvokerMap.get(opName);
349          if (op == null)
350          {
351             throw new BAD_OPERATION JavaDoc(opName);
352          }
353
354          Object JavaDoc id;
355          try
356          {
357             id = ReferenceData.extractObjectId(poaCurrent.get_object_id());
358             if (traceEnabled && id != null)
359             {
360                logger.trace(" id class is "
361                             + id.getClass().getName());
362             }
363          }
364          catch (Exception JavaDoc e)
365          {
366             logger.error("Error getting EJBObject id", e);
367             throw new UnknownException JavaDoc(e);
368          }
369
370          Invocation inv = new Invocation(id,
371             op.getMethod(),
372             arguments,
373             tx,
374             null, /* identity */
375             null /* credential */);
376          inv.setValue(InvocationKey.INVOKER_PROXY_BINDING,
377             "iiop",
378             PayloadKey.AS_IS);
379          inv.setType(InvocationType.REMOTE);
380          return mbeanServer.invoke(containerName,
381             "invoke",
382             new Object JavaDoc[]{inv},
383             Invocation.INVOKE_SIGNATURE);
384       }
385       catch (MBeanException JavaDoc e)
386       {
387          throw e.getTargetException();
388       }
389       finally
390       {
391          Thread.currentThread().setContextClassLoader(oldCl);
392       }
393    }
394
395 }
396
Popular Tags