/*
* Copyright (c) 2005
* XDoclet Team
* All rights reserved.
*/
package org.xdoclet.plugin.ejb.interfaces;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import org.generama.MergeableVelocityTemplateEngine;
import org.generama.WriterMapper;
import org.xdoclet.plugin.ejb.EjbConfig;
import org.xdoclet.plugin.ejb.EjbHomeUtils;
import org.xdoclet.plugin.ejb.EjbJavaClassBuilder;
import org.xdoclet.plugin.ejb.EjbRuntime;
import org.xdoclet.plugin.ejb.EjbUtils;
import org.xdoclet.plugin.ejb.qtags.EjbHomeTag;
import org.xdoclet.plugin.ejb.qtags.TagLibrary;
import org.xdoclet.plugin.ejb.util.DuplicatedJavaMethod;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.Type;
/**
* Remote home interface generation
*
* @author Diogo Quintela
* @version $Revision: 538 $
*/
public class RemoteHomeInterfacePlugin extends RemoteInterfaceBase implements EjbJavaClassBuilder {
/** Home utils */
protected EjbHomeUtils ejbHomeUtils;
/**
* Creates a new RemoteHomeInterfacePlugin object.
*
* @param templateEngine and velocity engine
* @param metadataProvider an qdox metadata provider
* @param writerMapper an writer mapper
* @param config the common ejb config
*
* @throws ClassNotFoundException in case of error
*/
public RemoteHomeInterfacePlugin(MergeableVelocityTemplateEngine templateEngine,
WriterMapper writerMapper, EjbConfig config) {
super(templateEngine, writerMapper, config);
EjbRuntime.setPlugin(this);
setPackageregex("beans");
setPackagereplace("interfaces");
super.setFileregex(config.getEjbReplaceRegex());
setFilereplace("RemoteHome");
super.setMultioutput(true);
this.ejbHomeUtils = new EjbHomeUtils(ejbUtils);
}
/**
* JavaClass that describes the generated artifacts
*
* @return The generated artifacts JavaClass otherwise null
*/
public JavaClass[] buildFor(JavaClass metadata) {
if (!shouldGenerate(metadata)) {
return null;
}
JavaField field;
JavaMethod method;
JavaClass retVal = createDynamicJavaClass(getDestinationClassname(metadata), getDestinationPackage(metadata), null, getMetadataProvider());
retVal.setInterface(true);
retVal.setModifiers(new String[]{"public"});
String[] extendz = getExtends(metadata);
Type[] extendzTypes = new Type[extendz.length];
for (int j = 0; j < extendz.length; j++) {
extendzTypes[j] = new Type(extendz[j]);
}
retVal.setImplementz(extendzTypes);
field = new JavaField(new Type("java.lang.String"), ejbHomeUtils.getCompleteNameConst());
field.setModifiers(new String[]{"public","static","final"});
retVal.addField(field);
field = new JavaField(new Type("java.lang.String"), ejbHomeUtils.getJndiNameConst());
field.setModifiers(new String[]{"public","static","final"});
retVal.addField(field);
Collection methods = getCreateMethods(metadata);
for (Iterator iter = methods.iterator(); iter.hasNext();) {
method = new DuplicatedJavaMethod((JavaMethod)iter.next());
method.setModifiers(new String[0]);
retVal.addMethod(method);
}
if (ejbUtils.isEntityBean(metadata)) {
methods = getFinderMethods(metadata);
for (Iterator iter = methods.iterator(); iter.hasNext();) {
method = new DuplicatedJavaMethod((JavaMethod)iter.next());
method.setModifiers(new String[0]);
retVal.addMethod(method);
}
}
methods = getHomeMethods(metadata);
for (Iterator iter = methods.iterator(); iter.hasNext();) {
method = new DuplicatedJavaMethod((JavaMethod)iter.next());
method.setModifiers(new String[0]);
retVal.addMethod(method);
}
return new JavaClass[]{retVal};
}
public String[] getExtends(JavaClass javaClass) {
Collection extendsLst = new ArrayList();
EjbHomeTag homeTag = (EjbHomeTag) javaClass.getTagByName(TagLibrary.EJB_HOME);
if ((homeTag != null) && (homeTag.getExtends() != null)) {
extendsLst.addAll(Arrays.asList(homeTag.getExtends()));
}
if (!extendsLst.contains("javax.ejb.EJBHome")) {
extendsLst.add("javax.ejb.EJBHome");
}
return (String[]) extendsLst.toArray(new String[0]);
}
public String ejbJndiName(JavaClass clazz) {
return ejbUtils.getComponentName(clazz, EjbUtils.REMOTE, true);
}
public String jndiName(JavaClass clazz) {
return ejbUtils.getJndiName(clazz, EjbUtils.REMOTE);
}
public boolean shouldGenerate(Object metadata) {
JavaClass javaClass = (JavaClass) metadata;
EjbHomeTag homeTag = (EjbHomeTag) javaClass.getTagByName(TagLibrary.EJB_HOME);
boolean generate = super.shouldGenerate(metadata);
generate = generate && ((homeTag == null) || Arrays.asList(homeTag.getGenerate()).contains("remote"));
if (generate) generate = isDestinationDirty(javaClass);
if (generate && verbose) System.out.println(
"Generating Remote Home Interface for " + javaClass.getName());
return generate;
}
protected String getLocalyDefinedFullClassName(JavaClass clazz) {
EjbHomeTag homeTag = (EjbHomeTag) clazz.getTagByName(TagLibrary.EJB_HOME);
return homeTag != null ? homeTag.getRemoteClass() : super.getLocalyDefinedFullClassName(clazz);
}
protected String getLocalyDefinedPackageName(JavaClass clazz) {
EjbHomeTag homeTag = (EjbHomeTag) clazz.getTagByName(TagLibrary.EJB_HOME);
String definedPackage = null;
if (homeTag != null) {
definedPackage = homeTag.getRemotePackage();
if (definedPackage == null) {
definedPackage = homeTag.getPackage();
}
}
return definedPackage != null ? definedPackage : super.getLocalyDefinedPackageName(clazz);
}
protected String getPatternBasedUnqualifiedName(JavaClass clazz) {
EjbHomeTag homeTag = (EjbHomeTag) clazz.getTagByName(TagLibrary.EJB_HOME);
String pattern = null;
if (homeTag != null) {
pattern = homeTag.getRemotePattern();
if ((pattern == null) && (homeTag.getPattern() != null)) {
pattern = homeTag.getPattern() + "RemoteHome";
}
}
return pattern != null ? ejbUtils.expandPattern(pattern, clazz) : super.getPatternBasedUnqualifiedName(clazz);
}
protected void populateContextMap(Map map) {
super.populateContextMap(map);
map.put("homeUtil", getEjbHomeUtils());
}
public EjbHomeUtils getEjbHomeUtils() {
return this.ejbHomeUtils;
}
/**
* Don't let multioutput be changed
*/
public void setMultioutput(boolean multioutput) {
throw new RuntimeException("Can't set multioutput for plugin");
}
/**
* Don't let fileregex be changed
*/
public void setFileregex(String fileregex) {
throw new RuntimeException("Can't set fileregex for plugin. Try setting it in " + EjbConfig.class.getName());
}
public Collection getCreateMethods(final JavaClass javaClass) {
Collection createMethods = ejbHomeUtils.getCreateMethods(javaClass, EjbUtils.REMOTE_HOME,
EjbRuntime.getRemoteInterfacePlugin().getVirtualType(javaClass).getType());
return ejbUtils.injectMethodThrowException(createMethods, RemoteException.class);
}
public Collection getFinderMethods(final JavaClass javaClass) {
if (!ejbUtils.isEntityBean(javaClass)) {
throw new Error("This must only be called for Entity Beans");
}
Collection finderMethods = ejbHomeUtils.getFinderMethods(javaClass, EjbUtils.REMOTE_HOME,
EjbRuntime.getRemoteInterfacePlugin().getVirtualType(javaClass).getType());
return ejbUtils.injectMethodThrowException(finderMethods, RemoteException.class);
}
public Collection getHomeMethods(final JavaClass clazz) {
return ejbUtils.injectMethodThrowException(ejbHomeUtils.getHomeMethods(clazz, EjbUtils.REMOTE_HOME),
RemoteException.class);
}
}