001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc;
023:
024: import java.lang.reflect.Constructor;
025: import java.lang.reflect.Method;
026: import java.lang.reflect.Modifier;
027: import java.util.*;
028:
029: import org.jboss.ejb.EntityContainer;
030: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
031: import org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler;
032: import org.jboss.ejb.plugins.cmp.bridge.FieldBridge;
033: import org.jboss.ejb.plugins.cmp.bridge.SelectorBridge;
034: import org.jboss.proxy.compiler.Proxy;
035: import org.jboss.proxy.compiler.InvocationHandler;
036: import org.jboss.deployment.DeploymentException;
037:
038: /**
039: * JDBCBeanClassInstanceCommand creates instance of the bean class. For
040: * CMP 2.0 it creates an instance of a subclass of the bean class, as the
041: * bean class is abstract.
042: * <p/>
043: * <FIX-ME>should not generat a subclass for ejb 1.1</FIX-ME>
044: *
045: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
046: * @version $Revision: 57209 $
047: */
048:
049: public final class JDBCCreateBeanClassInstanceCommand {
050: private final JDBCEntityBridge entityBridge;
051: private final Class beanClass;
052: private final Constructor beanProxyConstructor;
053: private final Map fieldMap;
054: private final Map selectorMap;
055:
056: public JDBCCreateBeanClassInstanceCommand(JDBCStoreManager manager)
057: throws Exception {
058: EntityContainer theContainer = manager.getContainer();
059: entityBridge = (JDBCEntityBridge) manager.getEntityBridge();
060: beanClass = theContainer.getBeanClass();
061: fieldMap = createFieldMap();
062: selectorMap = createSelectorMap();
063: // use proxy generator to create one implementation
064: EntityBridgeInvocationHandler handler = new EntityBridgeInvocationHandler(
065: fieldMap, selectorMap, beanClass);
066: Class[] classes = new Class[] { beanClass };
067: ClassLoader classLoader = beanClass.getClassLoader();
068:
069: Object o = Proxy
070: .newProxyInstance(classLoader, classes, handler);
071:
072: // steal the constructor from the object
073: beanProxyConstructor = o.getClass().getConstructor(
074: new Class[] { InvocationHandler.class });
075:
076: // now create one to make sure everything is cool
077: execute();
078: }
079:
080: public void destroy() {
081: Proxy.forgetProxyForClass(beanClass);
082: }
083:
084: public Object execute() throws Exception {
085: EntityBridgeInvocationHandler handler = new EntityBridgeInvocationHandler(
086: fieldMap, selectorMap, beanClass);
087: return beanProxyConstructor
088: .newInstance(new Object[] { handler });
089: }
090:
091: private Map getAbstractAccessors() {
092: Method[] methods = beanClass.getMethods();
093: Map abstractAccessors = new HashMap(methods.length);
094:
095: for (int i = 0; i < methods.length; i++) {
096: if (Modifier.isAbstract(methods[i].getModifiers())) {
097: String methodName = methods[i].getName();
098: if (methodName.startsWith("get")
099: || methodName.startsWith("set")) {
100: abstractAccessors.put(methodName, methods[i]);
101: }
102: }
103: }
104: return abstractAccessors;
105: }
106:
107: private Map createFieldMap() throws DeploymentException {
108: Map abstractAccessors = getAbstractAccessors();
109:
110: List fields = entityBridge.getFields();
111: Map map = new HashMap(fields.size() * 2);
112: for (int i = 0; i < fields.size(); i++) {
113: FieldBridge field = (FieldBridge) fields.get(i);
114:
115: // get the names
116: String fieldName = field.getFieldName();
117: String fieldBaseName = Character.toUpperCase(fieldName
118: .charAt(0))
119: + fieldName.substring(1);
120: String getterName = "get" + fieldBaseName;
121: String setterName = "set" + fieldBaseName;
122:
123: // get the accessor methods
124: Method getterMethod = (Method) abstractAccessors
125: .get(getterName);
126: Method setterMethod = (Method) abstractAccessors
127: .get(setterName);
128:
129: // getters and setters must come in pairs
130: if (getterMethod != null && setterMethod == null) {
131: throw new DeploymentException(
132: "Getter was found but no setter was found for field "
133: + fieldName + " in entity "
134: + entityBridge.getEntityName());
135: } else if (getterMethod == null && setterMethod != null) {
136: throw new DeploymentException(
137: "Setter was found but no getter was found for field "
138: + fieldName + " in entity "
139: + entityBridge.getEntityName());
140: } else if (getterMethod != null && setterMethod != null) {
141: // add methods
142: map
143: .put(
144: getterMethod.getName(),
145: new EntityBridgeInvocationHandler.FieldGetInvoker(
146: field));
147: map
148: .put(
149: setterMethod.getName(),
150: new EntityBridgeInvocationHandler.FieldSetInvoker(
151: field));
152:
153: // remove the accessors (they have been used)
154: abstractAccessors.remove(getterName);
155: abstractAccessors.remove(setterName);
156: }
157: }
158: return Collections.unmodifiableMap(map);
159: }
160:
161: private Map createSelectorMap() {
162: Collection selectors = entityBridge.getSelectors();
163: Map map = new HashMap(selectors.size());
164: for (Iterator iter = selectors.iterator(); iter.hasNext();) {
165: SelectorBridge selector = (SelectorBridge) iter.next();
166: //map.put(selector.getMethod().getName(), selector);
167: map.put(selector.getMethod(), selector);
168: }
169: return Collections.unmodifiableMap(map);
170: }
171: }
|