KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc2 > InstanceFactory


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.jdbc2;
23
24 import org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler;
25 import org.jboss.ejb.plugins.cmp.bridge.FieldBridge;
26 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
27 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.EJBSelectBridge;
28 import org.jboss.ejb.plugins.cmp.jdbc2.schema.Schema;
29 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData;
30 import org.jboss.ejb.EntityContainer;
31 import org.jboss.proxy.compiler.Proxy;
32 import org.jboss.proxy.compiler.InvocationHandler;
33 import org.jboss.deployment.DeploymentException;
34
35 import javax.ejb.FinderException JavaDoc;
36 import java.lang.reflect.Constructor JavaDoc;
37 import java.lang.reflect.Method JavaDoc;
38 import java.lang.reflect.Modifier JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Collections JavaDoc;
43 import java.util.Iterator JavaDoc;
44 import java.util.Collection JavaDoc;
45
46
47 /**
48  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
49  * @version <tt>$Revision: 37459 $</tt>
50  */

51 public class InstanceFactory
52 {
53    private final Class JavaDoc beanClass;
54    private final Constructor JavaDoc beanProxyConstructor;
55    private final Map JavaDoc fieldMap;
56    private final Map JavaDoc selectorMap;
57
58    public InstanceFactory(JDBCStoreManager2 manager, JDBCEntityBridge2 entity)
59       throws Exception JavaDoc
60    {
61       EntityContainer theContainer = manager.getContainer();
62       beanClass = theContainer.getBeanClass();
63       fieldMap = createFieldMap(entity);
64       selectorMap = createSelectorMap(entity, manager.getQueryFactory());
65       // use proxy generator to create one implementation
66
EntityBridgeInvocationHandler handler = new EntityBridgeInvocationHandler(fieldMap, selectorMap, beanClass);
67       Class JavaDoc[] classes = new Class JavaDoc[]{beanClass};
68       ClassLoader JavaDoc classLoader = beanClass.getClassLoader();
69
70       Object JavaDoc o = Proxy.newProxyInstance(classLoader, classes, handler);
71
72       // steal the constructor from the object
73
beanProxyConstructor = o.getClass().getConstructor(new Class JavaDoc[]{InvocationHandler.class});
74
75       // now create one to make sure everything is cool
76
newInstance();
77    }
78
79    public void destroy()
80    {
81       Proxy.forgetProxyForClass(beanClass);
82    }
83
84    public Object JavaDoc newInstance() throws Exception JavaDoc
85    {
86       EntityBridgeInvocationHandler handler = new EntityBridgeInvocationHandler(fieldMap, selectorMap, beanClass);
87       return beanProxyConstructor.newInstance(new Object JavaDoc[]{handler});
88    }
89
90    private static Map JavaDoc getAbstractAccessors(Class JavaDoc beanClass)
91    {
92       Method JavaDoc[] methods = beanClass.getMethods();
93       Map JavaDoc abstractAccessors = new HashMap JavaDoc(methods.length);
94
95       for(int i = 0; i < methods.length; i++)
96       {
97          if(Modifier.isAbstract(methods[i].getModifiers()))
98          {
99             String JavaDoc methodName = methods[i].getName();
100             if(methodName.startsWith("get") || methodName.startsWith("set"))
101             {
102                abstractAccessors.put(methodName, methods[i]);
103             }
104          }
105       }
106       return abstractAccessors;
107    }
108
109    private static Map JavaDoc createFieldMap(JDBCEntityBridge2 entityBridge) throws DeploymentException
110    {
111       Map JavaDoc abstractAccessors = getAbstractAccessors(entityBridge.getMetaData().getEntityClass());
112
113       List JavaDoc fields = entityBridge.getFields();
114       Map JavaDoc map = new HashMap JavaDoc(fields.size() * 2);
115       for(int i = 0; i < fields.size(); i++)
116       {
117          FieldBridge field = (FieldBridge) fields.get(i);
118
119          // get the names
120
String JavaDoc fieldName = field.getFieldName();
121          String JavaDoc fieldBaseName = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
122          String JavaDoc getterName = "get" + fieldBaseName;
123          String JavaDoc setterName = "set" + fieldBaseName;
124
125          // get the accessor methods
126
Method JavaDoc getterMethod = (Method JavaDoc) abstractAccessors.get(getterName);
127          Method JavaDoc setterMethod = (Method JavaDoc) abstractAccessors.get(setterName);
128
129          // getters and setters must come in pairs
130
if(getterMethod != null && setterMethod == null)
131          {
132             throw new DeploymentException("Getter was found but, no setter was found for field: " + fieldName);
133          }
134          else if(getterMethod == null && setterMethod != null)
135          {
136             throw new DeploymentException("Setter was found but, no getter was found for field: " + fieldName);
137          }
138          else if(getterMethod != null && setterMethod != null)
139          {
140             // add methods
141
map.put(getterMethod.getName(), new EntityBridgeInvocationHandler.FieldGetInvoker(field));
142             map.put(setterMethod.getName(), new EntityBridgeInvocationHandler.FieldSetInvoker(field));
143
144             // remove the accessors (they have been used)
145
abstractAccessors.remove(getterName);
146             abstractAccessors.remove(setterName);
147          }
148       }
149       return Collections.unmodifiableMap(map);
150    }
151
152    private static Map JavaDoc createSelectorMap(JDBCEntityBridge2 entityBridge, QueryFactory queryFactory)
153       throws DeploymentException
154    {
155       Collection JavaDoc queries = entityBridge.getMetaData().getQueries();
156       Map JavaDoc selectorsByMethod = new HashMap JavaDoc(queries.size());
157       Iterator JavaDoc definedFinders = queries.iterator();
158       while(definedFinders.hasNext())
159       {
160          JDBCQueryMetaData metadata = (JDBCQueryMetaData)definedFinders.next();
161          if(metadata.getMethod().getName().startsWith("ejbSelect"))
162          {
163             try
164             {
165                QueryCommand queryCommand = queryFactory.getQueryCommand(metadata.getMethod());
166                Schema schema = ((JDBCStoreManager2)entityBridge.getManager()).getSchema();
167                EJBSelectBridge ejbSelectBridge = new EJBSelectBridge(entityBridge.getContainer(), schema, metadata, queryCommand);
168                selectorsByMethod.put(metadata.getMethod(), ejbSelectBridge);
169             }
170             catch(FinderException JavaDoc e)
171             {
172                throw new DeploymentException(e.getMessage());
173             }
174          }
175       }
176
177       return selectorsByMethod;
178    }
179 }
180
Popular Tags