0001: /*
0002: * JBoss, Home of Professional Open Source.
0003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004: * as indicated by the @author tags. See the copyright.txt file in the
0005: * distribution for a full listing of individual contributors.
0006: *
0007: * This is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU Lesser General Public License as
0009: * published by the Free Software Foundation; either version 2.1 of
0010: * the License, or (at your option) any later version.
0011: *
0012: * This software is distributed in the hope that it will be useful,
0013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015: * Lesser General Public License for more details.
0016: *
0017: * You should have received a copy of the GNU Lesser General Public
0018: * License along with this software; if not, write to the Free
0019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021: */
0022: package org.jboss.verifier.strategy;
0023:
0024: // $Id: EJBVerifier20.java 57209 2006-09-26 12:21:57Z dimitris@jboss.org $
0025:
0026: import org.jboss.logging.Logger;
0027: import org.jboss.metadata.BeanMetaData;
0028: import org.jboss.metadata.EntityMetaData;
0029: import org.jboss.metadata.MessageDrivenMetaData;
0030: import org.jboss.metadata.SessionMetaData;
0031: import org.jboss.verifier.Section;
0032:
0033: import java.lang.reflect.Method;
0034: import java.util.Arrays;
0035: import java.util.Iterator;
0036:
0037: /**
0038: * EJB 2.0 bean verifier.
0039: *
0040: * @author Juha Lindfors (jplindfo@helsinki.fi)
0041: * @author Jay Walters (jwalters@computer.org)
0042: * @author <a href="mailto:criege@riege.com">Christian Riege</a>
0043: * @author Thomas.Diesler@jboss.org
0044: *
0045: * @version $Revision: 57209 $
0046: * @since JDK 1.3
0047: */
0048: public class EJBVerifier20 extends AbstractEJB2xVerifier {
0049: private static Logger log = Logger.getLogger(EJBVerifier20.class);
0050:
0051: /*
0052: * Constructor
0053: */
0054: public EJBVerifier20(VerificationContext context) {
0055: super (context);
0056: }
0057:
0058: public String getMessageBundle() {
0059: return "EJB20Messages.properties";
0060: }
0061:
0062: /***********************************************************************
0063: *
0064: * IMPLEMENTS VERIFICATION STRATEGY INTERFACE
0065: *
0066: ************************************************************************/
0067: public void checkSession(SessionMetaData session) {
0068: boolean localOrRemoteExists = false;
0069: boolean verified = false;
0070:
0071: if (!verifyBean(session))
0072: return;
0073:
0074: verified = verifySessionBean(session);
0075:
0076: if (hasRemoteInterfaces(session)) {
0077: // Check remote interfaces
0078: localOrRemoteExists = true;
0079: verified = verified && verifySessionRemote(session);
0080: verified = verified && verifySessionHome(session);
0081: }
0082:
0083: if (hasLocalInterfaces(session)) {
0084: // Check local interfaces
0085: localOrRemoteExists = true;
0086: verified = verified && verifySessionLocal(session);
0087: verified = verified && verifySessionLocalHome(session);
0088: }
0089:
0090: // The session bean MUST implement either a remote home and
0091: // remote, or local home and local interface. It MAY implement a
0092: // remote home, remote, local home or local interface.
0093: //
0094: // Spec 7.10.1
0095: //
0096: if (!localOrRemoteExists) {
0097: fireSpecViolationEvent(session, new Section("7.10.1"));
0098: verified = false;
0099: }
0100:
0101: if (verified) {
0102: // All OK; full steam ahead
0103: fireBeanVerifiedEvent(session);
0104: }
0105: }
0106:
0107: public void checkEntity(EntityMetaData entity) {
0108: if (entity.isCMP1x()) {
0109: cmp1XVerifier.checkEntity(entity);
0110: } else {
0111: checkBmpOrCmp2Entity(entity);
0112: }
0113: }
0114:
0115: public void checkMessageBean(MessageDrivenMetaData mdb) {
0116: boolean beanVerified = false;
0117:
0118: if (!verifyBean(mdb))
0119: return;
0120:
0121: beanVerified = verifyMessageDrivenBean(mdb);
0122:
0123: if (beanVerified) {
0124: // OK, we're done
0125: fireBeanVerifiedEvent(mdb);
0126: }
0127: }
0128:
0129: private void checkBmpOrCmp2Entity(EntityMetaData entity) {
0130: boolean localOrRemoteExists = false;
0131: boolean verified = false;
0132:
0133: if (!verifyBean(entity))
0134: return;
0135:
0136: if (entity.isCMP()) {
0137: verified = verifyCMPEntityBean(entity);
0138: } else if (entity.isBMP()) {
0139: verified = verifyBMPEntityBean(entity);
0140: }
0141:
0142: if (hasRemoteInterfaces(entity)) {
0143: // Check remote interfaces
0144: localOrRemoteExists = true;
0145: verified = verified && verifyEntityRemote(entity);
0146: verified = verified && verifyEntityHome(entity);
0147: }
0148:
0149: if (hasLocalInterfaces(entity)) {
0150: // Check local interfaces
0151: localOrRemoteExists = true;
0152: verified = verified && verifyEntityLocal(entity);
0153: verified = verified && verifyEntityLocalHome(entity);
0154: }
0155:
0156: verified = verified && verifyPrimaryKey(entity);
0157:
0158: if (!localOrRemoteExists) {
0159: // The entity bean MUST implement either a remote home and
0160: // remote, or local home and local interface. It MAY implement
0161: // a remote home, remote, local home or local interface.
0162: //
0163: // Spec 10.6.1 (CMP) / 12.2.1 (BMP)
0164: //
0165: if (entity.isCMP()) {
0166: fireSpecViolationEvent(entity, new Section("10.6.1"));
0167: verified = false;
0168: } else {
0169: fireSpecViolationEvent(entity, new Section("12.2.1"));
0170: verified = false;
0171: }
0172: }
0173:
0174: if (verified) {
0175: fireBeanVerifiedEvent(entity);
0176: }
0177: }
0178:
0179: /**
0180: * Try to load the beans class declared in the <ejb-class>
0181: * element.
0182: *
0183: * @return <code>true</code> if everything went alright
0184: */
0185: protected boolean verifyBean(BeanMetaData theBean) {
0186: String beanName = theBean.getEjbClass();
0187:
0188: if (beanName == null)
0189: return false;
0190:
0191: try {
0192: bean = classloader.loadClass(beanName);
0193: return true;
0194: } catch (ClassNotFoundException cnfe) {
0195: fireSpecViolationEvent(theBean, new Section("22.2.b",
0196: "Class not found on '" + beanName + "': "
0197: + cnfe.getMessage()));
0198: return false;
0199: }
0200: }
0201:
0202: /**
0203: * Check whether the bean has declared local interfaces and whether
0204: * we can load the defined classes
0205: *
0206: * @return <code>true</code> if everything went alright
0207: */
0208: protected boolean hasRemoteInterfaces(BeanMetaData bean) {
0209: boolean status = true;
0210: String homeName = bean.getHome();
0211: String remoteName = bean.getRemote();
0212:
0213: if (homeName == null || remoteName == null)
0214: return false;
0215:
0216: // Verify the <home> class
0217: try {
0218: home = classloader.loadClass(homeName);
0219: } catch (ClassNotFoundException cnfe) {
0220: fireSpecViolationEvent(bean, new Section("22.2.c",
0221: "Class not found on '" + homeName + "': "
0222: + cnfe.getMessage()));
0223: status = false;
0224: }
0225:
0226: // Verify the <remote> class
0227: try {
0228: remote = classloader.loadClass(remoteName);
0229: } catch (ClassNotFoundException cnfe) {
0230: fireSpecViolationEvent(bean, new Section("22.2.d",
0231: "Class not found on '" + remoteName + "': "
0232: + cnfe.getMessage()));
0233: status = false;
0234: }
0235:
0236: return status;
0237: }
0238:
0239: /**
0240: * Check whether the bean has declared local interfaces and whether
0241: * we can load the defined classes
0242: *
0243: * @return <code>true</code> if everything went alright
0244: */
0245: protected boolean hasLocalInterfaces(BeanMetaData bean) {
0246: boolean status = true;
0247: String localHomeName = bean.getLocalHome();
0248: String localName = bean.getLocal();
0249:
0250: if (localHomeName == null || localName == null)
0251: return false;
0252:
0253: // Verify the <local-home> class
0254: try {
0255: localHome = classloader.loadClass(localHomeName);
0256: } catch (ClassNotFoundException cnfe) {
0257: fireSpecViolationEvent(bean, new Section("22.2.e",
0258: "Class not found on '" + localHomeName + "': "
0259: + cnfe.getMessage()));
0260: status = false;
0261: }
0262:
0263: try {
0264: local = classloader.loadClass(localName);
0265: } catch (ClassNotFoundException cnfe) {
0266: fireSpecViolationEvent(bean, new Section("22.2.f",
0267: "Class not found on '" + localName + "': "
0268: + cnfe.getMessage()));
0269: status = false;
0270: }
0271:
0272: return status;
0273: }
0274:
0275: /**
0276: * Verifies the session bean remote home interface against the EJB 2.0
0277: * specification.
0278: *
0279: * @param session XML metadata of the session bean
0280: */
0281: protected boolean verifySessionHome(SessionMetaData session) {
0282: boolean status = true;
0283:
0284: // The home interface of a stateless session bean MUST have one
0285: // create() method that takes no arguments.
0286: //
0287: // The create() method MUST return the session bean's remote
0288: // interface.
0289: //
0290: // There CAN NOT be other create() methods in the home interface.
0291: //
0292: // Spec 7.10.6
0293: //
0294: if (session.isStateless()) {
0295: if (!hasDefaultCreateMethod(home)) {
0296: fireSpecViolationEvent(session,
0297: new Section("7.10.6.d2"));
0298: status = false;
0299: } else {
0300: Method create = getDefaultCreateMethod(home);
0301:
0302: if (hasMoreThanOneCreateMethods(home)) {
0303: fireSpecViolationEvent(session, new Section(
0304: "7.10.6.d2"));
0305: status = false;
0306: }
0307: }
0308: }
0309:
0310: // The session bean's home interface MUST extend the
0311: // javax.ejb.EJBHome interface.
0312: //
0313: // Spec 7.10.6
0314: //
0315: if (!hasEJBHomeInterface(home)) {
0316: fireSpecViolationEvent(session, new Section("7.10.6.a"));
0317: status = false;
0318: }
0319:
0320: // Method arguments defined in the home interface MUST be
0321: // of valid types for RMI/IIOP.
0322: //
0323: // Method return values defined in the home interface MUST
0324: // be of valid types for RMI/IIOP.
0325: //
0326: // Methods defined in the home interface MUST include
0327: // java.rmi.RemoteException in their throws clause.
0328: //
0329: // Spec 7.10.6
0330: ///
0331: Iterator it = Arrays.asList(home.getMethods()).iterator();
0332: while (it.hasNext()) {
0333: Method method = (Method) it.next();
0334:
0335: if (!hasLegalRMIIIOPArguments(method)) {
0336: fireSpecViolationEvent(session, method, new Section(
0337: "7.10.6.b1"));
0338: status = false;
0339: }
0340:
0341: if (!hasLegalRMIIIOPReturnType(method)) {
0342: fireSpecViolationEvent(session, method, new Section(
0343: "7.10.6.b2"));
0344: status = false;
0345: }
0346:
0347: if (!throwsRemoteException(method)) {
0348: fireSpecViolationEvent(session, method, new Section(
0349: "7.10.6.b3"));
0350: status = false;
0351: }
0352: }
0353:
0354: // A session bean's home interface MUST define one or more
0355: // create(...) methods.
0356: //
0357: // Spec 7.10.6
0358: //
0359: if (!hasCreateMethod(home)) {
0360: fireSpecViolationEvent(session, new Section("7.10.6.d1"));
0361: status = false;
0362: }
0363:
0364: // Each create(...) method in the session bean's home interface
0365: // MUST have a matching ejbCreate(...) method in the session
0366: // bean's class.
0367: //
0368: // Each create(...) method in the session bean's home interface
0369: // MUST have the same number and types of arguments to its
0370: // matching ejbCreate(...) method.
0371: //
0372: // The return type for a create(...) method MUST be the session
0373: // bean's remote interface type.
0374: //
0375: // All the exceptions defined in the throws clause of the matching
0376: // ejbCreate(...) method of the enterprise bean class MUST be
0377: // included in the throws clause of a matching create(...) method.
0378: //
0379: // The throws clause of a create(...) method MUST include the
0380: // javax.ejb.CreateException.
0381: //
0382: // Spec 7.10.6
0383: //
0384: Iterator createMethods = getCreateMethods(home);
0385: while (createMethods.hasNext()) {
0386: Method create = (Method) createMethods.next();
0387:
0388: if (!hasMatchingEJBCreate(bean, create)) {
0389: fireSpecViolationEvent(session, create, new Section(
0390: "7.10.6.e"));
0391: status = false;
0392: }
0393:
0394: if (!hasRemoteReturnType(session, create)) {
0395: fireSpecViolationEvent(session, create, new Section(
0396: "7.10.6.f"));
0397: status = false;
0398: }
0399:
0400: if (hasMatchingEJBCreate(bean, create)) {
0401: Method ejbCreate = getMatchingEJBCreate(bean, create);
0402: if (!hasMatchingExceptions(ejbCreate, create)) {
0403: fireSpecViolationEvent(session, create,
0404: new Section("7.10.6.g"));
0405: status = false;
0406: }
0407: }
0408:
0409: if (!throwsCreateException(create)) {
0410: fireSpecViolationEvent(session, create, new Section(
0411: "7.10.6.h"));
0412: status = false;
0413: }
0414: }
0415:
0416: return status;
0417: }
0418:
0419: /**
0420: * Verifies the session bean local home interface against the EJB 2.0
0421: * specification.
0422: *
0423: * @param session parsed metadata of the session bean
0424: */
0425: protected boolean verifySessionLocalHome(SessionMetaData session) {
0426: boolean status = true;
0427:
0428: // The local home interface of a stateless session bean MUST have
0429: // one create() method that takes no arguments.
0430: //
0431: // There CAN NOT be other create() methods in the home interface.
0432: //
0433: // Spec 7.10.8
0434: //
0435: if (session.isStateless()) {
0436: if (!hasDefaultCreateMethod(localHome)) {
0437: fireSpecViolationEvent(session,
0438: new Section("7.10.8.d2"));
0439: status = false;
0440: } else {
0441: Method create = getDefaultCreateMethod(localHome);
0442:
0443: if (hasMoreThanOneCreateMethods(localHome)) {
0444: fireSpecViolationEvent(session, new Section(
0445: "7.10.8.d2"));
0446: status = false;
0447: }
0448: }
0449: }
0450:
0451: // The session bean's home interface MUST extend the
0452: // javax.ejb.EJBLocalHome interface.
0453: //
0454: // Spec 7.10.8
0455: //
0456: if (!hasEJBLocalHomeInterface(localHome)) {
0457: fireSpecViolationEvent(session, new Section("7.10.8.a"));
0458: status = false;
0459: }
0460:
0461: // Methods defined in the local home interface MUST NOT include
0462: // java.rmi.RemoteException in their throws clause.
0463: //
0464: // Spec 7.10.8
0465: //
0466: Iterator it = Arrays.asList(localHome.getMethods()).iterator();
0467: while (it.hasNext()) {
0468: Method method = (Method) it.next();
0469:
0470: if (throwsRemoteException(method)) {
0471: fireSpecViolationEvent(session, method, new Section(
0472: "7.10.8.b"));
0473: status = false;
0474: }
0475: }
0476:
0477: // A session bean's home interface MUST define one or more
0478: // create(...) methods.
0479: //
0480: // Spec 7.10.8
0481: //
0482: if (!hasCreateMethod(localHome)) {
0483: fireSpecViolationEvent(session, new Section("7.10.8.d1"));
0484: status = false;
0485: }
0486:
0487: // Each create(...) method in the session bean's local home
0488: // interface MUST have a matching ejbCreate(...) method in the
0489: // session bean's class.
0490: //
0491: // Each create(...) method in the session bean's home interface
0492: // MUST have the same number and types of arguments to its
0493: // matching ejbCreate(...) method.
0494: //
0495: // The return type for a create(...) method MUST be the session
0496: // bean's local interface type.
0497: //
0498: // All the exceptions defined in the throws clause of the matching
0499: // ejbCreate(...) method of the enterprise bean class MUST be
0500: // included in the throws clause of a matching create(...) method.
0501: //
0502: // The throws clause of a create(...) method MUST include the
0503: // javax.ejb.CreateException.
0504: //
0505: // Spec 7.10.8
0506: //
0507: Iterator createMethods = getCreateMethods(localHome);
0508: while (createMethods.hasNext()) {
0509: Method create = (Method) createMethods.next();
0510:
0511: if (!hasMatchingEJBCreate(bean, create)) {
0512: fireSpecViolationEvent(session, create, new Section(
0513: "7.10.8.e"));
0514: status = false;
0515: }
0516:
0517: if (!hasLocalReturnType(session, create)) {
0518: fireSpecViolationEvent(session, create, new Section(
0519: "7.10.8.f"));
0520: status = false;
0521: }
0522:
0523: if (hasMatchingEJBCreate(bean, create)) {
0524: Method ejbCreate = getMatchingEJBCreate(bean, create);
0525: if (!hasMatchingExceptions(ejbCreate, create)) {
0526: fireSpecViolationEvent(session, create,
0527: new Section("7.10.8.g"));
0528: }
0529: }
0530:
0531: if (!throwsCreateException(create)) {
0532: fireSpecViolationEvent(session, create, new Section(
0533: "7.10.8.h"));
0534: status = false;
0535: }
0536: }
0537:
0538: return status;
0539: }
0540:
0541: /*
0542: * Verify Session Bean Remote Interface
0543: */
0544: protected boolean verifySessionRemote(SessionMetaData session) {
0545: boolean status = true;
0546:
0547: // The remote interface MUST extend the javax.ejb.EJBObject
0548: // interface.
0549: //
0550: // Spec 7.10.5
0551: //
0552: if (!hasEJBObjectInterface(remote)) {
0553: fireSpecViolationEvent(session, new Section("7.10.5.a"));
0554: status = false;
0555: }
0556:
0557: // Method arguments defined in the remote interface MUST be
0558: // of valid types for RMI/IIOP.
0559: //
0560: // Method return values defined in the remote interface MUST
0561: // be of valid types for RMI/IIOP.
0562: //
0563: // Methods defined in the remote interface MUST include
0564: // java.rmi.RemoteException in their throws clause.
0565: //
0566: // Spec 7.10.5
0567: //
0568: Iterator it = Arrays.asList(remote.getMethods()).iterator();
0569: while (it.hasNext()) {
0570: Method method = (Method) it.next();
0571:
0572: if (!hasLegalRMIIIOPArguments(method)) {
0573: fireSpecViolationEvent(session, method, new Section(
0574: "7.10.5.b1"));
0575: status = false;
0576: }
0577:
0578: if (!hasLegalRMIIIOPReturnType(method)) {
0579: fireSpecViolationEvent(session, method, new Section(
0580: "7.10.5.b2"));
0581: status = false;
0582: }
0583:
0584: if (!throwsRemoteException(method)) {
0585: fireSpecViolationEvent(session, method, new Section(
0586: "7.10.5.b3"));
0587: status = false;
0588: }
0589: }
0590:
0591: // For each method defined in the remote interface, there MUST be
0592: // a matching method in the session bean's class. The matching
0593: // method MUST have:
0594: //
0595: // - the same name
0596: // - the same number and types of arguments, and the same
0597: // return type
0598: // - All the exceptions defined in the throws clause of the
0599: // matching method of the session bean class must be defined
0600: // in the throws clause of the method of the remote interface
0601: //
0602: // Spec 7.10.5
0603: //
0604: it = Arrays.asList(remote.getDeclaredMethods()).iterator();
0605: while (it.hasNext()) {
0606: Method remoteMethod = (Method) it.next();
0607:
0608: if (!hasMatchingMethod(bean, remoteMethod)) {
0609: fireSpecViolationEvent(session, remoteMethod,
0610: new Section("7.10.5.d1"));
0611:
0612: status = false;
0613: }
0614:
0615: if (hasMatchingMethod(bean, remoteMethod)) {
0616: try {
0617: Method beanMethod = bean.getMethod(remoteMethod
0618: .getName(), remoteMethod
0619: .getParameterTypes());
0620:
0621: if (!hasMatchingReturnType(remoteMethod, beanMethod)) {
0622: fireSpecViolationEvent(session, remoteMethod,
0623: new Section("7.10.5.d2"));
0624: status = false;
0625: }
0626:
0627: if (!hasMatchingExceptions(beanMethod, remoteMethod)) {
0628: fireSpecViolationEvent(session, remoteMethod,
0629: new Section("7.10.5.d3"));
0630: status = false;
0631: }
0632: } catch (NoSuchMethodException ignored) {
0633: }
0634: }
0635: }
0636:
0637: return status;
0638: }
0639:
0640: /*
0641: * Verify Session Bean Local Interface
0642: */
0643: protected boolean verifySessionLocal(SessionMetaData session) {
0644: boolean status = true;
0645:
0646: // The local interface MUST extend the javax.ejb.EJBLocalObject
0647: // interface.
0648: //
0649: // Spec 7.10.7
0650: //
0651: if (!hasEJBLocalObjectInterface(local)) {
0652: fireSpecViolationEvent(session, new Section("7.10.7.a"));
0653: status = false;
0654: }
0655:
0656: // Methods defined in the local interface MUST NOT include
0657: // java.rmi.RemoteException in their throws clause.
0658: //
0659: // Spec 7.10.7
0660: //
0661: Iterator it = Arrays.asList(local.getMethods()).iterator();
0662: while (it.hasNext()) {
0663: Method method = (Method) it.next();
0664: if (throwsRemoteException(method)) {
0665: fireSpecViolationEvent(session, method, new Section(
0666: "7.10.7.b"));
0667: status = false;
0668: }
0669: }
0670:
0671: // For each method defined in the local interface, there MUST be
0672: // a matching method in the session bean's class. The matching
0673: // method MUST have:
0674: //
0675: // - the same name
0676: // - the same number and types of arguments, and the same
0677: // return type
0678: // - All the exceptions defined in the throws clause of the
0679: // matching method of the session bean class must be defined
0680: // in the throws clause of the method of the remote interface
0681: //
0682: // Spec 7.10.7
0683: //
0684: it = Arrays.asList(local.getDeclaredMethods()).iterator();
0685: while (it.hasNext()) {
0686: Method localMethod = (Method) it.next();
0687:
0688: if (!hasMatchingMethod(bean, localMethod)) {
0689: fireSpecViolationEvent(session, localMethod,
0690: new Section("7.10.7.d1"));
0691: status = false;
0692: }
0693:
0694: if (hasMatchingMethod(bean, localMethod)) {
0695: try {
0696: Method beanMethod = bean
0697: .getMethod(localMethod.getName(),
0698: localMethod.getParameterTypes());
0699:
0700: if (!hasMatchingReturnType(localMethod, beanMethod)) {
0701: fireSpecViolationEvent(session, localMethod,
0702: new Section("7.10.7.d2"));
0703: status = false;
0704: }
0705:
0706: if (!hasMatchingExceptions(beanMethod, localMethod)) {
0707: fireSpecViolationEvent(session, localMethod,
0708: new Section("7.10.7.d3"));
0709: status = false;
0710: }
0711: } catch (NoSuchMethodException ignored) {
0712: }
0713: }
0714: }
0715:
0716: return status;
0717: }
0718:
0719: /*
0720: * Verify Session Bean
0721: */
0722: protected boolean verifySessionBean(SessionMetaData session) {
0723: boolean status = true;
0724:
0725: // A session bean MUST implement, directly or indirectly,
0726: // javax.ejb.SessionBean interface.
0727: //
0728: // Spec 7.10.2
0729: //
0730: if (!hasSessionBeanInterface(bean)) {
0731: fireSpecViolationEvent(session, new Section("7.10.2.a"));
0732: status = false;
0733: }
0734:
0735: // Only a stateful container-managed transaction demarcation
0736: // session bean MAY implement the SessionSynchronization
0737: // interface.
0738: //
0739: // A stateless Session bean MUST NOT implement the
0740: // SessionSynchronization interface.
0741: //
0742: // Spec 7.5.3
0743: //
0744: if (hasSessionSynchronizationInterface(bean)) {
0745: if (session.isStateless()) {
0746: fireSpecViolationEvent(session, new Section("7.5.3.a"));
0747: status = false;
0748: }
0749:
0750: if (session.isBeanManagedTx()) {
0751: fireSpecViolationEvent(session, new Section("7.5.3.b"));
0752: status = false;
0753: }
0754: }
0755:
0756: //
0757: // A session bean MUST implement AT LEAST one ejbCreate method.
0758: //
0759: // Spec 7.10.3
0760: //
0761: if (!hasEJBCreateMethod(bean, true)) {
0762: fireSpecViolationEvent(session, new Section("7.10.3"));
0763: status = false;
0764: }
0765:
0766: // A session with bean-managed transaction demarcation CANNOT
0767: // implement the SessionSynchronization interface.
0768: //
0769: // Spec 7.6.1 (table 2)
0770: //
0771: if (hasSessionSynchronizationInterface(bean)
0772: && session.isBeanManagedTx()) {
0773: fireSpecViolationEvent(session, new Section("7.6.1"));
0774: status = false;
0775: }
0776:
0777: // The session bean class MUST be defined as public.
0778: //
0779: // Spec 7.10.2
0780: //
0781: if (!isPublic(bean)) {
0782: fireSpecViolationEvent(session, new Section("7.10.2.b1"));
0783: status = false;
0784: }
0785:
0786: // The session bean class MUST NOT be final.
0787: //
0788: // Spec 7.10.2
0789: //
0790: if (isFinal(bean)) {
0791: fireSpecViolationEvent(session, new Section("7.10.2.b2"));
0792: status = false;
0793: }
0794:
0795: // The session bean class MUST NOT be abstract.
0796: //
0797: // Spec 7.10.2
0798: //
0799: if (isAbstract(bean)) {
0800: fireSpecViolationEvent(session, new Section("7.10.2.b3"));
0801: status = false;
0802: }
0803:
0804: // The session bean class MUST have a public constructor that
0805: // takes no arguments.
0806: //
0807: // Spec 7.10.2
0808: //
0809: if (!hasDefaultConstructor(bean)) {
0810: fireSpecViolationEvent(session, new Section("7.10.2.c"));
0811: status = false;
0812: }
0813:
0814: // The session bean class MUST NOT define the finalize() method.
0815: //
0816: // Spec 7.10.2
0817: //
0818: if (hasFinalizer(bean)) {
0819: fireSpecViolationEvent(session, new Section("7.10.2.d"));
0820: status = false;
0821: }
0822:
0823: // The ejbCreate(...) method signatures MUST follow these rules:
0824: //
0825: // - The method name MUST have ejbCreate as its prefix
0826: // - The method MUST be declared as public
0827: // - The method MUST NOT be declared as final or static
0828: // - The return type MUST be void
0829: // - The method arguments MUST be legal types for RMI/IIOP
0830: // - The method SHOULD not throw a java.rmi.RemoteException
0831: // (NOTE we don't test for this as it's not a MUST)
0832: //
0833: // Spec 7.10.3
0834: //
0835: if (hasEJBCreateMethod(bean, true)) {
0836: Iterator it = getEJBCreateMethods(bean);
0837: while (it.hasNext()) {
0838: Method ejbCreate = (Method) it.next();
0839:
0840: if (!isPublic(ejbCreate)) {
0841: fireSpecViolationEvent(session, ejbCreate,
0842: new Section("7.10.3.b"));
0843: status = false;
0844: }
0845:
0846: if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
0847: fireSpecViolationEvent(session, ejbCreate,
0848: new Section("7.10.3.c"));
0849: status = false;
0850: }
0851:
0852: if (!hasVoidReturnType(ejbCreate)) {
0853: fireSpecViolationEvent(session, ejbCreate,
0854: new Section("7.10.3.d"));
0855: status = false;
0856: }
0857:
0858: if (!hasLegalRMIIIOPArguments(ejbCreate)) {
0859: fireSpecViolationEvent(session, ejbCreate,
0860: new Section("7.10.3.e"));
0861: status = false;
0862: }
0863: }
0864: }
0865:
0866: return status;
0867: }
0868:
0869: /*
0870: * Verify Entity Bean Home Interface
0871: */
0872: private boolean verifyEntityHome(EntityMetaData entity) {
0873: boolean status = true;
0874:
0875: // Entity bean's home interface MUST extend the javax.ejb.EJBHome
0876: // interface.
0877: //
0878: // Spec 12.2.9
0879: //
0880: if (!hasEJBHomeInterface(home)) {
0881: fireSpecViolationEvent(entity, new Section("12.2.9.a"));
0882: status = false;
0883: }
0884:
0885: // The methods defined in the entity bean's home interface MUST
0886: // have valid RMI-IIOP argument types.
0887: //
0888: // The methods defined in the entity bean's home interface MUST
0889: // have valid RMI-IIOP return types.
0890: //
0891: // The methods defined in the entity bean's home interface MUST
0892: // have java.rmi.RemoteException in their throws clause.
0893: //
0894: // Spec 12.2.9
0895: //
0896: Iterator methods = Arrays.asList(home.getMethods()).iterator();
0897: while (methods.hasNext()) {
0898: Method method = (Method) methods.next();
0899:
0900: if (!hasLegalRMIIIOPArguments(method)) {
0901: fireSpecViolationEvent(entity, method, new Section(
0902: "12.2.9.b1"));
0903: status = false;
0904: }
0905:
0906: if (!hasLegalRMIIIOPReturnType(method)) {
0907: fireSpecViolationEvent(entity, method, new Section(
0908: "12.2.9.b2"));
0909: status = false;
0910: }
0911:
0912: if (!throwsRemoteException(method)) {
0913: fireSpecViolationEvent(entity, method, new Section(
0914: "12.2.9.b3"));
0915: status = false;
0916: }
0917: }
0918:
0919: // Each method defined in the entity bean's home interface must be
0920: // one of the following:
0921: //
0922: // - a create method
0923: // - a finder method
0924: // - a home method
0925: //
0926: // Spec 12.2.9
0927: //
0928: methods = Arrays.asList(home.getMethods()).iterator();
0929: while (methods.hasNext()) {
0930: Method method = (Method) methods.next();
0931:
0932: // Do not check the methods of the javax.ejb.EJBHome interface
0933: if (method.getDeclaringClass().getName().equals(
0934: EJB_HOME_INTERFACE))
0935: continue;
0936:
0937: if (isCreateMethod(method)) {
0938: // Each create(...) method in the entity bean's home
0939: // interface MUST have a matching ejbCreate(...) method in
0940: // the entity bean's class.
0941: //
0942: // Each create(...) method in the entity bean's home
0943: // interface MUST have the same number and types of
0944: // arguments to its matching ejbCreate(...) method.
0945: //
0946: // The return type for a create(...) method MUST be the
0947: // entity bean's remote interface type.
0948: //
0949: // All the exceptions defined in the throws clause of the
0950: // matching ejbCreate(...) and ejbPostCreate(...) methods of
0951: // the enterprise bean class MUST be included in the throws
0952: // clause of a matching create(...) method.
0953: //
0954: // The throws clause of a create(...) method MUST include
0955: // the javax.ejb.CreateException.
0956: //
0957: // Spec 12.2.9
0958: //
0959: if (!hasMatchingEJBCreate(bean, method)) {
0960: fireSpecViolationEvent(entity, method, new Section(
0961: "12.2.9.d"));
0962: status = false;
0963: }
0964:
0965: if (!hasRemoteReturnType(entity, method)) {
0966: fireSpecViolationEvent(entity, method, new Section(
0967: "12.2.9.e"));
0968: status = false;
0969: }
0970:
0971: if (hasMatchingEJBCreate(bean, method)
0972: && hasMatchingEJBPostCreate(bean, method)) {
0973: Method ejbCreate = getMatchingEJBCreate(bean,
0974: method);
0975: Method ejbPostCreate = getMatchingEJBPostCreate(
0976: bean, method);
0977:
0978: if (!(hasMatchingExceptions(ejbCreate, method) && hasMatchingExceptions(
0979: ejbPostCreate, method))) {
0980: fireSpecViolationEvent(entity, method,
0981: new Section("12.2.9.f"));
0982: }
0983: }
0984:
0985: if (!throwsCreateException(method)) {
0986: fireSpecViolationEvent(entity, method, new Section(
0987: "12.2.9.g"));
0988: status = false;
0989: }
0990: } else if (isFinderMethod(method)) {
0991: // Each finder method MUST match one of the ejbFind<METHOD>
0992: // methods defined in the entity bean class.
0993: //
0994: // The matching ejbFind<METHOD> method MUST have the same
0995: // number and types of arguments.
0996: //
0997: // The return type for a find<METHOD> method MUST be the
0998: // entity bean's remote interface type (single-object
0999: // finder) or a collection thereof (for a multi-object
1000: // finder).
1001: //
1002: // All the exceptions defined in the throws clause of an
1003: // ejbFind method of the entity bean class MUST be included
1004: // in the throws clause of the matching find method of the
1005: // home interface.
1006: //
1007: // The throws clause of a finder method MUST include the
1008: // javax.ejb.FinderException.
1009: //
1010: // Spec 12.2.9
1011: //
1012: if (entity.isBMP()) { // Check for BMP violations
1013: if ((!hasMatchingEJBFind(bean, method))) {
1014: fireSpecViolationEvent(entity, method,
1015: new Section("12.2.9.h"));
1016: status = false;
1017: }
1018:
1019: if (!(hasRemoteReturnType(entity, method) || isMultiObjectFinder(method))) {
1020: fireSpecViolationEvent(entity, method,
1021: new Section("12.2.9.j"));
1022: status = false;
1023: }
1024:
1025: if ((hasMatchingEJBFind(bean, method))) {
1026: Method ejbFind = getMatchingEJBFind(bean,
1027: method);
1028: if (!(hasMatchingExceptions(ejbFind, method))) {
1029: fireSpecViolationEvent(entity, method,
1030: new Section("12.2.9.k"));
1031: status = false;
1032: }
1033: }
1034:
1035: if (!throwsFinderException(method)) {
1036: fireSpecViolationEvent(entity, method,
1037: new Section("12.2.9.l"));
1038: status = false;
1039: }
1040: } // if( entity.isBMP() )
1041:
1042: if (entity.isCMP()) {
1043:
1044: if (!(hasRemoteReturnType(entity, method) || isMultiObjectFinder(method))) {
1045: fireSpecViolationEvent(entity, method,
1046: new Section("10.6.10.a"));
1047: status = false;
1048: }
1049:
1050: if (!throwsFinderException(method)) {
1051: fireSpecViolationEvent(entity, method,
1052: new Section("10.6.10.b"));
1053: status = false;
1054: }
1055:
1056: // For every finder method there must be a matching
1057: // <query> element defined in the deployment descriptor
1058: // with the exception of findByPrimaryKey
1059: //
1060: // JBoss Extension: 'findAll' is _also_ ignored.
1061: //
1062: if (!method.getName().equals("findByPrimaryKey")
1063: && !method.getName().equals("findAll")
1064: && !hasMatchingQuery(method, entity)) {
1065: fireSpecViolationEvent(entity, method,
1066: new Section("10.5.6"));
1067: status = false;
1068: }
1069: } // if( entity.isCMP() )
1070: } else // Neither Create nor Finder method
1071: {
1072: // Each home method MUST match a method defined in the
1073: // entity bean class.
1074: //
1075: // The matching ejbHome<METHOD> method MUST have the same
1076: // number and types of arguments, and a matching return
1077: // type.
1078: //
1079: // Spec 12.2.9
1080: //
1081: if (!hasMatchingEJBHome(bean, method)) {
1082: fireSpecViolationEvent(entity, method, new Section(
1083: "12.2.9.m"));
1084: status = false;
1085: }
1086: }
1087: } // while( methods.hasNext() )
1088:
1089: return status;
1090: }
1091:
1092: /*
1093: * Verify Entity Bean Local Home Interface
1094: */
1095: private boolean verifyEntityLocalHome(EntityMetaData entity) {
1096: boolean status = true;
1097:
1098: // Entity bean's local home interface MUST extend the
1099: // javax.ejb.EJBLocalHome interface.
1100: //
1101: // Spec 12.2.11
1102: //
1103: if (!hasEJBLocalHomeInterface(localHome)) {
1104: fireSpecViolationEvent(entity, new Section("12.2.11.a"));
1105: status = false;
1106: }
1107:
1108: // The methods defined in the entity bean's home interface MUST
1109: // NOT have java.rmi.RemoteException in their throws clause.
1110: //
1111: // Spec 12.2.11
1112: //
1113: Iterator homeMethods = Arrays.asList(localHome.getMethods())
1114: .iterator();
1115: while (homeMethods.hasNext()) {
1116: Method method = (Method) homeMethods.next();
1117:
1118: if (throwsRemoteException(method)) {
1119: fireSpecViolationEvent(entity, method, new Section(
1120: "12.2.11.b"));
1121: status = false;
1122: }
1123: }
1124:
1125: // Each method defined in the entity bean's local home interface
1126: // must be one of the following:
1127: //
1128: // - a create method
1129: // - a finder method
1130: // - a home method
1131: //
1132: // Spec 12.2.11
1133: //
1134: homeMethods = Arrays.asList(localHome.getMethods()).iterator();
1135: while (homeMethods.hasNext()) {
1136: Method method = (Method) homeMethods.next();
1137:
1138: // Do not check the methods of the javax.ejb.EJBLocalHome interface
1139: if (method.getDeclaringClass().getName().equals(
1140: EJB_LOCAL_HOME_INTERFACE))
1141: continue;
1142:
1143: if (isCreateMethod(method)) {
1144: // Each create(...) method in the entity bean's local home
1145: // interface MUST have a matching ejbCreate(...) method in
1146: // the entity bean's class.
1147: //
1148: // Each create(...) method in the entity bean's local home
1149: // interface MUST have the same number and types of
1150: // arguments to its matching ejbCreate(...) method.
1151: //
1152: // The return type for a create(...) method MUST be the
1153: // entity bean's local interface type.
1154: //
1155: // All the exceptions defined in the throws clause of the
1156: // matching ejbCreate(...) and ejbPostCreate(...) methods of
1157: // the enterprise bean class MUST be included in the throws
1158: // clause of a matching create(...) method.
1159: //
1160: // The throws clause of a create(...) method MUST include
1161: // the javax.ejb.CreateException.
1162: //
1163: // Spec 12.2.11
1164: //
1165: if (!hasMatchingEJBCreate(bean, method)) {
1166: fireSpecViolationEvent(entity, method, new Section(
1167: "12.2.11.e"));
1168: status = false;
1169: }
1170:
1171: if (!hasLocalReturnType(entity, method)) {
1172: fireSpecViolationEvent(entity, method, new Section(
1173: "12.2.11.f"));
1174: status = false;
1175: }
1176:
1177: if (hasMatchingEJBCreate(bean, method)
1178: && hasMatchingEJBPostCreate(bean, method)) {
1179: Method ejbCreate = getMatchingEJBCreate(bean,
1180: method);
1181: Method ejbPostCreate = getMatchingEJBPostCreate(
1182: bean, method);
1183:
1184: if (!(hasMatchingExceptions(ejbCreate, method) && hasMatchingExceptions(
1185: ejbPostCreate, method))) {
1186: fireSpecViolationEvent(entity, method,
1187: new Section("12.2.11.g"));
1188: }
1189: }
1190:
1191: if (!throwsCreateException(method)) {
1192: fireSpecViolationEvent(entity, method, new Section(
1193: "12.2.11.h"));
1194: status = false;
1195: }
1196: } else if (isFinderMethod(method)) {
1197: // Each finder method MUST match one of the ejbFind<METHOD>
1198: // methods defined in the entity bean class.
1199: //
1200: // The matching ejbFind<METHOD> method MUST have the same
1201: // number and types of arguments.
1202: //
1203: // The return type for a find<METHOD> method MUST be the
1204: // entity bean's local interface type (single-object finder)
1205: // or a collection thereof (for a multi-object finder).
1206: //
1207: // All the exceptions defined in the throws clause of an
1208: // ejbFind method of the entity bean class MUST be included
1209: // in the throws clause of the matching find method of the
1210: // home interface.
1211: //
1212: // The throws clause of a finder method MUST include the
1213: // javax.ejb.FinderException.
1214: //
1215: // Spec 12.2.11
1216: //
1217: if (!(hasLocalReturnType(entity, method) || isMultiObjectFinder(method))) {
1218: fireSpecViolationEvent(entity, method, new Section(
1219: "12.2.11.j"));
1220: status = false;
1221: }
1222:
1223: if (!throwsFinderException(method)) {
1224: fireSpecViolationEvent(entity, method, new Section(
1225: "12.2.11.k"));
1226: status = false;
1227: }
1228:
1229: if (entity.isCMP()) {
1230: // The entity bean class does not implement the finder
1231: // methods. The implementation of the finder methods are
1232: // provided by the Container
1233: //
1234: // Spec 10.6.2
1235: //
1236: if (hasMatchingEJBFind(bean, method)) {
1237: fireSpecViolationEvent(entity, method,
1238: new Section("10.6.2.j"));
1239: status = false;
1240: }
1241:
1242: // For every finder method there must be a matching
1243: // <query> element defined in the deployment descriptor
1244: // with the exception of findByPrimaryKey
1245: //
1246: // JBoss Extension: 'findAll' is _also_ ignored.
1247: //
1248: // Spec 10.5.6
1249: //
1250: if (!method.getName().equals("findByPrimaryKey")
1251: && !method.getName().equals("findAll")
1252: && !hasMatchingQuery(method, entity)) {
1253: fireSpecViolationEvent(entity, method,
1254: new Section("10.5.6"));
1255: status = false;
1256: }
1257: }
1258:
1259: if (entity.isBMP()) {
1260: if (!hasMatchingEJBFind(bean, method)) {
1261: fireSpecViolationEvent(entity, method,
1262: new Section("12.2.11.i"));
1263: status = false;
1264: } else {
1265: Method ejbFind = getMatchingEJBFind(bean,
1266: method);
1267:
1268: if (!(hasMatchingExceptions(ejbFind, method))) {
1269: fireSpecViolationEvent(entity, method,
1270: new Section("12.2.11.l"));
1271: }
1272: }
1273: }
1274: } else {
1275: // Each home method MUST match a method defined in the
1276: // entity bean class.
1277: //
1278: // The matching ejbHome<METHOD> method MUST have the same
1279: // number and types of arguments, and a matching return
1280: // type.
1281: //
1282: // Spec 12.2.9
1283: //
1284: if (!hasMatchingEJBHome(bean, method)) {
1285: fireSpecViolationEvent(entity, method, new Section(
1286: "12.2.11.m"));
1287: status = false;
1288: }
1289: }
1290: } // while( homeMethods.hasNext() )
1291:
1292: return status;
1293: }
1294:
1295: /*
1296: * Verify Entity Bean Local Interface
1297: */
1298: private boolean verifyEntityLocal(EntityMetaData entity) {
1299: boolean status = true;
1300:
1301: // Entity bean's local interface MUST extend
1302: // the javax.ejb.EJBLocalObject interface.
1303: //
1304: // Spec 12.2.10
1305: //
1306: if (!hasEJBLocalObjectInterface(local)) {
1307: fireSpecViolationEvent(entity, new Section("12.2.10.a"));
1308: status = false;
1309: }
1310:
1311: // The methods defined in the entity bean's local interface MUST
1312: // NOT have java.rmi.RemoteException in their throws clause.
1313: //
1314: // Spec 12.2.10
1315: //
1316: Iterator localMethods = Arrays.asList(local.getMethods())
1317: .iterator();
1318: while (localMethods.hasNext()) {
1319: Method method = (Method) localMethods.next();
1320:
1321: if (throwsRemoteException(method)) {
1322: fireSpecViolationEvent(entity, method, new Section(
1323: "12.2.10.b"));
1324: status = false;
1325: }
1326: }
1327:
1328: // For each method defined in the local interface, there MUST be
1329: // a matching method in the entity bean's class. The matching
1330: // method MUST have:
1331: //
1332: // - The same name.
1333: // - The same number and types of its arguments.
1334: // - The same return type.
1335: // - All the exceptions defined in the throws clause of the
1336: // matching method of the enterprise Bean class must be
1337: // defined in the throws clause of the method of the local
1338: // interface.
1339: //
1340: // Spec 12.2.10
1341: //
1342: localMethods = Arrays.asList(local.getMethods()).iterator();
1343: while (localMethods.hasNext()) {
1344: Method method = (Method) localMethods.next();
1345:
1346: // Do not check the methods of the javax.ejb.EJBLocalObject
1347: // interface
1348: if (method.getDeclaringClass().getName().equals(
1349: EJB_LOCAL_OBJECT_INTERFACE))
1350: continue;
1351:
1352: if (!hasMatchingMethod(bean, method)) {
1353: fireSpecViolationEvent(entity, method, new Section(
1354: "12.2.10.c"));
1355: status = false;
1356: }
1357:
1358: if (hasMatchingMethod(bean, method)) {
1359: try {
1360: Method beanMethod = bean.getMethod(
1361: method.getName(), method
1362: .getParameterTypes());
1363:
1364: if (!hasMatchingReturnType(beanMethod, method)) {
1365: fireSpecViolationEvent(entity, method,
1366: new Section("12.2.10.d"));
1367: status = false;
1368: }
1369:
1370: if (!hasMatchingExceptions(beanMethod, method)) {
1371: fireSpecViolationEvent(entity, method,
1372: new Section("12.2.10.e"));
1373:
1374: status = false;
1375: }
1376: } catch (NoSuchMethodException ignored) {
1377: }
1378: }
1379: }
1380:
1381: return status;
1382: }
1383:
1384: /*
1385: * Verify Entity Bean Remote Interface
1386: */
1387: private boolean verifyEntityRemote(EntityMetaData entity) {
1388: boolean status = true;
1389:
1390: // Entity bean's remote interface MUST extend
1391: // the javax.ejb.EJBObject interface.
1392: //
1393: // Spec 9.2.7
1394: //
1395: if (!hasEJBObjectInterface(remote)) {
1396: fireSpecViolationEvent(entity, new Section("9.2.7.a"));
1397: status = false;
1398: }
1399:
1400: // The methods defined in the entity bean's remote interface MUST
1401: // have valid RMI-IIOP argument types.
1402: //
1403: // The methods defined in the entity bean's home interface MUST
1404: // have valid RMI-IIOP return types.
1405: //
1406: // The methods defined in the entity bean's home interface MUST
1407: // have java.rmi.RemoteException in their throws clause.
1408: //
1409: // Spec 9.2.7
1410: //
1411: Iterator it = Arrays.asList(remote.getMethods()).iterator();
1412: while (it.hasNext()) {
1413: Method method = (Method) it.next();
1414:
1415: if (!hasLegalRMIIIOPArguments(method)) {
1416: fireSpecViolationEvent(entity, method, new Section(
1417: "9.2.7.b"));
1418: status = false;
1419: }
1420:
1421: if (!hasLegalRMIIIOPReturnType(method)) {
1422: fireSpecViolationEvent(entity, method, new Section(
1423: "9.2.7.c"));
1424: status = false;
1425: }
1426:
1427: if (!hasLegalRMIIIOPExceptionTypes(method)) {
1428: fireSpecViolationEvent(entity, method, new Section(
1429: "9.2.7.h"));
1430: status = false;
1431: }
1432:
1433: if (!throwsRemoteException(method)) {
1434: fireSpecViolationEvent(entity, method, new Section(
1435: "9.2.7.d"));
1436: status = false;
1437: }
1438: }
1439:
1440: // For each method defined in the remote interface, there MUST be
1441: // a matching method in the entity bean's class. The matching
1442: // method MUST have:
1443: //
1444: // - The same name.
1445: // - The same number and types of its arguments.
1446: // - The same return type.
1447: // - All the exceptions defined in the throws clause of the
1448: // matching method of the enterprise Bean class must be
1449: // defined in the throws clause of the method of the remote
1450: // interface.
1451: //
1452: // Spec 9.2.7
1453: //
1454: it = Arrays.asList(remote.getMethods()).iterator();
1455: while (it.hasNext()) {
1456: Method method = (Method) it.next();
1457:
1458: // Do not check the methods of the javax.ejb.EJBObject interface
1459: if (method.getDeclaringClass().getName().equals(
1460: EJB_OBJECT_INTERFACE))
1461: continue;
1462:
1463: if (!hasMatchingMethod(bean, method)) {
1464: fireSpecViolationEvent(entity, method, new Section(
1465: "9.2.7.e"));
1466: status = false;
1467: }
1468:
1469: if (hasMatchingMethod(bean, method)) {
1470: try {
1471: Method beanMethod = bean.getMethod(
1472: method.getName(), method
1473: .getParameterTypes());
1474:
1475: if (!hasMatchingReturnType(beanMethod, method)) {
1476: fireSpecViolationEvent(entity, method,
1477: new Section("9.2.7.f"));
1478: status = false;
1479: }
1480:
1481: if (!hasMatchingExceptions(beanMethod, method)) {
1482: fireSpecViolationEvent(entity, method,
1483: new Section("9.2.7.g"));
1484: status = false;
1485: }
1486: } catch (NoSuchMethodException ignored) {
1487: }
1488: }
1489: }
1490:
1491: return status;
1492: }
1493:
1494: /*
1495: * Verify Entity Bean Class
1496: */
1497: private boolean verifyCMPEntityBean(EntityMetaData entity) {
1498: boolean status = true;
1499:
1500: // The enterprise bean class MUST implement, directly or
1501: // indirectly, the javax.ejb.EntityBean interface.
1502: //
1503: // Spec 10.6.2
1504: //
1505: if (!hasEntityBeanInterface(bean)) {
1506: fireSpecViolationEvent(entity, new Section("10.6.2.a"));
1507: status = false;
1508: }
1509:
1510: // The entity bean class MUST be defined as public and abstract.
1511: //
1512: // Spec 10.6.2
1513: //
1514: if (!isPublic(bean) || !isAbstract(bean)) {
1515: fireSpecViolationEvent(entity, new Section("10.6.2.b"));
1516: status = false;
1517: }
1518:
1519: // The entity bean class MUST define a public constructor that
1520: // takes no arguments
1521: //
1522: // Spec 10.6.2
1523: //
1524: if (!hasDefaultConstructor(bean)) {
1525: fireSpecViolationEvent(entity, new Section("10.6.2.c"));
1526: status = false;
1527: }
1528:
1529: // The entity bean class MUST NOT define the finalize() method.
1530: //
1531: // Spec 10.6.2
1532: //
1533: if (hasFinalizer(bean)) {
1534: fireSpecViolationEvent(entity, new Section("10.6.2.d"));
1535: status = false;
1536: }
1537:
1538: // The ejbCreate(...) method signatures MUST follow these rules:
1539: //
1540: // - The method MUST be declared as public
1541: // - The method MUST NOT be declared as final or static
1542: // - The return type MUST be the entity bean's primary key type
1543: // --- Only if method is on remote home ---
1544: // - The method arguments MUST be legal types for RMI/IIOP
1545: // - The method return value type MUST be legal type for RMI/IIOP
1546: // --- End of only if method is on remote home ---
1547: // - The method must define the javax.ejb.CreateException
1548: //
1549: // Spec 10.6.4
1550: //
1551: if (hasEJBCreateMethod(bean, false)) {
1552: Iterator it = getEJBCreateMethods(bean);
1553: while (it.hasNext()) {
1554: Method ejbCreate = (Method) it.next();
1555: if (!isPublic(ejbCreate)) {
1556: fireSpecViolationEvent(entity, ejbCreate,
1557: new Section("10.6.4.b"));
1558: status = false;
1559: }
1560:
1561: if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
1562: fireSpecViolationEvent(entity, ejbCreate,
1563: new Section("10.6.4.c"));
1564: status = false;
1565: }
1566:
1567: if (!hasPrimaryKeyReturnType(entity, ejbCreate)) {
1568: fireSpecViolationEvent(entity, ejbCreate,
1569: new Section("10.6.4.d"));
1570: status = false;
1571: }
1572:
1573: /* FIXME
1574: * This is only true if the method is on the remote home
1575: * interface
1576: if (!hasLegalRMIIIOPArguments(ejbCreate)) {
1577: fireSpecViolationEvent(entity, ejbCreate, new Section("10.6.4.d"));
1578: status = false;
1579: }
1580:
1581: if (!hasLegalRMIIIOPReturnType(ejbCreate)) {
1582: fireSpecViolationEvent(entity, ejbCreate, new Section("10.5.4.f"));
1583: status = false;
1584: }
1585: */
1586:
1587: if (!throwsCreateException(ejbCreate)) {
1588: fireSpecViolationEvent(entity, ejbCreate,
1589: new Section("10.6.4.g"));
1590: status = false;
1591: }
1592: }
1593: }
1594:
1595: // For each ejbCreate(...) method, the entity bean class MUST
1596: // define a matching ejbPostCreate(...) method.
1597: //
1598: // The ejbPostCreate(...) method MUST follow these rules:
1599: //
1600: // - the method MUST be declared as public
1601: // - the method MUST NOT be declared as final or static
1602: // - the return type MUST be void
1603: // - the method arguments MUST be the same as the matching
1604: // ejbCreate(...) method
1605: //
1606: // Spec 10.6.5
1607: //
1608: if (hasEJBCreateMethod(bean, false)) {
1609: Iterator it = getEJBCreateMethods(bean);
1610:
1611: while (it.hasNext()) {
1612: Method ejbCreate = (Method) it.next();
1613:
1614: if (!hasMatchingEJBPostCreate(bean, ejbCreate)) {
1615: fireSpecViolationEvent(entity, ejbCreate,
1616: new Section("10.6.5.a"));
1617: status = false;
1618: }
1619:
1620: if (hasMatchingEJBPostCreate(bean, ejbCreate)) {
1621: Method ejbPostCreate = getMatchingEJBPostCreate(
1622: bean, ejbCreate);
1623:
1624: if (!isPublic(ejbPostCreate)) {
1625: fireSpecViolationEvent(entity, ejbPostCreate,
1626: new Section("10.6.5.b"));
1627: status = false;
1628: }
1629:
1630: if (isStatic(ejbPostCreate)) {
1631: fireSpecViolationEvent(entity, ejbPostCreate,
1632: new Section("10.6.5.c"));
1633: status = false;
1634: }
1635:
1636: if (isFinal(ejbPostCreate)) {
1637: fireSpecViolationEvent(entity, ejbPostCreate,
1638: new Section("10.6.5.d"));
1639: status = false;
1640: }
1641:
1642: if (!hasVoidReturnType(ejbPostCreate)) {
1643: fireSpecViolationEvent(entity, ejbPostCreate,
1644: new Section("10.6.5.e"));
1645: status = false;
1646: }
1647: }
1648: }
1649: }
1650:
1651: // The ejbHome(...) method signatures MUST follow these rules:
1652: //
1653: // - The method name MUST have ejbHome as its prefix.
1654: // - The method MUST be declared as public
1655: // - The method MUST NOT be declared as static.
1656: // - The method MUST NOT define the java.rmi.RemoteException
1657: //
1658: // Spec 10.6.6
1659: //
1660: Iterator it = getEjbHomeMethods(bean);
1661: while (it.hasNext()) {
1662: Method ejbHome = (Method) it.next();
1663: if (!isPublic(ejbHome)) {
1664: fireSpecViolationEvent(entity, ejbHome, new Section(
1665: "10.6.6.a"));
1666: status = false;
1667: }
1668:
1669: if (isStatic(ejbHome)) {
1670: fireSpecViolationEvent(entity, ejbHome, new Section(
1671: "10.6.6.b"));
1672: status = false;
1673: }
1674:
1675: if (throwsRemoteException(ejbHome)) {
1676: fireSpecViolationEvent(entity, ejbHome, new Section(
1677: "10.6.6.c"));
1678: status = false;
1679: }
1680: }
1681:
1682: // The CMP entity bean MUST implement get and set accessor methods for
1683: // each field within the abstract persistance schema.
1684: //
1685: // Spec 10.6.2
1686: //
1687: it = entity.getCMPFields();
1688: while (it.hasNext()) {
1689: String fieldName = (String) it.next();
1690: String getName = "get"
1691: + fieldName.substring(0, 1).toUpperCase()
1692: + fieldName.substring(1);
1693: Class fieldType = null;
1694:
1695: try {
1696: Method m = bean.getMethod(getName, new Class[0]);
1697: fieldType = m.getReturnType();
1698:
1699: // The getter must not return 'void' according to the JavaBeans
1700: // Spec
1701: if (fieldType == Void.TYPE) {
1702: fireSpecViolationEvent(entity, new Section(
1703: "jb.7.1.b", "Field: " + fieldName));
1704: }
1705: } catch (NoSuchMethodException nsme) {
1706: fireSpecViolationEvent(entity, new Section("10.6.2.g",
1707: "Field: " + fieldName));
1708: status = false;
1709: }
1710:
1711: String setName = "set"
1712: + fieldName.substring(0, 1).toUpperCase()
1713: + fieldName.substring(1);
1714: Class[] args = new Class[1];
1715: args[0] = fieldType;
1716:
1717: try {
1718: Method m = bean.getMethod(setName, args);
1719: fieldType = m.getReturnType();
1720:
1721: // According to the JavaBeans Spec, a setter method must
1722: // return 'void'
1723: if (fieldType != Void.TYPE) {
1724: fireSpecViolationEvent(entity, new Section(
1725: "jb.7.1.a", "Field: " + fieldName));
1726: }
1727: } catch (NoSuchMethodException nsme) {
1728: // Try with java.util.Collection
1729: //
1730: // FIXME: This should only be tried for CMR methods; a CMP
1731: // setter cannot accept a Collection!
1732: try {
1733: args[0] = classloader
1734: .loadClass("java.util.Collection");
1735: Method m = bean.getMethod(setName, args);
1736: } catch (NoSuchMethodException nsme2) {
1737: fireSpecViolationEvent(entity, new Section(
1738: "10.6.2.h", "Field: " + fieldName));
1739: status = false;
1740: } catch (ClassNotFoundException cnfe) {
1741: // Something is really broken
1742: }
1743: }
1744: }
1745:
1746: // The ejbSelect(...) method signatures MUST follow these rules:
1747: //
1748: // - The method name MUST have ejbSelect as its prefix.
1749: // - The method MUST be declared as public
1750: // - The method MUST be declared as abstract.
1751: // - The method MUST define the javax.ejb.FinderException
1752: //
1753: // Spec 10.6.7
1754: //
1755: it = getEjbSelectMethods(bean);
1756: while (it.hasNext()) {
1757: Method ejbSelect = (Method) it.next();
1758:
1759: if (!isPublic(ejbSelect)) {
1760: fireSpecViolationEvent(entity, ejbSelect, new Section(
1761: "10.6.7.a"));
1762: status = false;
1763: }
1764:
1765: if (!isAbstract(ejbSelect)) {
1766: fireSpecViolationEvent(entity, ejbSelect, new Section(
1767: "10.6.7.b"));
1768: status = false;
1769: }
1770:
1771: if (!throwsFinderException(ejbSelect)) {
1772: fireSpecViolationEvent(entity, ejbSelect, new Section(
1773: "10.6.7.c"));
1774: status = false;
1775: }
1776:
1777: if (!hasMatchingQuery(ejbSelect, entity)) {
1778: fireSpecViolationEvent(entity, ejbSelect, new Section(
1779: "10.5.7"));
1780: status = false;
1781: }
1782: }
1783:
1784: // A CMP Entity Bean must not define Finder methods.
1785: //
1786: // Spec 10.6.2
1787: //
1788: if (hasFinderMethod(bean)) {
1789: fireSpecViolationEvent(entity, new Section("10.6.2.i"));
1790: status = false;
1791: }
1792:
1793: return status;
1794: }
1795:
1796: /*
1797: * Verify BMP Entity Class
1798: */
1799: private boolean verifyBMPEntityBean(EntityMetaData entity) {
1800: boolean status = true;
1801:
1802: // The enterprise bean class MUST implement, directly or
1803: // indirectly, the javax.ejb.EntityBean interface.
1804: //
1805: // Spec 12.2.2
1806: //
1807: if (!hasEntityBeanInterface(bean)) {
1808: fireSpecViolationEvent(entity, new Section("12.2.2.a"));
1809: status = false;
1810: }
1811:
1812: // The entity bean class MUST be defined as public and NOT abstract.
1813: //
1814: // Spec 12.2.2
1815: //
1816: if (!isPublic(bean) || isAbstract(bean)) {
1817: fireSpecViolationEvent(entity, new Section("12.2.2.b"));
1818: status = false;
1819: }
1820:
1821: // The entity bean class MUST NOT be defined as final.
1822: //
1823: // Spec 12.2.2
1824: //
1825: if (isFinal(bean)) {
1826: fireSpecViolationEvent(entity, new Section("12.2.2.c"));
1827: status = false;
1828: }
1829:
1830: // The entity bean class MUST define a public constructor that
1831: // takes no arguments
1832: //
1833: // Spec 12.2.2
1834: //
1835: if (!hasDefaultConstructor(bean)) {
1836: fireSpecViolationEvent(entity, new Section("12.2.2.d"));
1837: status = false;
1838: }
1839:
1840: // The entity bean class MUST NOT define the finalize() method.
1841: //
1842: // Spec 12.2.2
1843: //
1844: if (hasFinalizer(bean)) {
1845: fireSpecViolationEvent(entity, new Section("12.2.2.e"));
1846: status = false;
1847: }
1848:
1849: // The ejbCreate(...) method signatures MUST follow these rules:
1850: //
1851: // - The method MUST be declared as public
1852: // - The method MUST NOT be declared as final or static
1853: // - The return type MUST be the entity bean's primary key type
1854: // --- If the method is on the remote home interface ---
1855: // - The method arguments MUST be legal types for RMI/IIOP
1856: // - The method return value type MUST be legal type for RMI/IIOP
1857: // --- End if the method is on the remote home interface ---
1858: //
1859: // Spec 12.2.3
1860: //
1861: if (hasEJBCreateMethod(bean, false)) {
1862: Iterator it = getEJBCreateMethods(bean);
1863: while (it.hasNext()) {
1864: Method ejbCreate = (Method) it.next();
1865: if (!isPublic(ejbCreate)) {
1866: fireSpecViolationEvent(entity, ejbCreate,
1867: new Section("12.2.3.a"));
1868: status = false;
1869: }
1870:
1871: if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
1872: fireSpecViolationEvent(entity, ejbCreate,
1873: new Section("12.2.3.b"));
1874: status = false;
1875: }
1876:
1877: if (!hasPrimaryKeyReturnType(entity, ejbCreate)) {
1878: fireSpecViolationEvent(entity, ejbCreate,
1879: new Section("12.2.3.c"));
1880: status = false;
1881: }
1882:
1883: /* FIXME
1884: * This code needs to only be invoked if the method is on the
1885: * remote home.
1886: if (!hasLegalRMIIIOPArguments(ejbCreate)) {
1887: fireSpecViolationEvent(entity, ejbCreate, new Section("9.2.3.d"));
1888: status = false;
1889: }
1890: if (!hasLegalRMIIIOPReturnType(ejbCreate)) {
1891: fireSpecViolationEvent(entity, ejbCreate, new Section("9.2.3.e"));
1892: status = false;
1893: }
1894: */
1895: }
1896: }
1897:
1898: // For each ejbCreate(...) method, the entity bean class MUST
1899: // define a matching ejbPostCreate(...) method.
1900: //
1901: // The ejbPostCreate(...) method MUST follow these rules:
1902: //
1903: // - the method MUST be declared as public
1904: // - the method MUST NOT be declared as final or static
1905: // - the return type MUST be void
1906: // - the method arguments MUST be the same as the matching
1907: // ejbCreate(...) method
1908: //
1909: // Spec 12.2.4
1910: //
1911: if (hasEJBCreateMethod(bean, false)) {
1912: Iterator it = getEJBCreateMethods(bean);
1913: while (it.hasNext()) {
1914: Method ejbCreate = (Method) it.next();
1915:
1916: if (!hasMatchingEJBPostCreate(bean, ejbCreate)) {
1917: fireSpecViolationEvent(entity, ejbCreate,
1918: new Section("12.2.4.a"));
1919: status = false;
1920: }
1921:
1922: if (hasMatchingEJBPostCreate(bean, ejbCreate)) {
1923: Method ejbPostCreate = getMatchingEJBPostCreate(
1924: bean, ejbCreate);
1925:
1926: if (!isPublic(ejbPostCreate)) {
1927: fireSpecViolationEvent(entity, ejbPostCreate,
1928: new Section("12.2.4.b"));
1929: status = false;
1930: }
1931:
1932: if (isStatic(ejbPostCreate)
1933: || isFinal(ejbPostCreate)) {
1934: fireSpecViolationEvent(entity, ejbPostCreate,
1935: new Section("12.2.4.c"));
1936: status = false;
1937: }
1938:
1939: if (!hasVoidReturnType(ejbPostCreate)) {
1940: fireSpecViolationEvent(entity, ejbPostCreate,
1941: new Section("12.2.4.d"));
1942: status = false;
1943: }
1944: }
1945: }
1946: }
1947:
1948: // Every entity bean MUST define the ejbFindByPrimaryKey method.
1949: //
1950: // The return type for the ejbFindByPrimaryKey method MUST be the
1951: // primary key type.
1952: //
1953: // The ejbFindByPrimaryKey method MUST be a single-object finder.
1954: //
1955: // Spec 12.2.5
1956: //
1957: if (!hasEJBFindByPrimaryKey(bean)) {
1958: fireSpecViolationEvent(entity, new Section("12.2.5.e"));
1959: status = false;
1960: }
1961:
1962: if (hasEJBFindByPrimaryKey(bean)) {
1963: Method ejbFindByPrimaryKey = getEJBFindByPrimaryKey(bean);
1964:
1965: if (!hasPrimaryKeyReturnType(entity, ejbFindByPrimaryKey)) {
1966: fireSpecViolationEvent(entity, ejbFindByPrimaryKey,
1967: new Section("12.2.5.e1"));
1968: status = false;
1969: }
1970:
1971: if (!isSingleObjectFinder(entity, ejbFindByPrimaryKey)) {
1972: fireSpecViolationEvent(entity, ejbFindByPrimaryKey,
1973: new Section("12.2.5.e2"));
1974: status = false;
1975: }
1976: }
1977:
1978: // A finder method MUST be declared as public.
1979: //
1980: // A finder method MUST NOT be declared as static.
1981: //
1982: // A finder method MUST NOT be declared as final.
1983: //
1984: // The finder method argument types MUST be legal types for
1985: // RMI/IIOP
1986: //
1987: // The finder method return type MUST be either the entity bean's
1988: // primary key type, or java.lang.util.Enumeration interface or
1989: // java.lang.util.Collection interface.
1990: //
1991: // Spec 12.2.5
1992: //
1993: if (hasFinderMethod(bean)) {
1994: Iterator it = getEJBFindMethods(bean);
1995: while (it.hasNext()) {
1996: Method finder = (Method) it.next();
1997:
1998: if (!isPublic(finder)) {
1999: fireSpecViolationEvent(entity, finder, new Section(
2000: "12.2.5.a"));
2001: status = false;
2002: }
2003:
2004: if (isFinal(finder) || isStatic(finder)) {
2005: fireSpecViolationEvent(entity, finder, new Section(
2006: "12.2.5.b"));
2007: status = false;
2008: }
2009:
2010: /** FIXME
2011: * this path should only get invoked if the finder is on the
2012: * remote interface.
2013: if (!hasLegalRMIIIOPArguments(finder)) {
2014: fireSpecViolationEvent(entity, finder, new Section("12.2.5.c"));
2015: status = false;
2016: }
2017: */
2018:
2019: if (!(isSingleObjectFinder(entity, finder) || isMultiObjectFinder(finder))) {
2020: fireSpecViolationEvent(entity, finder, new Section(
2021: "12.2.5.d"));
2022: status = false;
2023: }
2024: }
2025: }
2026:
2027: // The ejbHome(...) method signatures MUST follow these rules:
2028: //
2029: // - The method name MUST have ejbHome as its prefix.
2030: // - The method MUST be declared as public
2031: // - The method MUST NOT be declared as static.
2032: // - The method MUST NOT define the java.rmi.RemoteException
2033: //
2034: // Spec 10.6.6
2035: //
2036: Iterator it = getEjbHomeMethods(bean);
2037: while (it.hasNext()) {
2038: Method ejbHome = (Method) it.next();
2039:
2040: if (!isPublic(ejbHome)) {
2041: fireSpecViolationEvent(entity, ejbHome, new Section(
2042: "10.6.6.a"));
2043: status = false;
2044: }
2045:
2046: if (isStatic(ejbHome)) {
2047: fireSpecViolationEvent(entity, ejbHome, new Section(
2048: "10.6.6.b"));
2049: status = false;
2050: }
2051:
2052: if (throwsRemoteException(ejbHome)) {
2053: fireSpecViolationEvent(entity, ejbHome, new Section(
2054: "10.6.6.c"));
2055: status = false;
2056: }
2057: }
2058:
2059: return status;
2060: }
2061:
2062: /*
2063: * Verify Primary Key
2064: */
2065: private boolean verifyPrimaryKey(EntityMetaData entity) {
2066: boolean status = true;
2067: boolean cmp = entity.isCMP();
2068:
2069: if (entity.getPrimaryKeyClass() == null
2070: || entity.getPrimaryKeyClass().length() == 0) {
2071: if (cmp)
2072: fireSpecViolationEvent(entity, new Section("10.6.1.a"));
2073: else
2074: fireSpecViolationEvent(entity, new Section("12.2.1.a"));
2075:
2076: // We can't get any further if there's no PK class specified!
2077: return false;
2078: }
2079:
2080: // FIXME - Still missing the bits from 10.8.2 for CMP primary
2081: // keys. Primarily the class must be public, all fields in the
2082: // class must be public and the fields must also be a subset of
2083: // the CMP fields within the bean.
2084: //
2085: Class cls = null;
2086: try {
2087: cls = classloader.loadClass(entity.getPrimaryKeyClass());
2088: } catch (ClassNotFoundException e) {
2089: if (cmp)
2090: fireSpecViolationEvent(entity, new Section("10.6.13.a"));
2091: else
2092: fireSpecViolationEvent(entity, new Section("12.2.12.a"));
2093:
2094: // Can't do any other checks if the class is null!
2095: return false;
2096: }
2097:
2098: // The primary key type must be a valid type in RMI-IIOP.
2099: //
2100: // Spec 10.6.13 & 12.2.12
2101: //
2102: if (!isRMIIDLValueType(cls)) {
2103: if (cmp)
2104: fireSpecViolationEvent(entity, new Section("10.6.13.b"));
2105: else
2106: fireSpecViolationEvent(entity, new Section("12.2.12.b"));
2107: status = false;
2108: }
2109:
2110: // No primary key field specified, just a primary key class.
2111: if (entity.getPrimKeyField() == null
2112: || entity.getPrimKeyField().length() == 0) {
2113: // This is a check for some interesting implementation of
2114: // equals() and hashCode(). I am not sure how well it works in
2115: // the end.
2116: //
2117: if (!cls.getName().equals("java.lang.Object")) {
2118: Object one, two;
2119:
2120: try {
2121: one = cls.newInstance();
2122: two = cls.newInstance();
2123: try {
2124: if (!one.equals(two)) {
2125: if (cmp) {
2126: // fireSpecViolationEvent(entity, new Section("10.6.13.c"));
2127: log
2128: .warn("Default instances of primary key: "
2129: + cls
2130: + " do not equate, check your equals method");
2131: } else {
2132: //fireSpecViolationEvent(entity, new Section("12.2.12.c"));
2133: log
2134: .warn("Default instances of primary key: "
2135: + cls
2136: + " do not equate, check your equals method");
2137: }
2138: status = true;
2139: }
2140: } catch (NullPointerException e) {
2141: // That's OK - the implementor expected the fields to
2142: // have values
2143: }
2144:
2145: try {
2146: if (one.hashCode() != two.hashCode()) {
2147: if (cmp) {
2148: //fireSpecViolationEvent(entity, new Section("10.6.13.d"));
2149: log
2150: .warn("Default instances of primary key: "
2151: + cls
2152: + " do not have the same hash, check your hashCode method");
2153: } else {
2154: //fireSpecViolationEvent(entity, new Section("12.2.12.d"));
2155: log
2156: .warn("Default instances of primary key: "
2157: + cls
2158: + " do not have the same hash, check your hashCode method");
2159: }
2160: status = true;
2161: }
2162: } catch (NullPointerException e) {
2163: // That's OK - the implementor expected the fields to have values
2164: }
2165: } catch (IllegalAccessException e) {
2166: // If CMP primary key class MUST have a public
2167: // constructor with no parameters. 10.8.2.a
2168: ///
2169: if (cmp) {
2170: fireSpecViolationEvent(entity, new Section(
2171: "10.8.2.a"));
2172: status = false;
2173: }
2174: } catch (InstantiationException e) {
2175: //Not sure what condition this is at the moment - JMW
2176: //fireSpecViolationEvent(entity, new Section("9.2.9.a"));
2177: //status = false;
2178: }
2179: }
2180: } else {
2181: // BMP Beans MUST not include the primkey-field element in
2182: // their deployment descriptor. Deployment descriptor comment
2183: //
2184: if (entity.isBMP()) {
2185: fireSpecViolationEvent(entity, new Section("dd.a"));
2186: status = false;
2187: }
2188:
2189: // The primary keyfield MUST be a CMP field within the
2190: // entity bean.
2191: //
2192: // Spec 10.8.1
2193: //
2194: boolean found = false;
2195: Iterator it = entity.getCMPFields();
2196: while (it.hasNext()) {
2197: String fieldName = (String) it.next();
2198: if (fieldName.equals(entity.getPrimKeyField())) {
2199: found = true;
2200: break;
2201: }
2202: }
2203:
2204: if (!found) {
2205: status = false;
2206: fireSpecViolationEvent(entity, new Section("10.8.1.b"));
2207: }
2208:
2209: try {
2210: // The class of the primary key field MUST match the
2211: // primary key class specified for the entity bean. We
2212: // figure out the class of this field by getting the
2213: // return type of the get<FieldName> accessor method.
2214: //
2215: // Spec 10.8.1
2216: //
2217: String pkField = entity.getPrimKeyField();
2218: String methodName = "get"
2219: + pkField.substring(0, 1).toUpperCase()
2220: + pkField.substring(1);
2221:
2222: Method method = bean
2223: .getMethod(methodName, new Class[0]);
2224: if (!entity.getPrimaryKeyClass().equals(
2225: method.getReturnType().getName())) {
2226: status = false;
2227: fireSpecViolationEvent(entity, new Section(
2228: "10.8.1.a"));
2229: }
2230:
2231: } catch (NoSuchMethodException e) {
2232: // The primary keyfield MUST be a CMP field within the
2233: // entity bean.
2234: //
2235: // Spec 10.8.1
2236: //
2237: status = false;
2238: fireSpecViolationEvent(entity, new Section("10.8.1.b"));
2239: }
2240: }
2241:
2242: return status;
2243: }
2244:
2245: /*
2246: * Verify Message Driven Bean
2247: */
2248: protected boolean verifyMessageDrivenBean(
2249: MessageDrivenMetaData mdBean) {
2250: boolean status = true;
2251:
2252: // A message driven bean MUST implement, directly or indirectly,
2253: // javax.ejb.MessageDrivenBean interface.
2254: //
2255: // Spec 15.7.2
2256: //
2257: if (!hasMessageDrivenBeanInterface(bean)) {
2258: fireSpecViolationEvent(mdBean, new Section("15.7.2.a"));
2259: status = false;
2260: }
2261:
2262: // A message driven bean MUST implement, directly or indirectly,
2263: // javax.jms.MessageListener interface.
2264: //
2265: // Spec 15.7.2
2266: //
2267: if (!hasMessageListenerInterface(bean)) {
2268: fireSpecViolationEvent(mdBean, new Section("15.7.2.b"));
2269: status = false;
2270: }
2271:
2272: // The message driven bean class MUST be defined as public.
2273: //
2274: // Spec 15.7.2
2275: //
2276: if (!isPublic(bean)) {
2277: fireSpecViolationEvent(mdBean, new Section("15.7.2.c1"));
2278: status = false;
2279: }
2280:
2281: // The message driven bean class MUST NOT be final.
2282: //
2283: // Spec 15.7.2
2284: //
2285: if (isFinal(bean)) {
2286: fireSpecViolationEvent(mdBean, new Section("15.7.2.c2"));
2287: status = false;
2288: }
2289:
2290: // The message driven bean class MUST NOT be abstract.
2291: //
2292: // Spec 15.7.2
2293: //
2294: if (isAbstract(bean)) {
2295: fireSpecViolationEvent(mdBean, new Section("15.7.2.c3"));
2296: status = false;
2297: }
2298:
2299: // The message driven bean class MUST have a public constructor that
2300: // takes no arguments.
2301: //
2302: // Spec 15.7.2
2303: //
2304: if (!hasDefaultConstructor(bean)) {
2305: fireSpecViolationEvent(mdBean, new Section("15.7.2.d"));
2306: status = false;
2307: }
2308:
2309: // The message driven bean class MUST NOT define the finalize() method.
2310: //
2311: // Spec 15.7.2
2312: //
2313: if (hasFinalizer(bean)) {
2314: fireSpecViolationEvent(mdBean, new Section("15.7.2.e"));
2315: status = false;
2316: }
2317:
2318: // A message driven bean MUST implement the ejbCreate() method.
2319: // The ejbCreate() method signature MUST follow these rules:
2320: //
2321: // - The method name MUST be ejbCreate
2322: // - The method MUST be declared as public
2323: // - The method MUST NOT be declared as final or static
2324: // - The return type MUST be void
2325: // - The method arguments MUST have no arguments.
2326: // - The method MUST NOT define any application exceptions.
2327: //
2328: // Spec 15.7.2, 3
2329: //
2330: if (hasEJBCreateMethod(bean, false)) {
2331: Iterator it = getEJBCreateMethods(bean);
2332: Method ejbCreate = (Method) it.next();
2333:
2334: if (!isPublic(ejbCreate)) {
2335: fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2336: "15.7.3.b"));
2337: status = false;
2338: }
2339:
2340: if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
2341: fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2342: "15.7.3.c"));
2343: status = false;
2344: }
2345:
2346: if (!hasVoidReturnType(ejbCreate)) {
2347: fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2348: "15.7.3.d"));
2349: status = false;
2350: }
2351:
2352: if (!hasNoArguments(ejbCreate)) {
2353: fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2354: "15.7.3.e"));
2355: status = false;
2356: }
2357:
2358: if (!throwsNoException(ejbCreate)) {
2359: fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2360: "15.7.3.f"));
2361: status = false;
2362: }
2363:
2364: if (it.hasNext()) {
2365: fireSpecViolationEvent(mdBean, new Section("15.7.3.a"));
2366: status = false;
2367: }
2368: } else {
2369: fireSpecViolationEvent(mdBean, new Section("15.7.3.a"));
2370: status = false;
2371: }
2372:
2373: // A message driven bean MUST implement the onMessage(...) method.
2374: // The onMessage() method signature MUST follow these rules:
2375: //
2376: // - The method name MUST be onMessage
2377: // - The method MUST be declared as public
2378: // - The method MUST NOT be declared as final or static
2379: // - The return type MUST be void
2380: // - The method arguments MUST have a single argument of type
2381: // javax.jms.Message.
2382: // - The method MUST NOT define any application exceptions.
2383: //
2384: // Spec 15.7.4
2385: //
2386: if (hasOnMessageMethod(bean)) {
2387: Iterator it = getOnMessageMethods(bean);
2388: Method onMessage = (Method) it.next();
2389:
2390: if (!isPublic(onMessage)) {
2391: fireSpecViolationEvent(mdBean, onMessage, new Section(
2392: "15.7.4.b"));
2393: status = false;
2394: }
2395:
2396: if ((isFinal(onMessage)) || (isStatic(onMessage))) {
2397: fireSpecViolationEvent(mdBean, onMessage, new Section(
2398: "15.7.4.c"));
2399: status = false;
2400: }
2401:
2402: try {
2403: Class message = classloader
2404: .loadClass("javax.jms.Message");
2405: if (!hasSingleArgument(onMessage, message)) {
2406: fireSpecViolationEvent(mdBean, onMessage,
2407: new Section("15.7.4.e"));
2408: status = false;
2409: }
2410:
2411: if (!throwsNoException(onMessage)) {
2412: fireSpecViolationEvent(mdBean, onMessage,
2413: new Section("15.7.4.f"));
2414: status = false;
2415: }
2416:
2417: if (it.hasNext()) {
2418: fireSpecViolationEvent(mdBean, new Section(
2419: "15.7.4.a"));
2420: status = false;
2421: }
2422: } catch (ClassNotFoundException cnfe) {
2423: // javax.jms.Message is not available?!
2424: }
2425: } else {
2426: fireSpecViolationEvent(mdBean, new Section("15.7.4.a"));
2427: status = false;
2428: }
2429:
2430: // A message driven bean MUST implement the ejbRemove() method.
2431: // The ejbRemove() method signature MUST follow these rules:
2432: //
2433: // - The method name MUST be ejbRemove
2434: // - The method MUST be declared as public
2435: // - The method MUST NOT be declared as final or static
2436: // - The return type MUST be void
2437: // - The method MUST have no arguments.
2438: // - The method MUST NOT define any application exceptions.
2439: //
2440: // Spec 15.7.5
2441: //
2442: if (hasEJBRemoveMethod(bean)) {
2443: Iterator it = getEJBRemoveMethods(bean);
2444: Method ejbRemove = (Method) it.next();
2445:
2446: if (!isPublic(ejbRemove)) {
2447: fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2448: "15.7.5.b"));
2449: status = false;
2450: }
2451:
2452: if ((isFinal(ejbRemove)) || (isStatic(ejbRemove))) {
2453: fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2454: "15.7.5.c"));
2455: status = false;
2456: }
2457:
2458: if (!hasVoidReturnType(ejbRemove)) {
2459: fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2460: "15.7.5.d"));
2461: status = false;
2462: }
2463:
2464: if (!hasNoArguments(ejbRemove)) {
2465: fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2466: "15.7.5.e"));
2467: status = false;
2468: }
2469:
2470: if (!throwsNoException(ejbRemove)) {
2471: fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2472: "15.7.5.f"));
2473: status = false;
2474: }
2475:
2476: if (it.hasNext()) {
2477: fireSpecViolationEvent(mdBean, new Section("15.7.5.a"));
2478: status = false;
2479: }
2480: } else {
2481: fireSpecViolationEvent(mdBean, new Section("15.7.5.a"));
2482: status = false;
2483: }
2484:
2485: return status;
2486: }
2487:
2488: }
2489:
2490: /*
2491: vim:ts=3:sw=3:et
2492: */
|