| /******************************************************************************* |
| * Copyright (c) 2001, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.j2ee.model.internal.validation; |
| |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.logging.Level; |
| |
| import org.eclipse.jem.java.JavaClass; |
| import org.eclipse.jem.util.logger.LogEntry; |
| import org.eclipse.jem.util.logger.proxy.Logger; |
| import org.eclipse.jst.j2ee.ejb.EJBJar; |
| import org.eclipse.jst.j2ee.ejb.EjbPackage; |
| import org.eclipse.jst.j2ee.ejb.EnterpriseBean; |
| import org.eclipse.jst.j2ee.ejb.Entity; |
| import org.eclipse.jst.j2ee.ejb.MessageDriven; |
| import org.eclipse.wst.validation.internal.core.ValidationException; |
| import org.eclipse.wst.validation.internal.provisional.core.IMessage; |
| |
| /** |
| * Validate the WebSphere-specific implementation of non-spec features, such |
| * as component inheritance. |
| */ |
| public class EJBExt20VRule extends AValidationRule implements IMessagePrefixEjb20Constants { |
| private static final Map MESSAGE_IDS; |
| private static final Object[] DEPENDS_ON = new Object[]{IValidationRuleList.EJB20_STATELESS_SESSION_BEANCLASS, IValidationRuleList.EJB20_STATELESS_SESSION_REMOTE, IValidationRuleList.EJB20_STATELESS_SESSION_HOME, IValidationRuleList.EJB20_STATELESS_SESSION_LOCAL, IValidationRuleList.EJB20_STATELESS_SESSION_LOCALHOME, IValidationRuleList.EJB20_STATEFUL_SESSION_BEANCLASS, IValidationRuleList.EJB20_STATEFUL_SESSION_REMOTE, IValidationRuleList.EJB20_STATEFUL_SESSION_HOME, IValidationRuleList.EJB20_STATEFUL_SESSION_LOCAL, IValidationRuleList.EJB20_STATEFUL_SESSION_LOCALHOME, IValidationRuleList.EJB20_CMP_BEANCLASS, IValidationRuleList.EJB20_CMP_REMOTE, IValidationRuleList.EJB20_CMP_HOME, IValidationRuleList.EJB20_CMP_LOCAL, IValidationRuleList.EJB20_CMP_LOCALHOME, IValidationRuleList.EJB20_CMP_KEYCLASS, IValidationRuleList.EJB20_BMP_BEANCLASS, IValidationRuleList.EJB20_BMP_REMOTE, IValidationRuleList.EJB20_BMP_HOME, IValidationRuleList.EJB20_BMP_LOCAL, IValidationRuleList.EJB20_BMP_LOCALHOME, IValidationRuleList.EJB20_BMP_KEYCLASS, IValidationRuleList.EJB20_MESSAGE_BEANCLASS, IValidationRuleList.EJB20_EJBJAR}; |
| |
| static { |
| MESSAGE_IDS = new HashMap(); |
| |
| MESSAGE_IDS.put(CHKJ2106, new String[]{CHKJ2106+SPEC}); |
| MESSAGE_IDS.put(CHKJ2849, new String[]{CHKJ2849+SPEC}); |
| MESSAGE_IDS.put(CHKJ2852, new String[]{CHKJ2852}); |
| } |
| |
| public Object[] getDependsOn() { |
| return DEPENDS_ON; |
| } |
| |
| public Object getId() { |
| return IValidationRuleList.EJB20_EJBEXT; |
| } |
| |
| public Map getMessageIds() { |
| return MESSAGE_IDS; |
| } |
| |
| public Object getTarget(Object parent, Object clazz) { |
| return null; |
| } |
| |
| /** |
| * If the bean components (home interface, remote interface, bean class, and primary |
| * key) can all be found and reflected, return true. Let the DDValidator |
| * report the error message against the bean if one of these types doesn't reflect. |
| */ |
| public boolean areBeanComponentsReflected(EnterpriseBean bean) { |
| // Don't need to check if the bean is null, because this method will |
| // not be called if it is. |
| try { |
| ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getEjbClass()); |
| } |
| catch (InvalidInputException exc) { |
| return false; |
| } |
| |
| if(bean instanceof MessageDriven) { |
| // don't need to check the rest |
| return true; |
| } |
| |
| try { |
| if(bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_HomeInterface())) { |
| ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getHomeInterface()); |
| } |
| } |
| catch (InvalidInputException exc) { |
| return false; |
| } |
| |
| try { |
| if(bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_RemoteInterface())) { |
| ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getRemoteInterface()); |
| } |
| } |
| catch (InvalidInputException exc) { |
| return false; |
| } |
| |
| try { |
| if(bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_LocalHomeInterface())) { |
| ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getLocalHomeInterface()); |
| } |
| } |
| catch (InvalidInputException exc) { |
| return false; |
| } |
| |
| try { |
| if(bean.eIsSet(EjbPackage.eINSTANCE.getEnterpriseBean_LocalInterface())) { |
| ValidationRuleUtility.isValidTypeHierarchy(bean, bean.getLocalInterface()); |
| } |
| } |
| catch (InvalidInputException exc) { |
| return false; |
| } |
| |
| if (bean.isEntity()) { |
| JavaClass primaryKey = ((Entity) bean).getPrimaryKey(); |
| try { |
| if(((Entity)bean).eIsSet(EjbPackage.eINSTANCE.getEntity_PrimaryKey())) { |
| ValidationRuleUtility.isValidTypeHierarchy(bean, primaryKey); |
| } |
| } |
| catch (InvalidInputException exc) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| public void validate(IEJBValidationContext vc, Object targetParent, Object target) throws ValidationCancelledException, ValidationException { |
| Logger logger = vc.getMsgLogger(); |
| if(logger != null && logger.isLoggingLevel(Level.FINEST)) { |
| LogEntry entry = vc.getLogEntry(); |
| entry.setSourceID("EJB20Validator - validate"); //$NON-NLS-1$ |
| entry.setText(getClass().getName() + "::validate(" + targetParent + ", " + target); //$NON-NLS-1$ //$NON-NLS-2$ |
| logger.write(Level.FINEST, entry); |
| } |
| |
| EJBJar ejbJar = null; |
| if(targetParent == null) { |
| ejbJar = (EJBJar)target; |
| validate(vc, ejbJar); |
| } |
| else { |
| // running as a dependent |
| ejbJar = (EJBJar)vc.loadModel(EJBValidatorModelEnum.EJB_MODEL); |
| EnterpriseBean bean = (EnterpriseBean)targetParent; |
| validate(vc, ejbJar, bean); |
| } |
| } |
| |
| /* |
| * @see IValidationRule#validate(IEJBValidationContext, Object, Object) |
| */ |
| public void validate(IEJBValidationContext vc, EJBJar ejbJar) throws ValidationCancelledException, ValidationException { |
| List enterpriseBeans = ejbJar.getEnterpriseBeans(); |
| Iterator iterator = enterpriseBeans.iterator(); |
| EnterpriseBean bean = null; |
| while(iterator.hasNext()) { |
| bean = (EnterpriseBean)iterator.next(); |
| if(bean == null) { |
| // If bean isn't valid, don't perform any of the other |
| // validation checks on it. Let DDValidator output the error message. |
| continue; |
| } |
| validate(vc, ejbJar, bean); |
| } |
| } |
| |
| public void validate(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) throws ValidationCancelledException, ValidationException { |
| try { |
| // Check if the class exists, etc. |
| if(!areBeanComponentsReflected(bean)) { |
| // Something didn't reflect properly, so don't continue with the |
| // rest of the checks. Some metadata will be nonsense. |
| return; |
| } |
| |
| // Component inheritance is now checked in each VRule instead of here. |
| // This was necessary for incremental validation; if one class changed |
| // in the bean, and the bean was a member of component inheritance, then |
| // messages were added multiple times onto the classes which had not changed. |
| // In order to avoid multiple messages, only the component inheritance of |
| // the class which changed should be revalidated when the class changes. |
| validateAppendixB(vc, ejbJar, bean); // validate the key class since that message is registered against ejb-jar.xml |
| } |
| catch(ValidationCancelledException e) { |
| throw e; |
| } |
| /* unreachable catch block |
| catch(ValidationException exc) { |
| // If there's a problem, proceed with the next bean. |
| IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorConstants.CHKJ2852, IEJBValidationContext.WARNING, bean, new String[]{ArchiveConstants.EJBJAR_EXTENSIONS_SHORT_NAME, beanName}, this); |
| vc.addMessage(message); |
| if(logger.isLoggingLevel(Level.FINER)) { |
| logger.write(Level.FINER, exc); |
| } |
| } |
| */ |
| catch(Throwable exc) { |
| // If there's a problem, proceed with the next bean. |
| String superTypeName = getEJBInheritanceFileName(); |
| if(superTypeName == null) |
| superTypeName = "unknown super type"; //$NON-NLS-1$ |
| IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2852, IEJBValidationContext.WARNING, bean, new String[]{superTypeName, bean.getName()}, this); |
| vc.addMessage(message); |
| Logger logger = vc.getMsgLogger(); |
| if(logger != null && logger.isLoggingLevel(Level.SEVERE)) { |
| logger.write(Level.SEVERE, exc); |
| } |
| } |
| } |
| |
| protected void validateAppendixB(IEJBValidationContext vc, EJBJar ejbJar, EnterpriseBean bean) { |
| // The Java inheritance structure must match the EJB inheritance structure. |
| // e.g. if EJB B is a child of EJB A, then class B must be a child of class A. |
| // B could be a grandchild (or great-grandchild or ...) of A. |
| if(bean == null) { |
| return; |
| } |
| if(!bean.isEntity()) { |
| return; |
| } |
| JavaClass thisKey = ((Entity)bean).getPrimaryKey(); |
| EnterpriseBean supertype = getSuperType(bean); |
| JavaClass parentKey = null; |
| if (supertype != null) { |
| // check this CMP's supertype |
| // Key a Xchild of parent Key |
| // In WSA EJB component inheritance, the root EJB must define the key. |
| // The key is the same for all child EJBs. |
| if (supertype instanceof Entity) { |
| parentKey = ((Entity) supertype).getPrimaryKey(); |
| |
| if ((thisKey == null) || (parentKey == null) || !thisKey.equals(parentKey)) { |
| String[] msgParm = new String[] { bean.getName(), parentKey.getQualifiedName()}; |
| IMessage message = MessageUtility.getUtility().getMessage(vc, IEJBValidatorMessageConstants.CHKJ2106, IEJBValidationContext.ERROR, bean, msgParm, this); |
| vc.addMessage(message); |
| } |
| } |
| } |
| |
| // validateAppendixB(vc, supertype, parentKey); |
| } |
| } |