/**
*
*/
package com.sun.tools.xjc.addon;
import java.lang.reflect.Field;
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.JAnnotationArrayMember;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JMethod;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.Plugin;
import com.sun.tools.xjc.outline.Outline;
import com.sun.tools.xjc.outline.PackageOutline;
/**
* XJC plugin (to be accurate, bugfix). Sometimes the created Object factory uses cast to raw Class class, which
* issues a warning. This patch adds @SupressWarnings("rawtypes", "unchecked") to the createElement factory.
*
* @author Martin Pecka
*/
public class PatchForObjectFactoryUncheckedCastUsage extends Plugin
{
@Override
public String getOptionName()
{
return "Xpatch-objFactory-uncheckedCast";
}
@Override
public String getUsage()
{
return " -Xpatch-objFactory-uncheckedCast: add @SupressWarnings(\"rawtypes\", \"unchecked\") to createElement() method in ObjectFactory";
}
@Override
public List<String> getCustomizationURIs()
{
return Collections.singletonList("http://www.mff.cuni.cz/~peckam/java/origamist/jaxb/plugins/patch");
}
@Override
public boolean run(Outline model, Options opt, ErrorHandler errorHandler) throws SAXException
{
Iterator<? extends PackageOutline> i = model.getAllPackageContexts().iterator();
while (i.hasNext()) {
PackageOutline pack = i.next();
JDefinedClass factory = pack.objectFactory();
// iterate through all methods of the object factory
outer: for (JMethod m : factory.methods()) {
@SuppressWarnings("unchecked")
List<JAnnotationUse> annots = (List<JAnnotationUse>) getValueWithReflection("annotations", m,
JMethod.class);
if (annots == null)
continue;
boolean foundXmlElementDeclAnnot = false;
// search for @XmlElementDecl annotation
for (JAnnotationUse annot : annots) {
JClass annotClass = (JClass) getValueWithReflection("clazz", annot, JAnnotationUse.class);
if ("XmlElementDecl".equals(annotClass.name())) {
foundXmlElementDeclAnnot = true;
break;
} else {
continue outer;
}
}
if (!foundXmlElementDeclAnnot)
continue;
// if this method has the @XmlElementDecl annotation, we want to add the @SuppressWarnings annotation.
JAnnotationUse annot = m.annotate(SuppressWarnings.class);
JAnnotationArrayMember params = annot.paramArray("value");
params.param("rawtypes");
params.param("unchecked");
}
}
return true;
}
/**
* Uses reflection to get the value of the field <code>field</code> of <code>obj</code>.
*
* @param field The name of the field to get.
* @param obj The object we get a field of.
* @param clazz The class containing the field (exactly that class, not a subclass or so!).
*/
protected Object getValueWithReflection(String field, Object obj, Class<?> clazz)
{
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
if (!field.equals(f.getName()))
continue;
f.setAccessible(true);
try {
return f.get(obj);
} catch (IllegalArgumentException e) {
System.err.println(e);
} catch (IllegalAccessException e) {
System.err.println(e);
}
}
return null;
}
}