001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.ejb.cfg21;
031:
032: import com.caucho.ejb.cfg.*;
033: import com.caucho.config.ConfigException;
034: import com.caucho.log.Log;
035: import com.caucho.util.L10N;
036:
037: import java.util.logging.Logger;
038: import java.lang.reflect.*;
039:
040: /**
041: * Configuration for a particular view.
042: */
043: public class EjbEntityHomeView extends EjbHomeView {
044: private static final Logger log = Log.open(EjbEntityHomeView.class);
045: private static final L10N L = new L10N(EjbEntityHomeView.class);
046:
047: private boolean _hasFindByPrimaryKey;
048:
049: /**
050: * Creates a new entity bean configuration.
051: */
052: public EjbEntityHomeView(EjbBean bean, ApiClass apiClass,
053: String prefix) throws ConfigException {
054: super (bean, apiClass, prefix);
055: }
056:
057: protected boolean isCMP() {
058: return ((EjbEntityBean) getBean()).isCMP();
059: }
060:
061: /**
062: * Introspects the bean's methods.
063: */
064: protected void introspect() throws ConfigException {
065: super .introspect();
066:
067: if (!_hasFindByPrimaryKey)
068: throw new ConfigException(
069: L
070: .l(
071: "{0}: expected 'findByPrimaryKey'. All entity homes must define findByPrimaryKey.",
072: getApiClass().getName()));
073: }
074:
075: /**
076: * Introspects an ejb method.
077: */
078: protected EjbMethod introspectEJBMethod(ApiMethod method)
079: throws ConfigException {
080: String methodName = method.getName();
081: Class[] paramTypes = method.getParameterTypes();
082:
083: if (methodName.startsWith("ejbCreate")) {
084: String apiMethodName = "c" + methodName.substring(4);
085:
086: ApiMethod apiMethod = getApiClass().getMethod(
087: apiMethodName, paramTypes);
088:
089: if (apiMethod == null) {
090: /*
091: validateNonFinalMethod(method.getName(), method.getParameterTypes());
092: if (! isPrimaryKeyClass(method.getReturnType()))
093: throw error(L.l("{0}: '{1}' must return '{2}'. ejbCreate methods must return the primary key.",
094: method.getDeclaringClass().getName(),
095: getFullMethodName(method),
096: getClassName(primKeyClass)));
097: if (isCMP())
098: validateException(method, CreateException.class);
099: */
100: // XXX: should be fatal?
101: log.config(errorMissingMethod(getApiClass(),
102: apiMethodName, method).getMessage());
103: return null;
104: }
105:
106: String postMethodName = "ejbPost" + methodName.substring(3);
107:
108: ApiMethod postCreateMethod = getImplClass().getMethod(
109: postMethodName, method.getParameterTypes());
110:
111: return new EjbEntityCreateMethod(this , apiMethod, method,
112: postCreateMethod);
113: } else if (methodName.startsWith("ejbFind")) {
114: /*
115: if (isCMP()) {
116: throw new ConfigException(L.l("{0}: '{1}' is not allowed. CMP beans can not define ejbFind method implementations.",
117: method.getDeclaringClass().getName(),
118: getFullMethodName(method)));
119: }
120: */
121:
122: if (methodName.equals("ejbFindByPrimaryKey")) {
123: _hasFindByPrimaryKey = true;
124:
125: ApiClass primKeyClass = ((EjbEntityBean) getBean())
126: .getPrimKeyClass();
127:
128: if (paramTypes.length != 1
129: || !paramTypes[0].equals(primKeyClass
130: .getJavaClass()))
131: throw error(L
132: .l(
133: "{0}: '{1}' expected as only argument of {2}. ejbFindByPrimaryKey must take the primary key as its only argument.",
134: method.getDeclaringClass()
135: .getName(), primKeyClass
136: .getName(), methodName));
137: }
138:
139: String apiMethodName = "f" + methodName.substring(4);
140:
141: ApiMethod apiMethod = EjbBean.getMethod(getApiClass(),
142: apiMethodName, paramTypes);
143:
144: if (apiMethod != null)
145: return new EjbEntityFindMethod(this , apiMethod, method);
146: } else if (methodName.startsWith("ejbHome")) {
147: // XXX: test for "ejbHome"
148: String apiMethodName = (Character.toLowerCase(methodName
149: .charAt(7)) + methodName.substring(8));
150:
151: ApiMethod apiMethod = EjbBean.getMethod(getApiClass(),
152: apiMethodName, paramTypes);
153:
154: if (apiMethod == null) {
155: log.config(errorMissingMethod(getApiClass(),
156: apiMethodName, method).getMessage());
157: return null;
158: }
159:
160: validateImplMethod(method);
161:
162: return new EjbMethod(this , apiMethod, method);
163: }
164:
165: return null;
166: }
167:
168: /**
169: * Introspects an ejb method.
170: */
171: protected EjbMethod introspectApiMethod(ApiMethod apiMethod)
172: throws ConfigException {
173: String methodName = apiMethod.getName();
174: Class[] paramTypes = apiMethod.getParameterTypes();
175:
176: if (methodName.equals("findByPrimaryKey")) {
177: _hasFindByPrimaryKey = true;
178:
179: ApiClass primKeyClass = ((EjbEntityBean) getBean())
180: .getPrimKeyClass();
181:
182: if (paramTypes.length != 1
183: || !paramTypes[0].equals(primKeyClass
184: .getJavaClass()))
185: throw error(L
186: .l(
187: "{0}: '{1}' expected as only argument of {2}. findByPrimaryKey must take the primary key as its only argument.",
188: apiMethod.getDeclaringClass().getName(),
189: primKeyClass.getName(), methodName));
190:
191: return new EjbEntityFindMethod(this , apiMethod);
192: } else if (methodName.startsWith("find")) {
193: if (isCMP()) {
194: EjbMethodPattern pattern = findMethodPattern(apiMethod,
195: getPrefix());
196:
197: if (pattern == null)
198: throw error(L
199: .l(
200: "{0}: '{1}' expects an ejb-ql query. All find methods need queries defined in the EJB deployment descriptor.",
201: apiMethod.getDeclaringClass()
202: .getName(),
203: getFullMethodName(apiMethod)));
204:
205: String query = pattern.getQuery();
206:
207: EjbAmberFindMethod findMethod;
208: findMethod = new EjbAmberFindMethod(this , apiMethod,
209: query, pattern.getQueryLocation());
210:
211: findMethod.setQueryLoadsBean(pattern
212: .getQueryLoadsBean());
213:
214: return findMethod;
215: }
216:
217: String name = methodName;
218: name = Character.toUpperCase(name.charAt(0))
219: + name.substring(1);
220:
221: throw errorMissingMethod(getImplClass(), "ejb" + name,
222: apiMethod);
223: } else if (methodName.startsWith("create")) {
224: String name = apiMethod.getName();
225:
226: name = Character.toUpperCase(name.charAt(0))
227: + name.substring(1);
228:
229: throw errorMissingMethod(getImplClass(), "ejb" + name,
230: apiMethod);
231: } else if (methodName.startsWith("ejb")) {
232: throw new ConfigException(
233: L
234: .l(
235: "{0}: '{1}' forbidden. ejbXXX methods are reserved by the EJB specification.",
236: apiMethod.getDeclaringClass()
237: .getName(),
238: getFullMethodName(apiMethod)));
239: } else if (methodName.startsWith("remove")) {
240: throw new ConfigException(
241: L
242: .l(
243: "{0}: '{1}' forbidden. removeXXX methods are reserved by the EJB specification.",
244: apiMethod.getDeclaringClass()
245: .getName(),
246: getFullMethodName(apiMethod)));
247: } else {
248: String name = apiMethod.getName();
249:
250: name = Character.toUpperCase(name.charAt(0))
251: + name.substring(1);
252:
253: throw errorMissingMethod(getImplClass(), "ejbHome" + name,
254: apiMethod);
255: }
256: }
257: }
|