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.ArrayList;
038: import java.util.logging.Logger;
039:
040: /**
041: * Configuration for a cmp view.
042: */
043: public class EjbCmpView extends EjbEntityView {
044: private static final Logger log = Log.open(EjbCmpView.class);
045: private static final L10N L = new L10N(EjbCmpView.class);
046:
047: private EjbEntityBean _entityBean;
048:
049: /**
050: * Creates a new entity bean configuration.
051: */
052: public EjbCmpView(EjbEntityBean bean, ArrayList<ApiClass> apiList,
053: String prefix) throws ConfigException {
054: super (bean, apiList, prefix);
055:
056: _entityBean = bean;
057: }
058:
059: /**
060: * Introspects an ejb method.
061: */
062: @Override
063: protected EjbMethod introspectEJBMethod(ApiMethod method)
064: throws ConfigException {
065: String methodName = method.getName();
066: Class[] paramTypes = method.getParameterTypes();
067:
068: if (methodName.startsWith("ejbSelect") && method.isAbstract()) {
069: _entityBean.addStubMethod(method);
070:
071: return null;
072: }
073:
074: return super .introspectEJBMethod(method);
075: }
076:
077: /**
078: * Creates a new business method.
079: */
080: @Override
081: protected EjbMethod createBusinessMethod(ApiMethod apiMethod,
082: ApiMethod implMethod) throws ConfigException {
083: String methodName = implMethod.getName();
084: Class[] paramTypes = implMethod.getParameterTypes();
085:
086: if (methodName.startsWith("get") && methodName.length() > 3
087: && paramTypes.length == 0) {
088: String fieldName = toFieldName(methodName.substring(3));
089:
090: CmpField field = _entityBean.getCmpField(fieldName);
091:
092: if (field != null) {
093: validateCmpMethod(implMethod);
094:
095: if (isLocal()
096: && apiMethod.getExceptionTypes().length != 0) {
097: throw new ConfigException(
098: L
099: .l(
100: "{0}: '{1}' must not throw {2}. Container managed fields and relations must not throw exceptions.",
101: apiMethod
102: .getDeclaringClass()
103: .getName(),
104: EjbBean
105: .getFullMethodName(apiMethod),
106: apiMethod
107: .getExceptionTypes()[0]
108: .getName()));
109: }
110:
111: if (field.isId())
112: return new CmpIdGetter(this , apiMethod, implMethod);
113: else
114: return new CmpGetter(this , apiMethod, implMethod);
115: }
116:
117: CmrRelation rel = _entityBean.getRelation(fieldName);
118:
119: if (rel != null) {
120: validateCmpMethod(implMethod);
121:
122: rel.setHasGetter(true);
123:
124: return rel.createGetter(this , apiMethod, implMethod);
125: }
126:
127: if (!implMethod.isAbstract()) {
128: validateCmpMethod(implMethod);
129:
130: // return new CmpGetter(this, apiMethod, implMethod);
131:
132: return new EjbMethod(this , apiMethod, implMethod);
133: }
134: } else if (methodName.startsWith("get")
135: && methodName.length() > 3 && paramTypes.length == 1) {
136: String fieldName = toFieldName(methodName.substring(3));
137:
138: CmrRelation rel = _entityBean.getRelation(fieldName);
139:
140: if (rel instanceof CmrMap) {
141: CmrMap map = (CmrMap) rel;
142:
143: validateCmpMethod(implMethod);
144:
145: rel.setHasGetter(true);
146:
147: // return new EjbMapGetter(this, apiMethod, implMethod, map);
148: return new CmpGetter(this , apiMethod, implMethod);
149: }
150: } else if (methodName.startsWith("set")
151: && methodName.length() > 3 && paramTypes.length == 1) {
152: String fieldName = toFieldName(methodName.substring(3));
153:
154: CmpField field = _entityBean.getCmpField(fieldName);
155:
156: if (field != null) {
157: validateCmpMethod(implMethod);
158:
159: if (isLocal()
160: && apiMethod.getExceptionTypes().length != 0) {
161: throw new ConfigException(
162: L
163: .l(
164: "{0}: '{1}' must not throw {2}. Container managed fields and relations must not throw exceptions.",
165: _entityBean.getEJBClass()
166: .getName(),
167: EjbBean
168: .getFullMethodName(apiMethod),
169: apiMethod
170: .getExceptionTypes()[0]
171: .getName()));
172: }
173:
174: return new EjbMethod(this , apiMethod, implMethod);
175: }
176:
177: CmrRelation rel = _entityBean.getRelation(fieldName);
178:
179: if (rel instanceof CmrOneToMany) {
180: validateCmpMethod(implMethod);
181:
182: return new CmpCollectionSetter(this , apiMethod,
183: implMethod);
184: // return new CmpRelationGetter(this, apiMethod, implMethod, rel);
185: } else if (rel instanceof CmrManyToOne) {
186: validateCmpMethod(implMethod);
187:
188: CmrManyToOne manyToOne = (CmrManyToOne) rel;
189:
190: return new EjbManyToOneSetMethod(this , apiMethod,
191: implMethod, manyToOne);
192: } else if (rel instanceof CmrManyToMany) {
193: validateCmpMethod(implMethod);
194:
195: return new CmpCollectionSetter(this , apiMethod,
196: implMethod);
197: // return new CmpRelationGetter(this, apiMethod, implMethod, rel);
198: }
199:
200: if (!implMethod.isAbstract()) {
201: validateCmpMethod(implMethod);
202:
203: return new EjbMethod(this , apiMethod, implMethod);
204: } else
205: throw new ConfigException(L.l(
206: "{0}: abstract setter {1}.", implMethod
207: .getDeclaringClass().getName(),
208: getFullMethodName(implMethod)));
209: }
210:
211: return super .createBusinessMethod(apiMethod, implMethod);
212: }
213:
214: protected String toFieldName(String name) {
215: if (name.length() == 0)
216: return "";
217: else if (name.length() == 1)
218: return String
219: .valueOf(Character.toLowerCase(name.charAt(0)));
220: else if (Character.isUpperCase(name.charAt(1)))
221: return name;
222: else
223: return Character.toLowerCase(name.charAt(0))
224: + name.substring(1);
225: }
226:
227: /**
228: * Validate impl method.
229: */
230: protected void validateCmpMethod(ApiMethod implMethod)
231: throws ConfigException {
232: if (!implMethod.isPublic()) {
233: throw error(L
234: .l(
235: "{0}: '{1}' must be public. CMP method implementations must be public.",
236: implMethod.getDeclaringClass().getName(),
237: getFullMethodName(implMethod)));
238: }
239:
240: if (implMethod.isStatic()) {
241: throw error(L
242: .l(
243: "{0}: '{1}' must not be static. CMP method implementations must not be static.",
244: implMethod.getDeclaringClass().getName(),
245: getFullMethodName(implMethod)));
246: }
247: }
248: }
|