KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > bridge > EntityBridgeInvocationHandler


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.ejb.plugins.cmp.bridge;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import javax.ejb.EJBException JavaDoc;
28 import javax.ejb.FinderException JavaDoc;
29
30 import org.jboss.ejb.EntityEnterpriseContext;
31 import org.jboss.proxy.compiler.InvocationHandler;
32
33 /**
34  * EntityBridgeInvocationHandler is the invocation hander used by the CMP 2.x
35  * dynamic proxy. This class only interacts with the EntityBridge. The main
36  * job of this class is to deligate invocation of abstract methods to the
37  * appropriate EntityBridge method.
38  * <p/>
39  * Life-cycle:
40  * Tied to the life-cycle of an entity bean instance.
41  * <p/>
42  * Multiplicity:
43  * One per cmp entity bean instance, including beans in pool.
44  *
45  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
46  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
47  * @version $Revision: 37459 $
48  */

49 public class EntityBridgeInvocationHandler implements InvocationHandler
50 {
51    private final Class JavaDoc beanClass;
52    private final Map JavaDoc fieldMap;
53    private final Map JavaDoc selectorMap;
54    private EntityEnterpriseContext ctx;
55
56    /**
57     * Creates an invocation handler for the specified entity.
58     */

59    public EntityBridgeInvocationHandler(Map JavaDoc fieldMap, Map JavaDoc selectorMap, Class JavaDoc beanClass)
60    {
61       this.beanClass = beanClass;
62       this.fieldMap = fieldMap;
63       this.selectorMap = selectorMap;
64    }
65
66    public void setContext(EntityEnterpriseContext ctx)
67    {
68       if(ctx != null && !beanClass.isInstance(ctx.getInstance()))
69       {
70          throw new EJBException JavaDoc("Instance must be an instance of beanClass");
71       }
72       this.ctx = ctx;
73    }
74
75    public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args)
76       throws FinderException JavaDoc
77    {
78       // todo find a better workaround
79
// CMP/CMR field bridges are mapped to its abstract method names because of the bug
80
// in reflection introduced in Sun's 1.4 JVM, i.e. when an abstract class C1 extends a super class C2
81
// and implements interface I and C2 and I both declare method with the same signature M,
82
// C1.getMethods() will contain M twice.
83
// ejbSelect methods are mapped to Method objects instead. Because ejbSelect methods having the same name
84
// might have different signatures. Hopefully, the probability of an ejbSelect method to appear in an interface
85
// is lower.
86

87       String JavaDoc methodName = method.getName();
88
89       BridgeInvoker invoker = (BridgeInvoker) fieldMap.get(methodName);
90       if(invoker == null)
91       {
92          //invoker = (BridgeInvoker) selectorMap.get(methodName);
93
invoker = (BridgeInvoker) selectorMap.get(method);
94
95          if(invoker == null)
96          {
97             throw new EJBException JavaDoc("Method is not a known CMP field " +
98                "accessor, CMR field accessor, or ejbSelect method: " +
99                "methodName=" + methodName);
100          }
101       }
102
103       try
104       {
105          return invoker.invoke(ctx, method, args);
106       }
107       catch(RuntimeException JavaDoc e)
108       {
109          throw e;
110       }
111       catch(FinderException JavaDoc e)
112       {
113          throw e;
114       }
115       catch(Exception JavaDoc e)
116       {
117          throw new EJBException JavaDoc("Internal error", e);
118       }
119    }
120
121    // Inner
122

123    public interface BridgeInvoker
124    {
125       Object JavaDoc invoke(EntityEnterpriseContext ctx, Method JavaDoc method, Object JavaDoc[] args) throws FinderException JavaDoc, Exception JavaDoc;
126    }
127
128    public static class FieldGetInvoker implements BridgeInvoker
129    {
130       private final FieldBridge field;
131
132       public FieldGetInvoker(FieldBridge field)
133       {
134          this.field = field;
135       }
136
137       public Object JavaDoc invoke(EntityEnterpriseContext ctx, Method JavaDoc method, Object JavaDoc[] args)
138       {
139          // In the case of ejbHome methods there is no context, but ejb home
140
// methods are only allowed to call selectors.
141
if(ctx == null)
142          {
143             throw new EJBException JavaDoc("EJB home methods are not allowed to " +
144                "access CMP or CMR fields: methodName=" + method.getName());
145          }
146
147          return field.getValue(ctx);
148       }
149    }
150
151    public static class FieldSetInvoker implements BridgeInvoker
152    {
153       private final FieldBridge field;
154
155       public FieldSetInvoker(FieldBridge field)
156       {
157          this.field = field;
158       }
159
160       public Object JavaDoc invoke(EntityEnterpriseContext ctx, Method JavaDoc method, Object JavaDoc[] args)
161       {
162          // In the case of ejbHome methods there is no context, but ejb home
163
// methods are only allowed to call selectors.
164
if(ctx == null)
165          {
166             throw new EJBException JavaDoc("EJB home methods are not allowed to " +
167                "access CMP or CMR fields: methodName=" + method.getName());
168          }
169
170          field.setValue(ctx, args[0]);
171          return null;
172       }
173    }
174 }
175
Popular Tags