package xjc.plugins.jaxbbooleangetterplugin;

import org.xml.sax.ErrorHandler;

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JType;
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;

/**
 *   
 * @author Fortomas Philipos
 * @author Hadjistratis Emmanuel
 *
 */

public class JaxbBooleanGetterPlugin extends Plugin
{
    private static final String OPTION_NAME = "Xfix-boolean-getter";

    private static final String GET_PREFIX = "get";
    private static final String ISA_PREFIX = "is";
    
    public JaxbBooleanGetterPlugin()
    {
    }

    @Override
    public String getOptionName()
    {
        return OPTION_NAME;
    }
    
    @Override
    public String getUsage()
    {
        return "-" + OPTION_NAME + " : generate both 'getXXX' and 'isXXX' for fields of type java.lang.Boolean";
    }
    
    @Override
    public boolean run(Outline outline,
                       @SuppressWarnings("unused") Options opt,
                       @SuppressWarnings("unused") ErrorHandler errorHandler)
    {
        for (ClassOutline classOutline : outline.getClasses())
        {
            JDefinedClass targetImplClass = classOutline.implClass;
            for (JFieldVar fldVar : targetImplClass.fields().values())
            {
                if(fldVar.type().name().equals("Boolean"))
                {
                    createGetters(targetImplClass, fldVar, new String[]{ISA_PREFIX, GET_PREFIX});
                }
            }
        }
        return true;
    }
    
    private void createGetters(JDefinedClass defClass, JFieldVar fldVar, String[] prefixes)
    {
        String varName  = fldVar.name();
        String normName = varName.substring(0, 1).toUpperCase() + varName.substring(1);
        
        for (String prefix : prefixes)
        {
            String methodName = prefix + normName;
            if (null == defClass.getMethod(methodName, new JType[]{ }))
            {
                defClass.method(JMod.PUBLIC, fldVar.type(), methodName).body()._return(JExpr.ref(varName));
            }
        }
    }
}
