/**
*
*/
package com.sun.tools.xjc.addon;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.tools.xjc.BadCommandLineException;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.Plugin;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.Outline;
/**
* This plugin adds a call to init() (or another defined method) to all generated class' no-arg constructors.
*
* The default behavior checks if the class of the current constructor's object is either the examined class or the
* user-specified implClass. This allows the init function to be called only once for each object even if your generated
* classes inherit one from another.
*
* @author Martin Pecka
*/
public class CallInitAfterConstructPlugin extends Plugin
{
/** The method to call. */
protected String initMethod = "init";
/** If false, the constructor won't check the class of created object as a condition to call the init method. */
protected boolean checkClass = true;
@Override
public String getOptionName()
{
return "Xcall-init-after-construct";
}
@Override
public String getUsage()
{
return " -Xcall-init-after-construct:\tadd a call to init() (or another defined method) to all generated class' no-arg constructors."
+ " -Xcall-init-after-construct-init-fn:\teither a name of the init a method or a call to the method as string (the default is \"init\")"
+ " -Xcall-init-after-construct-no-class-check:\tif set, the constructor won't check the class of created object as a condition to call the init method.";
}
@Override
public List<String> getCustomizationURIs()
{
return Collections.singletonList("http://www.mff.cuni.cz/~peckam/java/origamist/jaxb/plugins");
}
@Override
public int parseArgument(Options opt, String[] args, int i) throws BadCommandLineException, IOException
{
int parentRes = super.parseArgument(opt, args, i);
if (parentRes > 0)
return parentRes;
String option = args[i];
if (option.equals(option.equals("-Xcall-init-after-construct-init-fn"))) {
if (args.length < i + 2) {
throw new BadCommandLineException("-Xcall-init-after-construct-init-fn needs an argument");
}
initMethod = args[i + 1];
return 2;
} else if (option.equals("-Xcall-init-after-construct-no-class-check")) {
checkClass = false;
}
return 0;
}
@Override
public boolean run(Outline model, Options opt, ErrorHandler errorHandler) throws SAXException
{
for (ClassOutline co : model.getClasses()) {
JMethod constructor = null;
for (@SuppressWarnings("unchecked")
Iterator<JMethod> it = co.implClass.constructors(); it.hasNext();) {
JMethod constr = it.next();
if (constr.listParams().length == 0) {
constructor = constr;
break;
}
}
if (constructor == null)
constructor = co.implClass.constructor(JMod.PUBLIC);
JBlock body = constructor.body();
String className;
if (co.target.getUserSpecifiedImplClass() != null)
className = co.target.getUserSpecifiedImplClass();
else
className = co.implClass.fullName();
JBlock then;
if (checkClass)
then = body._if(JExpr.invoke("getClass").invoke("getName").invoke("equals").arg(className))._then();
else
then = body;
if (!initMethod.contains("(")) {
then.invoke(initMethod);
} else {
then.directStatement(initMethod);
}
}
return true;
}
}