blob: 867f4531a17f4401b7f91798743e968b7656b817 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openejb.config.rules;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.config.EjbModule;
import org.apache.openejb.jee.EnterpriseBean;
import org.apache.openejb.jee.EntityBean;
import org.apache.openejb.jee.RemoteBean;
import org.apache.openejb.jee.SessionBean;
import org.apache.openejb.jee.SessionType;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import java.lang.reflect.Method;
import java.util.List;
import java.util.ArrayList;
public class CheckMethods extends ValidationBase {
public void validate(EjbModule ejbModule) {
for (EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
if (!(bean instanceof RemoteBean)) continue;
RemoteBean b = (RemoteBean) bean;
if (b.getHome() != null) {
check_remoteInterfaceMethods(b);
check_homeInterfaceMethods(b);
}
if (b.getLocalHome() != null) {
check_localInterfaceMethods(b);
check_localHomeInterfaceMethods(b);
}
check_unusedCreateMethods(b);
check_unusedPostCreateMethods(b);
}
}
private void check_localHomeInterfaceMethods(RemoteBean b) {
Class home = null;
Class bean = null;
try {
home = loadClass(b.getLocalHome());
bean = loadClass(b.getEjbClass());
} catch (OpenEJBException e) {
return;
}
if (!EJBLocalHome.class.isAssignableFrom(home)) {
return;
}
if (check_hasCreateMethod(b, bean, home)) {
check_createMethodsAreImplemented(b, bean, home);
// check_postCreateMethodsAreImplemented(b, bean, home);
}
}
private void check_localInterfaceMethods(RemoteBean b) {
Class intrface = null;
Class beanClass = null;
try {
intrface = loadClass(b.getLocal());
beanClass = loadClass(b.getEjbClass());
} catch (OpenEJBException e) {
return;
}
if (!EJBLocalObject.class.isAssignableFrom(intrface)) {
return;
}
Method[] interfaceMethods = intrface.getMethods();
for (int i = 0; i < interfaceMethods.length; i++) {
if (interfaceMethods[i].getDeclaringClass() == EJBLocalObject.class) continue;
String name = interfaceMethods[i].getName();
try {
Class[] params = interfaceMethods[i].getParameterTypes();
Method beanMethod = beanClass.getMethod(name, params);
} catch (NoSuchMethodException nsme) {
List<Method> differentArgs = new ArrayList<Method>();
List<Method> differentCase = new ArrayList<Method>();
for (Method method : beanClass.getMethods()) {
if (method.getName().equals(name)){
differentArgs.add(method);
} else if (method.getName().equalsIgnoreCase(name)){
differentCase.add(method);
}
}
if (differentArgs.size() > 0) {
fail(b, "no.busines.method.args", interfaceMethods[i].getName(), interfaceMethods[i].toString(), "local", intrface.getName(), beanClass.getName(), differentArgs.size());
}
if (differentCase.size() > 0){
fail(b, "no.busines.method.case", interfaceMethods[i].getName(), interfaceMethods[i].toString(), "local", intrface.getName(), beanClass.getName(), differentCase.size());
}
if(differentArgs.size() == 0 && differentCase.size() == 0){
fail(b, "no.busines.method", interfaceMethods[i].getName(), interfaceMethods[i].toString(), "local", intrface.getName(), beanClass.getName());
}
}
}
}
private void check_remoteInterfaceMethods(RemoteBean b) {
Class intrface = null;
Class beanClass = null;
try {
intrface = loadClass(b.getRemote());
beanClass = loadClass(b.getEjbClass());
} catch (OpenEJBException e) {
return;
}
if (!EJBObject.class.isAssignableFrom(intrface)) {
return;
}
Method[] interfaceMethods = intrface.getMethods();
for (int i = 0; i < interfaceMethods.length; i++) {
if (interfaceMethods[i].getDeclaringClass() == javax.ejb.EJBObject.class) continue;
String name = interfaceMethods[i].getName();
try {
Class[] params = interfaceMethods[i].getParameterTypes();
Method beanMethod = beanClass.getMethod(name, params);
} catch (NoSuchMethodException nsme) {
List<Method> differentArgs = new ArrayList<Method>();
List<Method> differentCase = new ArrayList<Method>();
for (Method method : beanClass.getMethods()) {
if (method.getName().equals(name)){
differentArgs.add(method);
} else if (method.getName().equalsIgnoreCase(name)){
differentCase.add(method);
}
}
if (differentArgs.size() > 0) {
fail(b, "no.busines.method.args", interfaceMethods[i].getName(), interfaceMethods[i].toString(), "remote", intrface.getName(), beanClass.getName(), differentArgs.size());
}
if (differentCase.size() > 0){
fail(b, "no.busines.method.case", interfaceMethods[i].getName(), interfaceMethods[i].toString(), "remote", intrface.getName(), beanClass.getName(), differentCase.size());
}
if (differentArgs.size() == 0 && differentCase.size() == 0){
fail(b, "no.busines.method", interfaceMethods[i].getName(), interfaceMethods[i].toString(), "remote", intrface.getName(), beanClass.getName());
}
}
}
}
private void check_homeInterfaceMethods(RemoteBean b) {
Class home = null;
Class bean = null;
try {
home = loadClass(b.getHome());
bean = loadClass(b.getEjbClass());
} catch (OpenEJBException e) {
return;
}
if (!EJBHome.class.isAssignableFrom(home)) {
return;
}
if (check_hasCreateMethod(b, bean, home)) {
check_createMethodsAreImplemented(b, bean, home);
// ejbPostCreate methods are now automatically generated
// check_postCreateMethodsAreImplemented(b, bean, home);
}
}
public boolean check_hasCreateMethod(RemoteBean b, Class bean, Class home) {
if (b instanceof SessionBean && !javax.ejb.SessionBean.class.isAssignableFrom(bean)) {
// This is a pojo-style bean
return false;
}
Method[] homeMethods = home.getMethods();
boolean hasCreateMethod = false;
for (int i = 0; i < homeMethods.length && !hasCreateMethod; i++) {
hasCreateMethod = homeMethods[i].getName().startsWith("create");
}
if (!hasCreateMethod && !(b instanceof EntityBean)) {
fail(b, "no.home.create", b.getHome(), b.getRemote());
}
return hasCreateMethod;
}
public boolean check_createMethodsAreImplemented(RemoteBean b, Class bean, Class home) {
boolean result = true;
Method[] homeMethods = home.getMethods();
for (int i = 0; i < homeMethods.length; i++) {
if (!homeMethods[i].getName().startsWith("create")) continue;
Method create = homeMethods[i];
StringBuilder ejbCreateName = new StringBuilder(create.getName());
ejbCreateName.replace(0, 1, "ejbC");
try {
if (javax.ejb.EnterpriseBean.class.isAssignableFrom(bean)) {
bean.getMethod(ejbCreateName.toString(), create.getParameterTypes());
} else {
// TODO: Check for Init method in pojo session bean class
}
} catch (NoSuchMethodException e) {
result = false;
String paramString = getParameters(create);
if (b instanceof EntityBean) {
EntityBean entity = (EntityBean) b;
fail(b, "entity.no.ejb.create", b.getEjbClass(), entity.getPrimKeyClass(), ejbCreateName.toString(), paramString);
} else {
if (b instanceof SessionBean) {
SessionBean sb = (SessionBean) b;
// Under EJB 3.1, it is not required that a stateless session bean have an ejbCreate method, even when it has a home interface
if (!sb.getSessionType().equals(SessionType.STATELESS))
fail(b, "session.no.ejb.create", b.getEjbClass(), ejbCreateName.toString(), paramString);
}
}
}
}
return result;
}
public boolean check_postCreateMethodsAreImplemented(RemoteBean b, Class bean, Class home) {
boolean result = true;
if (b instanceof SessionBean) return true;
Method[] homeMethods = home.getMethods();
Method[] beanMethods = bean.getMethods();
for (int i = 0; i < homeMethods.length; i++) {
if (!homeMethods[i].getName().startsWith("create")) continue;
Method create = homeMethods[i];
StringBuilder ejbPostCreateName = new StringBuilder(create.getName());
ejbPostCreateName.replace(0, 1, "ejbPostC");
try {
bean.getMethod(ejbPostCreateName.toString(), create.getParameterTypes());
} catch (NoSuchMethodException e) {
result = false;
String paramString = getParameters(create);
fail(b, "no.ejb.post.create", b.getEjbClass(), ejbPostCreateName.toString(), paramString);
}
}
return result;
}
public void check_unusedCreateMethods(RemoteBean b) {
Class home = null;
Class localHome = null;
Class bean = null;
try {
if (b.getLocalHome() != null) {
localHome = loadClass(b.getLocalHome());
}
if (b.getHome() != null) {
home = loadClass(b.getHome());
}
bean = loadClass(b.getEjbClass());
} catch (OpenEJBException e) {
return;
}
for (Method ejbCreate : bean.getMethods()) {
if (!ejbCreate.getName().startsWith("ejbCreate")) continue;
StringBuilder create = new StringBuilder(ejbCreate.getName());
create.replace(0, "ejbC".length(), "c");
boolean inLocalHome = false;
boolean inHome = false;
try {
if (localHome != null) {
localHome.getMethod(create.toString(), ejbCreate.getParameterTypes());
inLocalHome = true;
}
} catch (NoSuchMethodException e) {
}
try {
if (home != null) {
home.getMethod(create.toString(), ejbCreate.getParameterTypes());
inHome = true;
}
} catch (NoSuchMethodException e) {
}
if (!inLocalHome && !inHome){
String paramString = getParameters(ejbCreate);
warn(b, "unused.ejb.create", b.getEjbClass(), ejbCreate.getName(), paramString, create.toString());
}
}
}
public void check_unusedPostCreateMethods(RemoteBean b) {
Class bean = null;
try {
bean = loadClass(b.getEjbClass());
} catch (OpenEJBException e) {
return;
}
for (Method postCreate : bean.getMethods()) {
if (!postCreate.getName().startsWith("ejbPostCreate")) continue;
StringBuilder ejbCreate = new StringBuilder(postCreate.getName());
ejbCreate.replace(0, "ejbPostCreate".length(), "ejbCreate");
try {
bean.getMethod(ejbCreate.toString(), postCreate.getParameterTypes());
} catch (NoSuchMethodException e) {
String paramString = getParameters(postCreate);
warn(b, "unused.ejbPostCreate", b.getEjbClass(), postCreate.getName(), paramString, ejbCreate.toString());
}
}
}
/// public void check_findMethods(){
/// if(this.componentType == this.BMP_ENTITY ){
///
/// String beanMethodName = "ejbF"+method.getName().substring(1);
/// beanMethod = beanClass.getMethod(beanMethodName,method.getParameterTypes());
/// }
/// }
///
/// public void check_homeMethods(){
/// String beanMethodName = "ejbHome"+method.getName().substring(0,1).toUpperCase()+method.getName().substring(1);
/// beanMethod = beanClass.getMethod(beanMethodName,method.getParameterTypes());
/// }
}