在完成这个EJB单元测试框架的CMP的时候,核心应该就是成功使用Command模式,框架在初始化的时候会自动初始化需要使用的Entity Bean,包括Entity Bean之间的依赖关系,但是如果在初始化的时候,一个Entity Bean依赖另外一个还没有初始化的Entity Bean,而所依赖的那个Entity Bean又依赖这个Entity Bean,就会形成循环依赖。我使用Command模式,讲这个依赖关系放到一个Command里面,然后在一个Entity Bean的基本属性初始化完成以后再执行Command队列初始化那些关系,就不会形成循环依赖了。
代码如下:
package com.activereasoning.test.base;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import com.activereasoning.test.util.ClassUtil;
import com.activereasoning.test.util.CommandUtil;
import com.activereasoning.test.util.EJBUtil;
import com.activereasoning.test.util.StringUtil;
import com.activereasoning.test.util.ValueConverter;
public class InitEntityBeanCommand implements Command
{
private static Logger log = LogManager.getLogger(InitEntityBeanCommand.class);
private BeanInfo beanInfo;
private Object pk;
private Object object;
private List setReferenceCommands = new ArrayList();
private List setManyToManyCommands = new ArrayList();
private List lookupEntityBeanCommands = new ArrayList();
private List fields = new ArrayList();
public InitEntityBeanCommand(BeanInfo beanInfo, Object pk)
{
this.beanInfo = beanInfo;
this.pk = pk;
}
public void initCMPCommands(Object object, Map record)
{
setObject(object);
String name = beanInfo.getShortName();
Method[] methods = ClassUtil.getSetterMethods(object);
for (int i = 0; i < methods.length; i++)
{
Method method = methods[i];
String field = ClassUtil.getField(method);
Class[] types = method.getParameterTypes();
String column = null;
String value = null;
if (ClassUtil.isEntityBeanObject(types[0]))
{//try to process entity type
String targetBean = StringUtil.getShortClassName(types[0].getName());
column = beanInfo.getFKColumn(targetBean);
if (column == null)
{
log.warn("Can not find target column for reference entity bean:" + targetBean + " of " + name);
continue;
}
value = (String) record.get(column);
if (value == null)
{
continue;
}
BeanInfo targetBeanInfo = EJBUtil.getBeanInfoByName(targetBean);
if (targetBeanInfo == null)
{
log.warn("Can not find target BeanInfo for " + targetBean);
}
else
{
SetReferenceCommand command = new SetReferenceCommand(beanInfo, field, column, object, (Long) pk,
method, targetBeanInfo, value);
setReferenceCommands.add(command);
}
}
else if (types[0].isAssignableFrom(Collection.class))
{//try to process many to many relationship
EJBRelationship ejbRelationship = beanInfo.getManyToManyRelationship(field);
if (ejbRelationship != null)
{
SetManyToManyCommand command = new SetManyToManyCommand(beanInfo, field, ejbRelationship);
setManyToManyCommands.add(command);
continue;
}
String manyBeanName = beanInfo.getManyToOneRelationship(field);
if (manyBeanName != null)
{
LookupEntityBeanCommand command = new LookupEntityBeanCommand(manyBeanName);
lookupEntityBeanCommands.add(command);
}
}
else
{//process normal type
column = beanInfo.getFieldColumn(field);
value = (String) record.get(column);
if (column == null || value == null)
{//ignore those null value or can not find corresponding database column
continue;
}
Object realValue = ValueConverter.getBeanValue(types[0], value);
if (realValue != null)
{
fields.add(new Object[]
{ method, realValue });
}
}
}
}
public void execute()
{
String name = beanInfo.getShortName();
log.debug("Execute InitEntityBeanCommand for " + name + ", pk=" + pk);
for (int i = 0; i < setReferenceCommands.size(); i++)
{
SetReferenceCommand command = (SetReferenceCommand) setReferenceCommands.get(i);
command.setObject(object);
CommandUtil.addCommand(CommandUtil.CMP, name, command);
}
for (int i = 0; i < setManyToManyCommands.size(); i++)
{
SetManyToManyCommand command = (SetManyToManyCommand) setManyToManyCommands.get(i);
CommandUtil.addCommand(CommandUtil.CMP_LAZY_LOAD, name, command);
}
for (int i = 0; i < lookupEntityBeanCommands.size(); i++)
{
LookupEntityBeanCommand command = (LookupEntityBeanCommand) lookupEntityBeanCommands.get(i);
CommandUtil.addCommand(CommandUtil.CMP_LAZY_LOAD, name, command);
}
try
{
for (int i = 0; i < fields.size(); i++)
{
Object[] objects = (Object[]) fields.get(i);
((Method) objects[0]).invoke(object, new Object[]
{ objects[1] });
}
}
catch (Exception e)
{
log.error("Set entity bean fields error.", e);
}
}
/**
* @return the object
*/
public Object getObject()
{
return object;
}
/**
* @param object the object to set
*/
public void setObject(Object object)
{
this.object = object;
}
public void add(Collection commands)
{
}
}
发表评论