0001: /*
0002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003: *
0004: * This file is part of Resin(R) Open Source
0005: *
0006: * Each copy or derived work must preserve the copyright notice and this
0007: * notice unmodified.
0008: *
0009: * Resin Open Source is free software; you can redistribute it and/or modify
0010: * it under the terms of the GNU General Public License as published by
0011: * the Free Software Foundation; either version 2 of the License, or
0012: * (at your option) any later version.
0013: *
0014: * Resin Open Source is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017: * of NON-INFRINGEMENT. See the GNU General Public License for more
0018: * details.
0019: *
0020: * You should have received a copy of the GNU General Public License
0021: * along with Resin Open Source; if not, write to the
0022: *
0023: * Free Software Foundation, Inc.
0024: * 59 Temple Place, Suite 330
0025: * Boston, MA 02111-1307 USA
0026: *
0027: * @author Scott Ferguson
0028: */
0029:
0030: package com.caucho.ejb.cfg;
0031:
0032: import com.caucho.ejb.cfg21.EjbHomeView;
0033: import com.caucho.bytecode.*;
0034: import com.caucho.config.program.ConfigProgram;
0035: import com.caucho.config.program.ContainerProgram;
0036: import com.caucho.config.ConfigException;
0037: import com.caucho.config.LineConfigException;
0038: import com.caucho.config.DependencyBean;
0039: import com.caucho.config.types.*;
0040: import com.caucho.ejb.AbstractServer;
0041: import com.caucho.ejb.amber.AmberConfig;
0042: import com.caucho.ejb.gen.*;
0043: import com.caucho.ejb.gen21.BeanAssembler;
0044: import com.caucho.ejb.gen21.ViewClass;
0045: import com.caucho.ejb.manager.EjbContainer;
0046: import com.caucho.java.gen.BaseClass;
0047: import com.caucho.java.gen.BaseMethod;
0048: import com.caucho.java.gen.CallChain;
0049: import com.caucho.java.gen.GenClass;
0050: import com.caucho.java.gen.JavaClassGenerator;
0051: import com.caucho.java.gen.MethodCallChain;
0052: import com.caucho.loader.EnvironmentBean;
0053: import com.caucho.loader.EnvironmentLocal;
0054: import com.caucho.make.ClassDependency;
0055: import com.caucho.util.L10N;
0056: import com.caucho.vfs.Depend;
0057: import com.caucho.vfs.Path;
0058: import com.caucho.vfs.PersistentDependency;
0059: import com.caucho.vfs.Vfs;
0060:
0061: import javax.annotation.PostConstruct;
0062: import javax.ejb.*;
0063: import javax.interceptor.*;
0064: import java.lang.annotation.Annotation;
0065: import java.lang.ref.SoftReference;
0066: import java.util.ArrayList;
0067: import java.util.HashMap;
0068: import java.util.Map;
0069: import java.util.logging.Level;
0070: import java.util.logging.Logger;
0071: import java.lang.reflect.*;
0072:
0073: /**
0074: * Configuration for an ejb bean.
0075: */
0076: public class EjbBean extends DescriptionGroupConfig implements
0077: EnvironmentBean, DependencyBean {
0078: private static Logger log = Logger.getLogger(EjbBean.class
0079: .getName());
0080: private static L10N L = new L10N(EjbBean.class);
0081:
0082: private static EnvironmentLocal<Map<Class, SoftReference<ApiMethod[]>>> _methodCache = new EnvironmentLocal<Map<Class, SoftReference<ApiMethod[]>>>();
0083:
0084: private final EjbConfig _ejbConfig;
0085: private final String _ejbModuleName;
0086:
0087: private ClassLoader _loader;
0088:
0089: protected ClassLoader _jClassLoader;
0090:
0091: private String _ejbName;
0092:
0093: // The published name as used by IIOP, Hessian, and
0094: // jndi-remote-prefix/jndi-local-prefix
0095: private String _mappedName;
0096:
0097: private String _location = "";
0098: private String _filename;
0099: private int _line;
0100:
0101: private boolean _isInit; // used for error messsage line #
0102:
0103: // these classes are loaded with the parent (configuration) loader, not
0104: // the server loader
0105: private ApiClass _ejbClass;
0106:
0107: protected ApiClass _remoteHome;
0108:
0109: protected ArrayList<ApiClass> _remoteList = new ArrayList<ApiClass>();
0110:
0111: protected ApiClass _localHome;
0112:
0113: protected ArrayList<ApiClass> _localList = new ArrayList<ApiClass>();
0114:
0115: protected BeanGenerator _bean;
0116:
0117: private boolean _isAllowPOJO = true;
0118:
0119: protected boolean _isContainerTransaction = true;
0120:
0121: ArrayList<PersistentDependency> _dependList = new ArrayList<PersistentDependency>();
0122:
0123: ArrayList<PersistentDependency> _configDependList = new ArrayList<PersistentDependency>();
0124:
0125: ArrayList<String> _beanDependList = new ArrayList<String>();
0126:
0127: protected ArrayList<EjbMethodPattern> _methodList = new ArrayList<EjbMethodPattern>();
0128:
0129: private HashMap<String, EjbBaseMethod> _methodMap = new HashMap<String, EjbBaseMethod>();
0130:
0131: private ContainerProgram _initProgram;
0132: private ArrayList<ConfigProgram> _postConstructList = new ArrayList<ConfigProgram>();
0133: private ContainerProgram _serverProgram;
0134:
0135: private ArrayList<Interceptor> _interceptors = new ArrayList<Interceptor>();
0136:
0137: private String _aroundInvokeMethodName;
0138: private Method _aroundInvokeMethod;
0139: private String _timeoutMethodName;
0140:
0141: private long _transactionTimeout;
0142:
0143: private AroundInvokeConfig _aroundInvokeConfig;
0144:
0145: private ArrayList<RemoveMethod> _removeMethods = new ArrayList<RemoveMethod>();
0146:
0147: /**
0148: * Creates a new entity bean configuration.
0149: */
0150: public EjbBean(EjbConfig ejbConfig, String ejbModuleName) {
0151: _ejbConfig = ejbConfig;
0152: _ejbModuleName = ejbModuleName;
0153:
0154: _loader = ejbConfig.getEjbContainer().getClassLoader();
0155:
0156: // TCK ejb30/tx: ejb/0f14 vs ejb/02a0
0157: getEjbContainer().getTransactionManager().setEJB3(isEJB3());
0158: }
0159:
0160: public EjbConfig getConfig() {
0161: return _ejbConfig;
0162: }
0163:
0164: public EjbContainer getEjbContainer() {
0165: return _ejbConfig.getEjbContainer();
0166: }
0167:
0168: public String getAroundInvokeMethodName() {
0169: return _aroundInvokeMethodName;
0170: }
0171:
0172: public void setAroundInvokeMethodName(String aroundInvokeMethodName) {
0173: _aroundInvokeMethodName = aroundInvokeMethodName;
0174: }
0175:
0176: public void setAroundInvoke(AroundInvokeConfig aroundInvoke) {
0177: _aroundInvokeConfig = aroundInvoke;
0178:
0179: // ejb/0fbb
0180: _aroundInvokeMethodName = aroundInvoke.getMethodName();
0181: }
0182:
0183: /**
0184: * Returns the remove-method for the given method.
0185: */
0186: public RemoveMethod getRemoveMethod(Method method) {
0187: for (RemoveMethod removeMethod : _removeMethods) {
0188: if (removeMethod.isMatch(method))
0189: return removeMethod;
0190: }
0191:
0192: return null;
0193: }
0194:
0195: /**
0196: * Returns the remove-method list.
0197: */
0198: public ArrayList<RemoveMethod> getRemoveMethods() {
0199: return _removeMethods;
0200: }
0201:
0202: /**
0203: * Returns the timeout method name.
0204: */
0205: public String getTimeoutMethodName() {
0206: return _timeoutMethodName;
0207: }
0208:
0209: /**
0210: * Adds a new remove-method
0211: */
0212: public void addRemoveMethod(RemoveMethod removeMethod) {
0213: _removeMethods.add(removeMethod);
0214: }
0215:
0216: /**
0217: * Returns the interceptors.
0218: */
0219: public ArrayList<Interceptor> getInterceptors() {
0220: return _interceptors;
0221: }
0222:
0223: /**
0224: * Returns the interceptors.
0225: */
0226: public ArrayList<Interceptor> getInvokeInterceptors(
0227: String methodName) {
0228: ArrayList<Interceptor> matchList = null;
0229:
0230: for (Interceptor interceptor : _interceptors) {
0231: if (methodName.equals(interceptor
0232: .getAroundInvokeMethodName())) {
0233: if (matchList == null)
0234: matchList = new ArrayList<Interceptor>();
0235:
0236: matchList.add(interceptor);
0237: }
0238: }
0239:
0240: return matchList;
0241: }
0242:
0243: /**
0244: * Adds a new interceptor.
0245: */
0246: public void addInterceptor(Interceptor interceptor) {
0247: _interceptors.add(interceptor);
0248: }
0249:
0250: /**
0251: * Returns true if the interceptor is already configured.
0252: */
0253: public boolean containsInterceptor(String interceptorClassName) {
0254: return getInterceptor(interceptorClassName) != null;
0255: }
0256:
0257: /**
0258: * Returns the interceptor for a given class name.
0259: */
0260: public Interceptor getInterceptor(String interceptorClassName) {
0261: for (Interceptor interceptor : _interceptors) {
0262: String className = interceptor.getInterceptorClass();
0263:
0264: if (className.equals(interceptorClassName))
0265: return interceptor;
0266: }
0267:
0268: return null;
0269: }
0270:
0271: public String getEJBModuleName() {
0272: return _ejbModuleName;
0273: }
0274:
0275: /**
0276: * Returns the class loader.
0277: */
0278: public ClassLoader getClassLoader() {
0279: return _loader;
0280: }
0281:
0282: protected Class loadClass(String className) {
0283: try {
0284: return Class.forName(className, false, _loader);
0285: } catch (ClassNotFoundException e) {
0286: throw ConfigException.create(e);
0287: }
0288: }
0289:
0290: /**
0291: * Sets the location
0292: */
0293: public void setConfigLocation(String filename, int line) {
0294: if (_filename == null) {
0295: _filename = filename;
0296: _line = line;
0297: }
0298:
0299: if (_location == null)
0300: _location = filename + ":" + line + ": ";
0301: }
0302:
0303: /**
0304: * Sets the location
0305: */
0306: public void setLocation(String location) {
0307: _location = location;
0308: }
0309:
0310: /**
0311: * Gets the location
0312: */
0313: public String getLocation() {
0314: return _location;
0315: }
0316:
0317: /**
0318: * Gets the file name
0319: */
0320: public String getFilename() {
0321: return _filename;
0322: }
0323:
0324: /**
0325: * Gets the line
0326: */
0327: public int getLine() {
0328: return _line;
0329: }
0330:
0331: /**
0332: * Sets true if POJO are allowed.
0333: */
0334: public void setAllowPOJO(boolean allowPOJO) {
0335: _isAllowPOJO = allowPOJO;
0336: }
0337:
0338: /**
0339: * Return true if POJO are allowed.
0340: */
0341: public boolean isAllowPOJO() {
0342: return _isAllowPOJO;
0343: }
0344:
0345: /**
0346: * Sets the ejbName
0347: */
0348: public void setEJBName(String ejbName) {
0349: _ejbName = ejbName;
0350: }
0351:
0352: /**
0353: * Gets the ejbName
0354: */
0355: public String getEJBName() {
0356: return _ejbName;
0357: }
0358:
0359: /**
0360: * The mapped-name is the remote published name
0361: * used by IIOP, Hessian, and jndi-remote-prefix, jndi-local-prefix.
0362: * The default is the EJBName.
0363: */
0364: public void setMappedName(String mappedName) {
0365: _mappedName = mappedName;
0366: }
0367:
0368: /**
0369: * The mapped-name is the published name
0370: * used by IIOP, Hessian, and jndi-remote-prefix, jndi-local-prefix.
0371: */
0372: public String getMappedName() {
0373: return _mappedName == null ? getEJBName() : _mappedName;
0374: }
0375:
0376: /**
0377: * Returns the kind of bean.
0378: */
0379: public String getEJBKind() {
0380: return "unknown";
0381: }
0382:
0383: /**
0384: * Sets the ejb implementation class.
0385: */
0386: public void setEJBClass(Class ejbClass) throws ConfigException {
0387: setEJBClassWrapper(new ApiClass(ejbClass));
0388: }
0389:
0390: /**
0391: * Sets the ejb implementation class.
0392: */
0393: public void setEJBClassWrapper(ApiClass ejbClass)
0394: throws ConfigException {
0395: if (_ejbClass != null
0396: && !_ejbClass.getName().equals(ejbClass.getName()))
0397: throw error(L
0398: .l(
0399: "ejb-class '{0}' cannot be redefined. Old value is '{1}'.",
0400: _ejbClass.getName(), ejbClass.getName()));
0401:
0402: _ejbClass = ejbClass;
0403:
0404: if (!_ejbClass.isPublic())
0405: throw error(L
0406: .l(
0407: "'{0}' must be public. Bean implementations must be public.",
0408: ejbClass.getName()));
0409:
0410: if (_ejbClass.isFinal())
0411: throw error(L
0412: .l(
0413: "'{0}' must not be final. Bean implementations must not be final.",
0414: ejbClass.getName()));
0415:
0416: if (_ejbClass.isInterface())
0417: throw error(L
0418: .l(
0419: "'{0}' must not be an interface. Bean implementations must be classes.",
0420: ejbClass.getName()));
0421:
0422: // ejb/02e5
0423: Constructor constructor = null;
0424: try {
0425: constructor = ejbClass.getConstructor(new Class[0]);
0426: } catch (Exception e) {
0427: log.log(Level.FINE, e.toString(), e);
0428: }
0429:
0430: if (constructor == null)
0431: throw error(L
0432: .l(
0433: "'{0}' needs a public zero-arg constructor. Bean implementations need a public zero-argument constructor.",
0434: ejbClass.getName()));
0435:
0436: for (Class exn : constructor.getExceptionTypes()) {
0437: if (!RuntimeException.class.isAssignableFrom(exn)) {
0438: throw error(L
0439: .l(
0440: "{0}: constructor must not throw '{1}'. Bean constructors must not throw checked exceptions.",
0441: ejbClass.getName(), exn.getName()));
0442: }
0443: }
0444:
0445: ApiMethod method = ejbClass.getMethod("finalize", new Class[0]);
0446:
0447: if (method != null
0448: && !method.getDeclaringClass().equals(Object.class))
0449: throw error(L
0450: .l(
0451: "'{0}' may not implement finalize(). Bean implementations may not implement finalize().",
0452: ejbClass.getName()));
0453: }
0454:
0455: /**
0456: * Gets the ejb implementation class.
0457: */
0458: public Class getEJBClass() {
0459: try {
0460: if (_ejbClass == null)
0461: return null;
0462:
0463: return Class.forName(_ejbClass.getName(), false,
0464: getClassLoader());
0465: } catch (RuntimeException e) {
0466: throw e;
0467: } catch (Exception e) {
0468: throw ConfigException.create(e);
0469: }
0470: }
0471:
0472: /**
0473: * Gets the ejb implementation class.
0474: */
0475: public ApiClass getEJBClassWrapper() {
0476: return _ejbClass;
0477: }
0478:
0479: /**
0480: * Gets the ejb implementation class.
0481: */
0482: public String getEJBFullClassName() {
0483: return _ejbClass.getName();
0484: }
0485:
0486: /**
0487: * Gets the ejb implementation class.
0488: */
0489: public String getEJBClassName() {
0490: String s = _ejbClass.getName();
0491: int p = s.lastIndexOf('.');
0492:
0493: if (p > 0)
0494: return s.substring(p + 1);
0495: else
0496: return s;
0497: }
0498:
0499: /**
0500: * Gets the implementation class name.
0501: */
0502: public String getFullImplName() {
0503: return getEJBFullClassName();
0504: }
0505:
0506: /**
0507: * Sets the remote home interface class.
0508: */
0509: public void setHome(Class homeClass) throws ConfigException {
0510: ApiClass home = new ApiClass(homeClass);
0511:
0512: setRemoteHomeWrapper(home);
0513: }
0514:
0515: /**
0516: * Sets the remote home interface class.
0517: */
0518: public void setRemoteHomeWrapper(ApiClass remoteHome)
0519: throws ConfigException {
0520: _remoteHome = remoteHome;
0521:
0522: if (!remoteHome.isPublic())
0523: throw error(L
0524: .l(
0525: "'{0}' must be public. <home> interfaces must be public.",
0526: remoteHome.getName()));
0527:
0528: if (!remoteHome.isInterface())
0529: throw error(L
0530: .l(
0531: "'{0}' must be an interface. <home> interfaces must be interfaces.",
0532: remoteHome.getName()));
0533:
0534: if (EJBHome.class.isAssignableFrom(remoteHome.getJavaClass())) {
0535: } else if (!isAllowPOJO()) {
0536: // XXX: does descriptor still have this requirement?
0537: // i.e. annotations act differently
0538: throw new ConfigException(
0539: L
0540: .l(
0541: "'{0}' must extend EJBHome. <home> interfaces must extend javax.ejb.EJBHome.",
0542: remoteHome.getName()));
0543: }
0544: }
0545:
0546: /**
0547: * Gets the ejb implementation class.
0548: */
0549: public ApiClass getRemoteHome() {
0550: return _remoteHome;
0551: }
0552:
0553: /**
0554: * Gets the remote home class.
0555: */
0556: public Class getRemoteHomeClass() {
0557: if (_remoteHome == null)
0558: return null;
0559:
0560: try {
0561: return Class.forName(_remoteHome.getName(), false,
0562: getClassLoader());
0563: } catch (Exception e) {
0564: throw new RuntimeException(e);
0565: }
0566: }
0567:
0568: /**
0569: * Sets the ejb remote interface
0570: */
0571: public void setRemote(Class remote) throws ConfigException {
0572: setRemoteWrapper(new ApiClass(remote));
0573: }
0574:
0575: /**
0576: * Sets the remote interface class.
0577: */
0578: public void setRemoteWrapper(ApiClass remote)
0579: throws ConfigException {
0580: if (!remote.isPublic())
0581: throw error(L
0582: .l(
0583: "'{0}' must be public. <remote> interfaces must be public.",
0584: remote.getName()));
0585:
0586: if (!remote.isInterface())
0587: throw error(L
0588: .l(
0589: "'{0}' must be an interface. <remote> interfaces must be interfaces.",
0590: remote.getName()));
0591:
0592: if (!EJBObject.class.isAssignableFrom(remote.getJavaClass())
0593: && !isAllowPOJO())
0594: throw new ConfigException(
0595: L
0596: .l(
0597: "'{0}' must extend EJBObject. <remote> interfaces must extend javax.ejb.EJBObject.",
0598: remote.getName()));
0599:
0600: if (!_remoteList.contains(remote)) {
0601: _remoteList.add(remote);
0602: }
0603: }
0604:
0605: /**
0606: * Adds a remote interface class
0607: */
0608: public void addBusinessRemote(Class remoteClass) {
0609: ApiClass remote = new ApiClass(remoteClass);
0610:
0611: if (!remote.isPublic())
0612: throw error(L
0613: .l(
0614: "'{0}' must be public. <business-remote> interfaces must be public.",
0615: remote.getName()));
0616:
0617: if (!remote.isInterface())
0618: throw error(L
0619: .l(
0620: "'{0}' must be an interface. <business-remote> interfaces must be interfaces.",
0621: remote.getName()));
0622:
0623: if (!_remoteList.contains(remote)) {
0624: _remoteList.add(remote);
0625: }
0626: }
0627:
0628: /**
0629: * Gets the remote interface class.
0630: */
0631: public ArrayList<ApiClass> getRemoteList() {
0632: return _remoteList;
0633: }
0634:
0635: /**
0636: * Gets the remote class.
0637: */
0638: public Class getRemoteClass() {
0639: if (_remoteList.size() < 1)
0640: return null;
0641:
0642: try {
0643: ApiClass remote = _remoteList.get(0);
0644:
0645: return Class.forName(remote.getName(), false,
0646: getClassLoader());
0647: } catch (Exception e) {
0648: throw new RuntimeException(e);
0649: }
0650: }
0651:
0652: /**
0653: * Sets the ejb local home interface
0654: */
0655: public void setLocalHome(Class localHomeClass)
0656: throws ConfigException {
0657: ApiClass localHome = new ApiClass(localHomeClass);
0658:
0659: setLocalHomeWrapper(localHome);
0660: }
0661:
0662: /**
0663: * Sets the local home interface class.
0664: */
0665: public void setLocalHomeWrapper(ApiClass localHome)
0666: throws ConfigException {
0667: _localHome = localHome;
0668:
0669: if (!localHome.isPublic())
0670: throw error(L
0671: .l(
0672: "'{0}' must be public. <local-home> interfaces must be public.",
0673: localHome.getName()));
0674:
0675: if (!localHome.isInterface())
0676: throw error(L
0677: .l(
0678: "'{0}' must be an interface. <local-home> interfaces must be interfaces.",
0679: localHome.getName()));
0680:
0681: if (!EJBLocalHome.class.isAssignableFrom(localHome
0682: .getJavaClass())
0683: && !isAllowPOJO())
0684: throw new ConfigException(
0685: L
0686: .l(
0687: "'{0}' must extend EJBLocalHome. <local-home> interfaces must extend javax.ejb.EJBLocalHome.",
0688: localHome.getName()));
0689:
0690: }
0691:
0692: /**
0693: * Gets the local home interface class.
0694: */
0695: public ApiClass getLocalHome() {
0696: return _localHome;
0697: }
0698:
0699: /**
0700: * Sets the ejb local interface
0701: */
0702: public void setLocal(Class local) throws ConfigException {
0703: setLocalWrapper(new ApiClass(local));
0704: }
0705:
0706: /**
0707: * Sets the local interface class.
0708: */
0709: public void setLocalWrapper(ApiClass local) throws ConfigException {
0710: if (!local.isPublic())
0711: throw error(L
0712: .l(
0713: "'{0}' must be public. <local> interfaces must be public.",
0714: local.getName()));
0715:
0716: if (!local.isInterface())
0717: throw error(L
0718: .l(
0719: "'{0}' must be an interface. <local> interfaces must be interfaces.",
0720: local.getName()));
0721:
0722: if (EJBLocalObject.class.isAssignableFrom(local.getJavaClass())) {
0723: } else if (!isAllowPOJO())
0724: throw new ConfigException(
0725: L
0726: .l(
0727: "'{0}' must extend EJBLocalObject. <local> interfaces must extend javax.ejb.EJBLocalObject.",
0728: local.getName()));
0729:
0730: if (!_localList.contains(local)) {
0731: _localList.add(local);
0732: }
0733: }
0734:
0735: /**
0736: * Adds a local interface class
0737: */
0738: public void addBusinessLocal(Class localClass) {
0739: ApiClass local = new ApiClass(localClass);
0740:
0741: if (!local.isPublic())
0742: throw error(L
0743: .l(
0744: "'{0}' must be public. <local> interfaces must be public.",
0745: local.getName()));
0746:
0747: if (!local.isInterface())
0748: throw error(L
0749: .l(
0750: "'{0}' must be an interface. <local> interfaces must be interfaces.",
0751: local.getName()));
0752:
0753: if (!_localList.contains(local)) {
0754: _localList.add(local);
0755: }
0756: }
0757:
0758: /**
0759: * Gets the local interface class.
0760: */
0761: public ArrayList<ApiClass> getLocalList() {
0762: return _localList;
0763: }
0764:
0765: /**
0766: * Returns true if the transaction type is container.
0767: */
0768: public boolean isContainerTransaction() {
0769: return _isContainerTransaction;
0770: }
0771:
0772: /**
0773: * Returns true if the transaction type is container.
0774: */
0775: public void setContainerTransaction(boolean isContainerTransaction) {
0776: _isContainerTransaction = isContainerTransaction;
0777: }
0778:
0779: /**
0780: * Adds a method.
0781: */
0782: public EjbMethodPattern createMethod(MethodSignature sig) {
0783: for (int i = 0; i < _methodList.size(); i++) {
0784: EjbMethodPattern method = _methodList.get(i);
0785:
0786: if (method.getSignature().equals(sig))
0787: return method;
0788: }
0789:
0790: EjbMethodPattern method = new EjbMethodPattern(this , sig);
0791:
0792: _methodList.add(method);
0793:
0794: return method;
0795: }
0796:
0797: /**
0798: * Adds a method.
0799: */
0800: public void addMethod(EjbMethodPattern method) {
0801: _methodList.add(method);
0802: }
0803:
0804: /**
0805: * Gets the best method.
0806: */
0807: public EjbMethodPattern getMethodPattern(ApiMethod method,
0808: String intf) {
0809: EjbMethodPattern bestMethod = null;
0810: int bestCost = -1;
0811:
0812: for (int i = 0; i < _methodList.size(); i++) {
0813: EjbMethodPattern ejbMethod = _methodList.get(i);
0814: MethodSignature sig = ejbMethod.getSignature();
0815:
0816: if (sig.isMatch(method, intf) && bestCost < sig.getCost()) {
0817: bestMethod = ejbMethod;
0818: bestCost = sig.getCost();
0819: }
0820: }
0821:
0822: return bestMethod;
0823: }
0824:
0825: /**
0826: * returns the method list.
0827: */
0828: public ArrayList<EjbMethodPattern> getMethodList() {
0829: return _methodList;
0830: }
0831:
0832: /**
0833: * Sets the transaction timeout.
0834: */
0835: public void setTransactionTimeout(Period timeout) {
0836: _transactionTimeout = timeout.getPeriod();
0837: }
0838:
0839: /**
0840: * Gets the transaction timeout.
0841: */
0842: public long getTransactionTimeout() {
0843: return _transactionTimeout;
0844: }
0845:
0846: public MessageDestinationRef createMessageDestinationRef() {
0847: return new MessageDestinationRef(Vfs.lookup(_ejbModuleName));
0848: }
0849:
0850: /**
0851: * Sets the security identity
0852: */
0853: public void setSecurityIdentity(EjbSecurityIdentity securityIdentity) {
0854: }
0855:
0856: /**
0857: * Adds a list of dependencies.
0858: */
0859: public void addDependencyList(
0860: ArrayList<PersistentDependency> dependList) {
0861: for (int i = 0; dependList != null && i < dependList.size(); i++) {
0862: addDependency(dependList.get(i));
0863: }
0864: }
0865:
0866: /**
0867: * Add a dependency.
0868: */
0869: public void addDepend(Path path) {
0870: addDependency(new Depend(path));
0871: }
0872:
0873: /**
0874: * Add a dependency.
0875: */
0876: public void addDependency(PersistentDependency depend) {
0877: if (!_dependList.contains(depend))
0878: _dependList.add(depend);
0879: }
0880:
0881: /**
0882: * Add a dependency.
0883: */
0884: public void addDependency(Class cl) {
0885: addDependency(new ClassDependency(cl));
0886: }
0887:
0888: /**
0889: * Gets the depend list.
0890: */
0891: public ArrayList<PersistentDependency> getDependList() {
0892: return _dependList;
0893: }
0894:
0895: /**
0896: * Add a bean dependency.
0897: */
0898: public void addBeanDependency(String ejbName) {
0899: if (!_beanDependList.contains(ejbName))
0900: _beanDependList.add(ejbName);
0901: }
0902:
0903: /**
0904: * Gets the bean depend list.
0905: */
0906: public ArrayList<String> getBeanDependList() {
0907: return _beanDependList;
0908: }
0909:
0910: /**
0911: * Adds an init program.
0912: */
0913: public void addInitProgram(ConfigProgram init) {
0914: if (_initProgram == null)
0915: _initProgram = new ContainerProgram();
0916:
0917: _initProgram.addProgram(init);
0918: }
0919:
0920: /**
0921: * Adds an undefined value, e.g. env-entry
0922: */
0923: public void addBuilderProgram(ConfigProgram init) {
0924: if (_serverProgram == null)
0925: _serverProgram = new ContainerProgram();
0926:
0927: _serverProgram.addProgram(init);
0928: }
0929:
0930: public void setInit(ContainerProgram init) {
0931: if (_initProgram == null)
0932: _initProgram = new ContainerProgram();
0933:
0934: _initProgram.addProgram(init);
0935: }
0936:
0937: public void addPostConstruct(PostConstructType postConstruct) {
0938: _postConstructList.add(postConstruct.getProgram(getEJBClass()));
0939: }
0940:
0941: /**
0942: * Gets the init program.
0943: */
0944: public ContainerProgram getInitProgram() {
0945: if (_postConstructList != null) {
0946: if (_initProgram == null)
0947: _initProgram = new ContainerProgram();
0948:
0949: for (ConfigProgram program : _postConstructList)
0950: _initProgram.addProgram(program);
0951:
0952: _postConstructList = null;
0953: }
0954:
0955: return _initProgram;
0956: }
0957:
0958: /**
0959: * Gets the server program.
0960: */
0961: public ContainerProgram getServerProgram() {
0962: return _serverProgram;
0963: }
0964:
0965: /**
0966: * Configure initialization.
0967: */
0968: @PostConstruct
0969: public void init() throws ConfigException {
0970: try {
0971: if (_isInit)
0972: return;
0973: _isInit = true;
0974:
0975: if (getEJBClassWrapper() == null)
0976: throw error(L.l("ejb-class is not defined for '{0}'",
0977: getEJBName()));
0978:
0979: _bean = createBeanGenerator();
0980:
0981: if (getLocalHome() != null)
0982: _bean.setLocalHome(getLocalHome());
0983:
0984: for (ApiClass localApi : _localList) {
0985: _bean.addLocal(localApi);
0986: }
0987:
0988: if (getRemoteHome() != null)
0989: _bean.setRemoteHome(getRemoteHome());
0990:
0991: for (ApiClass remoteApi : _remoteList) {
0992: _bean.addRemote(remoteApi);
0993: }
0994:
0995: // XXX: add local api
0996:
0997: introspect();
0998:
0999: _bean.createViews();
1000:
1001: InterceptorBinding interceptor = getConfig()
1002: .getInterceptorBinding(getEJBName(), false);
1003:
1004: if (_aroundInvokeMethodName != null) {
1005: ApiMethod method = getMethod(_aroundInvokeMethodName,
1006: new Class[] { InvocationContext.class });
1007:
1008: if (method == null)
1009: throw error(L.l(
1010: "'{0}' is an unknown around-invoke method",
1011: _aroundInvokeMethodName));
1012:
1013: _bean.setAroundInvokeMethod(method.getMethod());
1014: }
1015:
1016: if (interceptor != null) {
1017: for (Class cl : interceptor.getInterceptors()) {
1018: _bean.addInterceptor(cl);
1019: }
1020: }
1021:
1022: for (View view : _bean.getViews()) {
1023: for (BusinessMethodGenerator bizMethod : view
1024: .getMethods()) {
1025: if (!isContainerTransaction())
1026: bizMethod.getXa().setContainerManaged(false);
1027: }
1028: }
1029:
1030: for (EjbMethodPattern method : _methodList) {
1031: method.configure(_bean);
1032: }
1033:
1034: // initIntrospect();
1035:
1036: // assembleBeanMethods();
1037:
1038: // createViews();
1039: } catch (ConfigException e) {
1040: throw ConfigException.createLine(_location, e);
1041: }
1042: }
1043:
1044: protected void introspect() {
1045: _bean.introspect();
1046: }
1047:
1048: /**
1049: * Creates the BeanGenerator generator instance
1050: */
1051: protected BeanGenerator createBeanGenerator() {
1052: throw new UnsupportedOperationException(getClass().getName());
1053: }
1054:
1055: /**
1056: * Configure initialization.
1057: */
1058: public void initIntrospect() throws ConfigException {
1059: boolean isExcludeDefault = false;
1060:
1061: // XXX: ejb/0f78
1062: /*
1063: if (_ejbClass != null) {
1064: Interceptors interceptorsAnn = _ejbClass.getAnnotation(Interceptors.class);
1065:
1066: if (interceptorsAnn != null) {
1067: for (Class cl : interceptorsAnn.value()) {
1068: // XXX: ejb/0fb0
1069: if (! containsInterceptor(cl.getName())) {
1070: addInterceptor(configureInterceptor(cl));
1071: }
1072: }
1073: }
1074:
1075: // ejb/0fbj
1076: if (_ejbClass.isAnnotationPresent(ExcludeDefaultInterceptors.class))
1077: isExcludeDefault = true;
1078: }
1079: */
1080:
1081: // ejb/0fb5
1082: InterceptorBinding binding = _ejbConfig.getInterceptorBinding(
1083: getEJBName(), isExcludeDefault);
1084:
1085: /*
1086: if (binding != null) {
1087: ArrayList<Class> interceptorClasses = binding.getInterceptors();
1088:
1089: // ejb/0fb7
1090: if (interceptorClasses.isEmpty()) {
1091: InterceptorOrder interceptorOrder = binding.getInterceptorOrder();
1092:
1093: // ejb/0fbf
1094: if (interceptorOrder != null)
1095: interceptorClasses = interceptorOrder.getInterceptorClasses();
1096: }
1097:
1098: for (String className : interceptorClasses) {
1099: Interceptor interceptor = getInterceptor(className);
1100:
1101: // ejb/0fb5 vs ejb/0fb6
1102: if (interceptor != null) {
1103: _interceptors.remove(interceptor);
1104:
1105: addInterceptor(interceptor);
1106: }
1107: else {
1108: interceptor = _ejbConfig.getInterceptor(className);
1109:
1110: interceptor.init();
1111:
1112: addInterceptor(interceptor);
1113: }
1114: }
1115: }
1116: */
1117: }
1118:
1119: private Interceptor configureInterceptor(Class type)
1120: throws ConfigException {
1121: try {
1122: Interceptor interceptor = new Interceptor();
1123:
1124: interceptor.setInterceptorClass(type.getName());
1125:
1126: interceptor.init();
1127:
1128: return interceptor;
1129: } catch (RuntimeException e) {
1130: throw e;
1131: } catch (Exception e) {
1132: throw new RuntimeException(e);
1133: }
1134: }
1135:
1136: /**
1137: * Configure for amber.
1138: */
1139: public void configureAmber(AmberConfig config)
1140: throws ConfigException {
1141: }
1142:
1143: /**
1144: * Creates the views.
1145: */
1146: protected void createViews21() throws ConfigException {
1147: /*
1148: if (_remoteHome != null) {
1149: _remoteHomeView = createHomeView(_remoteHome, "RemoteHome");
1150: _remoteHomeView.introspect();
1151: }
1152:
1153: if (_remote != null) {
1154: ArrayList<ApiClass> list = new ArrayList<ApiClass>();
1155: list.add(_remote);
1156:
1157: _remoteView = createRemoteObjectView(list, "Remote", "21");
1158: _remoteView.introspect();
1159: }
1160:
1161: if (_remote21 != null) {
1162: ArrayList<ApiClass> list = new ArrayList<ApiClass>();
1163: list.add(_remote21);
1164:
1165: _remoteView21 = createRemoteObjectView(list, "Remote", "21");
1166: _remoteView21.introspect();
1167: }
1168:
1169: else if (_remoteList.size() > 0) {
1170: ArrayList<ApiClass> list = new ArrayList<ApiClass>();
1171: list.addAll(_remoteList);
1172: list.remove(_remote21);
1173:
1174: if (list.size() > 0) {
1175: _remoteView = createRemoteObjectView(list, "Remote", "");
1176: _remoteView.introspect();
1177: }
1178: }
1179:
1180: if (_localHome != null) {
1181: _localHomeView = createHomeView(_localHome, "LocalHome");
1182: _localHomeView.introspect();
1183: }
1184:
1185: if (_local21 != null) {
1186: ArrayList<ApiClass> list = new ArrayList<ApiClass>();
1187: list.add(_local21);
1188:
1189: _localView21 = createObjectView(list, "Local", "21");
1190: _localView21.introspect();
1191: }
1192:
1193: if (_localList.size() > 0) {
1194: ArrayList<ApiClass> list = new ArrayList<ApiClass>();
1195: list.addAll(_localList);
1196: list.remove(_local21);
1197:
1198: if (list.size() > 0) {
1199: _localView = createObjectView(list, "Local", "");
1200: _localView.introspect();
1201: }
1202: }
1203: */
1204: }
1205:
1206: /**
1207: * Creates a home view.
1208: */
1209: protected EjbHomeView createHomeView(ApiClass homeClass,
1210: String prefix) throws ConfigException {
1211: return new EjbHomeView(this , homeClass, prefix);
1212: }
1213:
1214: /**
1215: * Creates an object view.
1216: */
1217: protected EjbObjectView createObjectView(
1218: ArrayList<ApiClass> apiList, String prefix, String suffix)
1219: throws ConfigException {
1220: return new EjbObjectView(this , apiList, prefix, suffix, false);
1221: }
1222:
1223: protected EjbObjectView createRemoteObjectView(
1224: ArrayList<ApiClass> apiList, String prefix, String suffix)
1225: throws ConfigException {
1226: return new EjbObjectView(this , apiList, prefix, suffix, true);
1227: }
1228:
1229: /**
1230: * Generates the class.
1231: */
1232: public void generate(JavaClassGenerator javaGen,
1233: boolean isAutoCompile) throws Exception {
1234: String fullClassName = _bean.getFullClassName();
1235:
1236: if (javaGen.preload(fullClassName) != null) {
1237: } else if (isAutoCompile) {
1238: javaGen.generate(_bean);
1239:
1240: /*
1241: GenClass genClass = assembleGenerator(fullClassName);
1242:
1243: if (genClass != null)
1244: javaGen.generate(genClass);
1245: */
1246: }
1247: }
1248:
1249: /**
1250: * Deploys the bean.
1251: */
1252: public AbstractServer deployServer(EjbContainer ejbContainer,
1253: JavaClassGenerator javaGen) throws ClassNotFoundException,
1254: ConfigException {
1255: throw new UnsupportedOperationException();
1256: }
1257:
1258: /**
1259: * Validates the remote interface.
1260: */
1261: protected void validateRemote(ApiClass objectClass)
1262: throws ConfigException {
1263: ApiClass beanClass = getEJBClassWrapper();
1264: String beanName = beanClass.getName();
1265:
1266: String objectName = objectClass.getName();
1267:
1268: if (!objectClass.isPublic())
1269: throw error(L.l("'{0}' must be public", objectName));
1270:
1271: if (!objectClass.isInterface())
1272: throw error(L.l("'{0}' must be an interface", objectName));
1273:
1274: for (ApiMethod method : objectClass.getMethods()) {
1275: String name = method.getName();
1276: Class[] param = method.getParameterTypes();
1277: Class retType = method.getReturnType();
1278:
1279: if (method.getDeclaringClass().isAssignableFrom(
1280: EJBObject.class))
1281: continue;
1282: if (method.getDeclaringClass().isAssignableFrom(
1283: EJBLocalObject.class))
1284: continue;
1285:
1286: if (EJBObject.class.isAssignableFrom(objectClass
1287: .getJavaClass()))
1288: validateException(method,
1289: java.rmi.RemoteException.class);
1290:
1291: if (name.startsWith("ejb")) {
1292: throw error(L
1293: .l(
1294: "'{0}' forbidden in {1}. Local or remote interfaces may not define ejbXXX methods.",
1295: getFullMethodName(method), objectName));
1296: }
1297:
1298: Class returnType = method.getReturnType();
1299:
1300: if (EJBObject.class.isAssignableFrom(objectClass
1301: .getJavaClass())
1302: && (EJBLocalObject.class
1303: .isAssignableFrom(returnType) || EJBLocalHome.class
1304: .isAssignableFrom(returnType))) {
1305: throw error(L
1306: .l(
1307: "'{0}' must not return '{1}' in {2}. Remote methods must not return local interfaces.",
1308: getFullMethodName(method),
1309: getShortClassName(returnType),
1310: objectClass.getName()));
1311: }
1312:
1313: ApiMethod implMethod = validateRemoteImplMethod(method
1314: .getName(), param, method, objectClass);
1315:
1316: if (!returnType.equals(implMethod.getReturnType())) {
1317: throw error(L
1318: .l(
1319: "{0}: '{1}' must return {2} to match {3}.{4}. Business methods must return the same type as the interface.",
1320: method.getDeclaringClass().getName(),
1321: getFullMethodName(method), implMethod
1322: .getReturnType().getName(),
1323: getShortClassName(implMethod
1324: .getDeclaringClass()),
1325: getFullMethodName(implMethod)));
1326: }
1327:
1328: validateExceptions(method, implMethod.getExceptionTypes());
1329: }
1330: }
1331:
1332: /**
1333: * Check that a method exists, is public, not abstract.
1334: *
1335: * @param methodName the name of the method to check for
1336: * @param args the expected method parameters
1337: *
1338: * @return the matching method
1339: */
1340: private ApiMethod validateRemoteImplMethod(String methodName,
1341: Class[] param, ApiMethod sourceMethod, ApiClass sourceClass)
1342: throws ConfigException {
1343: ApiMethod method = null;
1344: ApiClass beanClass = getEJBClassWrapper();
1345:
1346: method = getMethod(beanClass, methodName, param);
1347:
1348: if (method == null && sourceMethod != null) {
1349: throw error(L.l("{0}: '{1}' expected to match {2}.{3}",
1350: beanClass.getName(), getFullMethodName(methodName,
1351: param), getShortClassName(sourceMethod
1352: .getDeclaringClass()),
1353: getFullMethodName(sourceMethod)));
1354: } else if (method == null) {
1355: throw error(L.l("{0}: '{1}' expected", beanClass.getName(),
1356: getFullMethodName(methodName, param)));
1357: }
1358: /*
1359: else if (Modifier.isAbstract(method.getModifiers()) &&
1360: getBeanManagedPersistence()) {
1361: throw error(L.l("{0}: '{1}' must not be abstract",
1362: beanClass.getName(),
1363: getFullMethodName(methodName, param)));
1364: }
1365: */
1366: else if (!method.isPublic()) {
1367: throw error(L.l("{0}: '{1}' must be public", beanClass
1368: .getName(), getFullMethodName(methodName, param)));
1369: }
1370:
1371: if (method.isStatic()) {
1372: throw error(L.l("{0}: '{1}' must not be static", beanClass
1373: .getName(), getFullMethodName(methodName, param)));
1374: }
1375:
1376: if (method.isFinal()) {
1377: throw error(L.l("{0}: '{1}' must not be final.", beanClass
1378: .getName(), getFullMethodName(methodName, param),
1379: beanClass.getName()));
1380: }
1381:
1382: return method;
1383: }
1384:
1385: protected ApiMethod validateNonFinalMethod(String methodName,
1386: Class[] param, boolean isOptional) throws ConfigException {
1387: if (isOptional
1388: && getMethod(_ejbClass, methodName, param) == null)
1389: return null;
1390: else
1391: return validateNonFinalMethod(methodName, param);
1392: }
1393:
1394: protected ApiMethod validateNonFinalMethod(String methodName,
1395: Class[] param) throws ConfigException {
1396: return validateNonFinalMethod(methodName, param, null, null);
1397: }
1398:
1399: protected ApiMethod validateNonFinalMethod(String methodName,
1400: Class[] param, ApiMethod sourceMethod, ApiClass sourceClass)
1401: throws ConfigException {
1402: return validateNonFinalMethod(methodName, param, sourceMethod,
1403: sourceClass, false);
1404: }
1405:
1406: /**
1407: * Check that a method exists, is public, not abstract, and not final.
1408: *
1409: * @param methodName the name of the method to check for
1410: * @param args the expected method parameters
1411: *
1412: * @return the matching method
1413: */
1414: protected ApiMethod validateNonFinalMethod(String methodName,
1415: Class[] param, ApiMethod sourceMethod,
1416: ApiClass sourceClass, boolean isOptional)
1417: throws ConfigException {
1418: ApiMethod method = validateMethod(methodName, param,
1419: sourceMethod, sourceClass, isOptional);
1420:
1421: if (method == null && isOptional)
1422: return null;
1423:
1424: if (method.isFinal())
1425: throw error(L.l("{0}: '{1}' must not be final", _ejbClass
1426: .getName(), getFullMethodName(method)));
1427:
1428: if (method.isStatic())
1429: throw error(L.l("{0}: '{1}' must not be static", _ejbClass
1430: .getName(), getFullMethodName(method)));
1431:
1432: return method;
1433: }
1434:
1435: protected ApiMethod validateMethod(String methodName, Class[] param)
1436: throws ConfigException {
1437: return validateMethod(methodName, param, null, null);
1438: }
1439:
1440: /**
1441: * Check that a method exists, is public and is not abstract.
1442: *
1443: * @param methodName the name of the method to check for
1444: * @param args the expected method parameters
1445: *
1446: * @return the matching method
1447: */
1448: protected ApiMethod validateMethod(String methodName,
1449: Class[] param, ApiMethod sourceMethod, ApiClass sourceClass)
1450: throws ConfigException {
1451: return validateMethod(methodName, param, sourceMethod,
1452: sourceClass, false);
1453: }
1454:
1455: /**
1456: * Check that a method exists, is public and is not abstract.
1457: *
1458: * @param methodName the name of the method to check for
1459: * @param args the expected method parameters
1460: *
1461: * @return the matching method
1462: */
1463: protected ApiMethod validateMethod(String methodName,
1464: Class[] param, ApiMethod sourceMethod,
1465: ApiClass sourceClass, boolean isOptional)
1466: throws ConfigException {
1467: ApiMethod method = null;
1468:
1469: method = getMethod(_ejbClass, methodName, param);
1470:
1471: if (method == null && isOptional)
1472: return null;
1473:
1474: if (method == null && sourceMethod != null) {
1475: throw error(L.l(
1476: "{0}: missing '{1}' needed to match {2}.{3}",
1477: _ejbClass.getName(), getFullMethodName(methodName,
1478: param), sourceClass.getSimpleName(),
1479: getFullMethodName(sourceMethod)));
1480: } else if (method == null) {
1481: throw error(L.l("{0}: expected '{1}'", _ejbClass.getName(),
1482: getFullMethodName(methodName, param)));
1483: }
1484:
1485: Class declaringClass = method.getDeclaringClass();
1486:
1487: if (method.isAbstract()) {
1488: if (method.getDeclaringClass().getName().equals(
1489: "javax.ejb.EntityBean"))
1490: throw error(L
1491: .l(
1492: "{0}: '{1}' must not be abstract. Entity beans must implement the methods in EntityBean.",
1493: _ejbClass.getName(), getFullMethodName(
1494: methodName, param)));
1495: else if (method.getDeclaringClass().getName().equals(
1496: "javax.ejb.SessionBean"))
1497: throw error(L
1498: .l(
1499: "{0}: '{1}' must not be abstract. Session beans must implement the methods in SessionBean.",
1500: _ejbClass.getName(), getFullMethodName(
1501: methodName, param)));
1502: else if (sourceMethod != null)
1503: throw error(L
1504: .l(
1505: "{0}: '{1}' must not be abstract. All methods from '{2}' must be implemented in the bean.",
1506: _ejbClass.getName(), getFullMethodName(
1507: methodName, param), sourceClass
1508: .getName()));
1509: else
1510: throw error(L
1511: .l(
1512: "{0}: '{1}' must not be abstract. Business methods must be implemented.",
1513: _ejbClass.getName(), getFullMethodName(
1514: methodName, param)));
1515: } else if (!method.isPublic()) {
1516: throw error(L
1517: .l(
1518: "{0}: '{1}' must be public. Business method implementations must be public.",
1519: _ejbClass.getName(), getFullMethodName(
1520: methodName, param)));
1521: }
1522: if (method.isStatic()) {
1523: throw error(L
1524: .l(
1525: "{0}: '{1}' must not be static. Business method implementations must not be static.",
1526: _ejbClass.getName(),
1527: getFullMethodName(method)));
1528: }
1529:
1530: return method;
1531: }
1532:
1533: public String getSkeletonName() {
1534: String className = getEJBClass().getName();
1535: int p = className.lastIndexOf('.');
1536:
1537: if (p > 0)
1538: className = className.substring(p + 1);
1539:
1540: String ejbName = getEJBName();
1541:
1542: String fullClassName = "_ejb." + ejbName + "." + className
1543: + "__EJB";
1544:
1545: return JavaClassGenerator.cleanClassName(fullClassName);
1546: }
1547:
1548: /**
1549: * Assembles the generator.
1550: */
1551: public GenClass assembleGenerator(String fullClassName)
1552: throws NoSuchMethodException, ConfigException {
1553: int p = fullClassName.lastIndexOf('.');
1554: String className = fullClassName;
1555: if (p > 0)
1556: className = fullClassName.substring(p + 1);
1557:
1558: BeanAssembler assembler = createAssembler(fullClassName);
1559:
1560: if (assembler == null)
1561: return null;
1562:
1563: addImports(assembler);
1564:
1565: assembler.addHeaderComponent(getEJBClassWrapper(),
1566: fullClassName, getFullImplName());
1567:
1568: assembleMethods(assembler, fullClassName);
1569:
1570: // getEJBClassName());
1571:
1572: assembleViews(assembler, fullClassName);
1573:
1574: /*
1575: if (_remoteHomeView != null)
1576: _remoteHomeView.assembleView(assembler, fullClassName);
1577:
1578: if (_remoteView21 != null)
1579: _remoteView21.assembleView(assembler, fullClassName);
1580:
1581: if (_remoteView != null)
1582: _remoteView.assembleView(assembler, fullClassName);
1583:
1584: if (_localHomeView != null)
1585: _localHomeView.assembleView(assembler, fullClassName);
1586:
1587: if (_localView21 != null)
1588: _localView21.assembleView(assembler, fullClassName);
1589:
1590: if (_localView != null)
1591: _localView.assembleView(assembler, fullClassName);
1592: */
1593: for (PersistentDependency depend : _dependList) {
1594: assembler.addDependency(depend);
1595: }
1596:
1597: assembler.addDependency(new ClassDependency(_ejbClass
1598: .getJavaClass()));
1599:
1600: if (_remoteHome != null)
1601: assembler.addDependency(new ClassDependency(_remoteHome
1602: .getJavaClass()));
1603:
1604: for (ApiClass remote : _remoteList) {
1605: assembler.addDependency(new ClassDependency(remote
1606: .getJavaClass()));
1607: }
1608:
1609: if (_localHome != null)
1610: assembler.addDependency(new ClassDependency(_localHome
1611: .getJavaClass()));
1612:
1613: for (ApiClass local : _localList) {
1614: assembler.addDependency(new ClassDependency(local
1615: .getJavaClass()));
1616: }
1617:
1618: return assembler.getAssembledGenerator();
1619: }
1620:
1621: /**
1622: * Adds the assemblers.
1623: */
1624: protected void addImports(BeanAssembler assembler) {
1625: assembler.addImport("javax.ejb.*");
1626: assembler.addImport("com.caucho.vfs.*");
1627:
1628: assembler.addImport("com.caucho.ejb.xa.EjbTransactionManager");
1629: assembler.addImport("com.caucho.ejb.xa.TransactionContext");
1630:
1631: assembler.addImport("com.caucho.ejb.AbstractContext");
1632: }
1633:
1634: /**
1635: * Creates the assembler for the bean.
1636: */
1637: protected BeanAssembler createAssembler(String fullClassName) {
1638: return null;
1639: }
1640:
1641: /**
1642: * Introspects the bean's methods.
1643: */
1644: public void assembleBeanMethods() throws ConfigException {
1645: if (getEJBClassWrapper() == null)
1646: return;
1647:
1648: // find API methods matching an implementation method
1649: for (ApiMethod method : getEJBClassWrapper().getMethods()) {
1650: EjbBaseMethod ejbMethod = null;
1651:
1652: String name = method.getName();
1653:
1654: if (name.startsWith("ejb")) {
1655: ejbMethod = introspectEJBMethod(method);
1656:
1657: if (ejbMethod != null)
1658: _methodMap.put(ejbMethod.getMethod().getFullName(),
1659: ejbMethod);
1660: } else
1661: validateImplMethod(method);
1662: }
1663: }
1664:
1665: /**
1666: * Assembles the generator methods.
1667: */
1668: protected void assembleMethods(BeanAssembler assembler,
1669: String fullClassName) throws ConfigException {
1670: for (EjbBaseMethod method : _methodMap.values()) {
1671: assembler.addMethod(method.assemble(assembler,
1672: fullClassName));
1673: }
1674: }
1675:
1676: /**
1677: * Assembles the generator methods.
1678: */
1679: protected void assembleViews(BeanAssembler assembler,
1680: String fullClassName) throws ConfigException {
1681: }
1682:
1683: /**
1684: * Introspects an ejb method.
1685: */
1686: protected EjbBaseMethod introspectEJBMethod(ApiMethod method)
1687: throws ConfigException {
1688: return null;
1689: }
1690:
1691: /**
1692: * Validates an implementation method.
1693: */
1694: protected void validateImplMethod(ApiMethod method)
1695: throws ConfigException {
1696: }
1697:
1698: /**
1699: * Assembles methods.
1700: */
1701: protected void assembleMethods(BeanAssembler assembler,
1702: ViewClass view, String contextClassName,
1703: ArrayList<ApiMethod> methods, String prefix)
1704: throws NoSuchMethodException {
1705: for (ApiMethod method : methods) {
1706: String className = method.getDeclaringClass().getName();
1707: String methodName = method.getName();
1708: Class[] args = method.getParameterTypes();
1709:
1710: if (className.startsWith("javax.ejb.")) {
1711: }
1712: /*
1713: else if (isOld(methods, method, i)) {
1714: }
1715: */
1716: else if (methodName.equals("equals") && args.length == 1
1717: && args[0].equals(Object.class)) {
1718: } else if (methodName.equals("hashCode")
1719: && args.length == 0) {
1720: } else {
1721: ApiMethod beanMethod = null;
1722:
1723: ApiClass ejbClass = getEJBClassWrapper();
1724:
1725: beanMethod = ejbClass.getMethod(method.getName(),
1726: method.getParameterTypes());
1727:
1728: if (beanMethod == null)
1729: throw new NoSuchMethodException(
1730: "Can't find public method "
1731: + method.getFullName());
1732:
1733: CallChain call = new MethodCallChain(beanMethod
1734: .getMethod());
1735: call = view.createPoolChain(call, null);
1736: call = getTransactionChain(call, beanMethod, method,
1737: prefix);
1738: call = getSecurityChain(call, beanMethod, prefix);
1739:
1740: view
1741: .addMethod(new BaseMethod(method.getMethod(),
1742: call));
1743: }
1744: }
1745: }
1746:
1747: protected void assembleHomeMethods(BeanAssembler assembler,
1748: BaseClass baseClass, String contextClassName,
1749: ApiClass homeClass, String prefix)
1750: throws NoSuchMethodException {
1751: for (ApiMethod method : homeClass.getMethods()) {
1752: String className = method.getDeclaringClass().getName();
1753: String methodName = method.getName();
1754:
1755: if (className.startsWith("javax.ejb.")) {
1756: }
1757: /*
1758: else if (isOld(methods, method, i)) {
1759: }
1760: */
1761: else if (methodName.startsWith("create")) {
1762: ApiMethod beanMethod = null;
1763:
1764: String name = ("ejbCreate"
1765: + Character.toUpperCase(methodName.charAt(0)) + methodName
1766: .substring(1));
1767:
1768: beanMethod = getEJBClassWrapper().getMethod(name,
1769: method.getParameterTypes());
1770:
1771: /*
1772: baseClass.addMethod(assembler.createCreateMethod(methods[i],
1773: contextClassName,
1774: prefix));
1775: */
1776:
1777: /*
1778: if (isStateless()) {
1779: }
1780: else {
1781: CallChain call = new MethodCallChain(beanMethod);
1782: call = getTransactionChain(call, beanMethod, prefix);
1783:
1784: baseClass.addMethod(new BaseMethod(methods[i], call));
1785: }
1786: */
1787: /*
1788: CallChain call = new MethodCallChain(beanMethod);
1789: call = getTransactionChain(call, beanMethod, prefix);
1790:
1791: baseClass.addMethod(new BaseMethod(methods[i], call));
1792: */
1793:
1794: //printCreate(methods[i], prefix);
1795: } else if (methodName.startsWith("find")) {
1796: //printFind(methods[i], prefix);
1797: } else {
1798: ApiMethod beanMethod = null;
1799:
1800: String name = ("ejbHome"
1801: + Character.toUpperCase(methodName.charAt(0)) + methodName
1802: .substring(1));
1803:
1804: beanMethod = getEJBClassWrapper().getMethod(name,
1805: method.getParameterTypes());
1806:
1807: CallChain call = new MethodCallChain(beanMethod
1808: .getMethod());
1809: call = getTransactionChain(call, beanMethod, method,
1810: prefix);
1811: call = getSecurityChain(call, beanMethod, prefix);
1812:
1813: baseClass.addMethod(new BaseMethod(method.getMethod(),
1814: call));
1815: }
1816: }
1817: }
1818:
1819: public CallChain getTransactionChain(CallChain next,
1820: ApiMethod apiMethod, ApiMethod implMethod, String prefix) {
1821: return TransactionChain.create(next, getTransactionAttribute(
1822: implMethod, prefix), apiMethod, implMethod, isEJB3(),
1823: _ejbConfig.getApplicationExceptions());
1824: }
1825:
1826: public CallChain getSecurityChain(CallChain next, ApiMethod method,
1827: String prefix) {
1828: EjbMethodPattern ejbMethod = getMethodPattern(method, prefix);
1829:
1830: ArrayList<String> roles = null;
1831:
1832: if (ejbMethod != null)
1833: roles = ejbMethod.getRoles();
1834:
1835: if (roles == null) {
1836: ejbMethod = getMethodPattern(null, prefix);
1837: if (ejbMethod != null)
1838: roles = ejbMethod.getRoles();
1839: }
1840:
1841: if (roles == null) {
1842: ejbMethod = getMethodPattern(method, null);
1843: if (ejbMethod != null)
1844: roles = ejbMethod.getRoles();
1845: }
1846:
1847: if (roles == null) {
1848: ejbMethod = getMethodPattern(null, null);
1849: if (ejbMethod != null)
1850: roles = ejbMethod.getRoles();
1851: }
1852:
1853: /*
1854: if (roles != null)
1855: return new UserInRoleChain(next, roles);
1856: else
1857: return next;
1858: */
1859: return next;
1860: }
1861:
1862: /**
1863: * Check that a method is public.
1864: *
1865: * @return the matching method
1866: */
1867: protected void validatePublicMethod(ApiMethod method)
1868: throws ConfigException {
1869: if (!method.isPublic()) {
1870: throw error(L.l("{0}: '{1}' must be public.", _ejbClass
1871: .getName(), getFullMethodName(method)));
1872: } else if (method.isStatic()) {
1873: throw error(L.l("{0}: '{1}' must not be static.", _ejbClass
1874: .getName(), getFullMethodName(method)));
1875: }
1876: }
1877:
1878: /**
1879: * True if we've already handled the method.
1880: */
1881: /*
1882: static boolean isOld(ApiMethod []methods, ApiMethod method, int index)
1883: {
1884: for (int i = 0; i < index; i++) {
1885: if (isEquiv(methods[i], method))
1886: return true;
1887: }
1888:
1889: return false;
1890: }
1891: */
1892:
1893: public static boolean isEquiv(ApiMethod oldMethod, ApiMethod method) {
1894: if (!oldMethod.getName().equals(method.getName()))
1895: return false;
1896:
1897: Class[] oldParam = oldMethod.getParameterTypes();
1898: Class[] param = method.getParameterTypes();
1899:
1900: if (oldParam.length != param.length)
1901: return false;
1902:
1903: for (int j = 0; j < param.length; j++) {
1904: if (!param[j].equals(oldParam[j]))
1905: return false;
1906: }
1907:
1908: return true;
1909: }
1910:
1911: /**
1912: * Returns the matching transaction attribute.
1913: */
1914: public TransactionAttributeType getTransactionAttribute(
1915: ApiMethod method, String intf) {
1916: if (!isContainerTransaction())
1917: return null;
1918:
1919: TransactionAttributeType transaction = TransactionAttributeType.REQUIRED;
1920:
1921: EjbMethodPattern ejbMethod = getMethodPattern(null, null);
1922:
1923: if (ejbMethod != null)
1924: transaction = ejbMethod.getTransactionType();
1925:
1926: ejbMethod = getMethodPattern(method, null);
1927:
1928: if (ejbMethod != null)
1929: transaction = ejbMethod.getTransactionType();
1930:
1931: ejbMethod = getMethodPattern(method, intf);
1932:
1933: if (ejbMethod != null)
1934: transaction = ejbMethod.getTransactionType();
1935:
1936: return transaction;
1937: }
1938:
1939: /**
1940: * Finds the method in the class.
1941: *
1942: * @param cl owning class
1943: * @param method source method
1944: *
1945: * @return the matching method or null if non matches.
1946: */
1947: public ApiMethod getMethod(String methodName, Class[] paramTypes) {
1948: return getMethod(getEJBClassWrapper(), methodName, paramTypes);
1949: }
1950:
1951: /**
1952: * Finds the method in the class.
1953: *
1954: * @param cl owning class
1955: * @param method source method
1956: *
1957: * @return the matching method or null if non matches.
1958: */
1959: public static ApiMethod getMethod(ApiClass cl,
1960: ApiMethod sourceMethod) {
1961: return getMethod(cl, sourceMethod.getName(), sourceMethod
1962: .getParameterTypes());
1963: }
1964:
1965: /**
1966: * Finds the method in the class.
1967: *
1968: * @param apiList owning class
1969: * @param name method name to match
1970: * @param params method parameters to match
1971: *
1972: * @return the matching method or null if non matches.
1973: */
1974: public static ApiMethod getMethod(ArrayList<ApiClass> apiList,
1975: String name, Class[] param) {
1976:
1977: for (int i = 0; i < apiList.size(); i++) {
1978: ApiMethod method = getMethod(apiList.get(i), name, param);
1979:
1980: if (method != null)
1981: return method;
1982: }
1983:
1984: return null;
1985: }
1986:
1987: /**
1988: * Finds the method in the class.
1989: *
1990: * @param cl owning class
1991: * @param name method name to match
1992: * @param params method parameters to match
1993: *
1994: * @return the matching method or null if non matches.
1995: */
1996: public static ApiMethod getMethod(ApiClass cl, String name,
1997: Class[] param) {
1998: return cl.getMethod(name, param);
1999: }
2000:
2001: public boolean isCMP() {
2002: return false;
2003: }
2004:
2005: public boolean isCMP1() {
2006: return false;
2007: }
2008:
2009: public boolean isEJB3() {
2010: return !(isCMP() || isCMP1());
2011: }
2012:
2013: public static boolean isMatch(ApiMethod methodA, ApiMethod methodB) {
2014: if (methodA == methodB)
2015: return true;
2016: else if (methodA == null || methodB == null)
2017: return false;
2018: else
2019: return isMatch(methodA, methodB.getName(), methodB
2020: .getParameterTypes());
2021: }
2022:
2023: public static boolean isMatch(ApiMethod method, String name,
2024: Class[] param) {
2025: if (!method.getName().equals(name))
2026: return false;
2027:
2028: Class[] mparam = method.getParameterTypes();
2029:
2030: if (mparam.length != param.length)
2031: return false;
2032:
2033: for (int j = 0; j < param.length; j++) {
2034: if (!mparam[j].equals(param[j]))
2035: return false;
2036: }
2037:
2038: return true;
2039: }
2040:
2041: /**
2042: * Finds the method in the class.
2043: *
2044: * @param cl owning class
2045: * @param name method name to match
2046: * @param params method parameters to match
2047: *
2048: * @return the matching method or null if non matches.
2049: */
2050: public static ApiMethod findMethod(MethodSignature sig,
2051: ApiClass cl, String intf) {
2052: if (cl == null)
2053: return null;
2054:
2055: for (ApiMethod method : cl.getMethods()) {
2056: if (sig.isMatch(method, intf))
2057: return method;
2058: }
2059:
2060: return null;
2061: }
2062:
2063: /**
2064: * Returns all the method in the class.
2065: */
2066: public static ArrayList<ApiMethod> getMethods(
2067: ArrayList<ApiClass> apiList) {
2068: ArrayList<ApiMethod> methodList = new ArrayList<ApiMethod>();
2069:
2070: for (ApiClass api : apiList) {
2071: for (ApiMethod method : api.getMethods()) {
2072: if (!methodList.contains(method))
2073: methodList.add(method);
2074: }
2075: }
2076:
2077: return methodList;
2078: }
2079:
2080: /**
2081: * Finds the method in the class.
2082: *
2083: * @param cl owning class
2084: * @param method source method
2085: *
2086: * @return the matching method or null if non matches.
2087: */
2088: public static ApiMethod findMethod(ArrayList<ApiMethod> methods,
2089: ApiMethod method) {
2090: loop: for (int i = 0; i < methods.size(); i++) {
2091: ApiMethod oldMethod = methods.get(i);
2092:
2093: if (oldMethod.equals(method))
2094: return oldMethod;
2095: }
2096:
2097: return null;
2098: }
2099:
2100: /**
2101: * Returns a printable version of a class.
2102: */
2103: public static String getClassName(Class cl) {
2104: if (cl == null)
2105: return "null";
2106: else if (cl.isArray())
2107: return getClassName(cl.getComponentType()) + "[]";
2108: else if (cl.getName().startsWith("java")) {
2109: int p = cl.getName().lastIndexOf('.');
2110:
2111: return cl.getName().substring(p + 1);
2112: } else
2113: return cl.getName();
2114: }
2115:
2116: /**
2117: * Returns a printable version of a class.
2118: */
2119: public static String getShortClassName(Class cl) {
2120: if (cl.isArray())
2121: return getShortClassName(cl.getComponentType()) + "[]";
2122: else
2123: return cl.getSimpleName();
2124: }
2125:
2126: /**
2127: * Tests is a method is declared in a class.
2128: */
2129: public boolean classHasMethod(ApiMethod method, ApiClass cl) {
2130: try {
2131: ApiMethod match = cl.getMethod(method.getName(), method
2132: .getParameterTypes());
2133: return match != null;
2134: } catch (Exception e) {
2135: return false;
2136: }
2137: }
2138:
2139: public void validateException(ApiMethod method, Class e)
2140: throws ConfigException {
2141: validateExceptions(method, new Class[] { e });
2142: }
2143:
2144: /**
2145: * Check that the method throws the expected exceptions.
2146: *
2147: * @param method the method to test
2148: * @param exn the expected exceptions
2149: */
2150: public void validateExceptions(ApiMethod method, Class[] exn)
2151: throws ConfigException {
2152: Class[] methodExceptions = method.getExceptionTypes();
2153:
2154: loop: for (int i = 0; i < exn.length; i++) {
2155: if (RuntimeException.class.isAssignableFrom(exn[i]))
2156: continue;
2157:
2158: for (int j = 0; j < methodExceptions.length; j++) {
2159: if (methodExceptions[j].isAssignableFrom(exn[i]))
2160: continue loop;
2161: }
2162:
2163: throw new ConfigException(L.l("{2}: '{0}' must throw {1}.",
2164: getFullMethodName(method), exn[i].getName(), method
2165: .getDeclaringClass().getName()));
2166: }
2167: }
2168:
2169: public void validateExceptions(ApiMethod caller, ApiMethod callee)
2170: throws ConfigException {
2171: Class[] exn = callee.getExceptionTypes();
2172: Class missing = findMissingException(caller, exn);
2173:
2174: if (missing != null) {
2175: throw error(L.l("{0}: '{1}' must throw {2}.", caller
2176: .getDeclaringClass().getName(),
2177: getFullMethodName(caller),
2178: getShortClassName(missing), caller
2179: .getDeclaringClass().getName())
2180: + L.l(" {0} must throw all {1}.{2} exceptions.",
2181: caller.getName(), getShortClassName(callee
2182: .getDeclaringClass()), callee
2183: .getName()));
2184: }
2185: }
2186:
2187: /**
2188: * Finds any exception in the exception array that the method isn't
2189: * throwing.
2190: *
2191: * @param method the method which should throw a superset of exceptions.
2192: * @param exn an array of exceptions the method should throw.
2193: *
2194: * @return the first missing exception
2195: */
2196: Class findMissingException(ApiMethod method, Class[] exn)
2197: throws ConfigException {
2198: Class[] methodExceptions = method.getExceptionTypes();
2199:
2200: for (int i = 0; i < exn.length; i++) {
2201: if (!hasException(method, exn[i])
2202: && !RuntimeException.class.isAssignableFrom(exn[i]))
2203: return exn[i];
2204: }
2205:
2206: return null;
2207: }
2208:
2209: public boolean hasException(ApiMethod method, Class exn)
2210: throws ConfigException {
2211: Class[] methodExceptions = method.getExceptionTypes();
2212:
2213: for (int j = 0; j < methodExceptions.length; j++) {
2214: if (methodExceptions[j].isAssignableFrom(exn))
2215: return true;
2216: }
2217:
2218: return false;
2219: }
2220:
2221: protected ApiMethod findFirstCreateMethod(ApiClass cl)
2222: throws ConfigException {
2223: for (ApiMethod method : cl.getMethods()) {
2224: if (method.getName().startsWith("create"))
2225: return method;
2226: }
2227:
2228: return null;
2229: }
2230:
2231: protected void introspectBean(ApiClass type, String defaultName)
2232: throws ConfigException {
2233: try {
2234: setEJBClassWrapper(type);
2235:
2236: String name = getEJBName();
2237:
2238: if (name == null || name.equals(""))
2239: name = defaultName;
2240:
2241: if (name == null || name.equals("")) {
2242: String className = type.getName();
2243:
2244: int p = className.lastIndexOf('.');
2245:
2246: if (p > 0)
2247: name = className.substring(p + 1);
2248: else
2249: name = className;
2250: }
2251:
2252: setEJBName(name);
2253:
2254: Local local = type.getAnnotation(Local.class);
2255: if (local != null) {
2256: Object[] values = local.value();
2257:
2258: for (int i = 0; i < values.length; i++) {
2259: if (values[i] instanceof Class) {
2260: Class localClass = (Class) values[i];
2261:
2262: setLocalWrapper(new ApiClass(localClass));
2263: } else if (values[i] instanceof Class) {
2264: setLocal((Class) values[i]);
2265: }
2266: }
2267: }
2268:
2269: Remote remote = type.getAnnotation(Remote.class);
2270: if (remote != null) {
2271: Object[] values = remote.value();
2272:
2273: for (int i = 0; i < values.length; i++) {
2274: if (values[i] instanceof Class) {
2275: Class remoteClass = (Class) values[i];
2276:
2277: setRemoteWrapper(new ApiClass(remoteClass));
2278: } else if (values[i] instanceof Class) {
2279: setRemote((Class) values[i]);
2280: }
2281: }
2282:
2283: // ejb/0f08: single interface
2284: if (values.length == 0) {
2285: // XXX: getGenericInterfaces
2286: Class[] ifs = type.getJavaClass().getInterfaces();
2287:
2288: if (ifs.length == 1)
2289: setRemoteWrapper(new ApiClass(ifs[0]));
2290: }
2291: }
2292:
2293: TransactionAttribute xa = type
2294: .getAnnotation(TransactionAttribute.class);
2295: if (xa != null) {
2296: MethodSignature sig = new MethodSignature();
2297: sig.setMethodName("*");
2298:
2299: EjbMethodPattern pattern = createMethod(sig);
2300:
2301: setPatternTransaction(pattern, xa);
2302: }
2303:
2304: configureMethods(type);
2305:
2306: /*
2307: for (int i = 0; i < _initList.size(); i++)
2308: addInitProgram(_initList.get(i).getBuilderProgram());
2309: */
2310: } catch (ConfigException e) {
2311: throw e;
2312: } catch (RuntimeException e) {
2313: throw e;
2314: } catch (Exception e) {
2315: throw ConfigException.createLine(_location, e);
2316: }
2317: }
2318:
2319: private void configureMethods(ApiClass type) throws ConfigException {
2320: for (ApiMethod method : type.getMethods()) {
2321: TransactionAttribute xa = (TransactionAttribute) method
2322: .getAnnotation(TransactionAttribute.class);
2323:
2324: if (xa != null) {
2325: EjbMethodPattern pattern = createMethod(getSignature(method));
2326:
2327: setPatternTransaction(pattern, xa);
2328: }
2329:
2330: Annotation aroundInvoke = method
2331: .getAnnotation(AroundInvoke.class);
2332:
2333: // ejb/0fb8
2334: if (aroundInvoke != null) {
2335: _aroundInvokeMethodName = method.getName();
2336: }
2337:
2338: Annotation timeout = method.getAnnotation(Timeout.class);
2339:
2340: // ejb/0fj0
2341: if (timeout != null) {
2342: _timeoutMethodName = method.getName();
2343: }
2344: }
2345: }
2346:
2347: private void setPatternTransaction(EjbMethodPattern pattern,
2348: TransactionAttribute xa) throws ConfigException {
2349: TransactionAttributeType xaType = xa.value();
2350:
2351: pattern.setTransaction(xaType);
2352: }
2353:
2354: private MethodSignature getSignature(ApiMethod method)
2355: throws ConfigException {
2356: MethodSignature sig = new MethodSignature();
2357:
2358: sig.setMethodName(method.getName());
2359:
2360: Class[] paramTypes = method.getParameterTypes();
2361:
2362: for (int i = 0; i < paramTypes.length; i++) {
2363: sig.addParam(paramTypes[i].getName());
2364: }
2365:
2366: return sig;
2367: }
2368:
2369: /**
2370: * Returns a full method name with arguments.
2371: */
2372: public static String getFullMethodName(ApiMethod method) {
2373: return getFullMethodName(method.getName(), method
2374: .getParameterTypes());
2375: }
2376:
2377: /**
2378: * Returns a full method name with arguments.
2379: */
2380: public static String getFullMethodName(String methodName,
2381: Class[] params) {
2382: String name = methodName + "(";
2383:
2384: for (int i = 0; i < params.length; i++) {
2385: if (i != 0)
2386: name += ", ";
2387:
2388: name += params[i].getSimpleName();
2389: }
2390:
2391: return name + ")";
2392: }
2393:
2394: /**
2395: * Returns an error.
2396: */
2397: public ConfigException error(String msg) {
2398: if (_isInit && _filename != null)
2399: return new LineConfigException(_filename, _line, msg);
2400: else if (_isInit && !"".equals(_location))
2401: return new LineConfigException(_location + msg);
2402: else
2403: return new ConfigException(msg);
2404: }
2405:
2406: /**
2407: * Returns an error.
2408: */
2409: public RuntimeException error(Exception e) {
2410: if (_filename != null)
2411: return LineConfigException.create(_filename, _line, e);
2412: else if (_location != null)
2413: return ConfigException.createLine(_location, e);
2414: else
2415: return ConfigException.create(e);
2416: }
2417:
2418: public String toString() {
2419: return getClass().getSimpleName() + "[" + _ejbName + "]";
2420: }
2421: }
|