blob: 081c31a21ae0b57209bdba5bf698b6617ede581a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2006 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);
}
}