package at.ac.tuwien.infosys.jaxb; import javax.xml.bind.annotation.Annotation; import javax.xml.bind.annotation.AppInfo; import javax.xml.bind.annotation.Documentation; import javax.xml.bind.annotation.Facets; import javax.xml.bind.annotation.Facets.WhiteSpace; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import com.sun.codemodel.JAnnotationUse; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JFieldVar; import com.sun.tools.xjc.Options; import com.sun.tools.xjc.Plugin; import com.sun.tools.xjc.generator.bean.ClassOutlineImpl; import com.sun.tools.xjc.outline.ClassOutline; import com.sun.tools.xjc.outline.FieldOutline; import com.sun.tools.xjc.outline.Outline; import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIDeclaration; import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIXPluginCustomization; import com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo; import com.sun.xml.xsom.XSAnnotation; import com.sun.xml.xsom.XSComponent; import com.sun.xml.xsom.XSFacet; import com.sun.xml.xsom.XSSimpleType; import com.sun.xml.xsom.XSType; import com.sun.xml.xsom.impl.AnnotationImpl; import com.sun.xml.xsom.impl.ParticleImpl; /** * wsimport plugin to generate JAXB-Facets specific annotations in generated Java code. * @author Waldemar Hummer (hummer@infosys.tuwien.ac.at) * @since JAXB-Facets 1.1.0 */ public class WsImportFacetsPlugin extends Plugin { public String getOptionName() { return "jaxb-facets"; } public String getUsage() { return " -jaxb-facets : Generate JAXB annotations for XSD <facet>'s and <annotation>'s"; } public boolean run(Outline outline, Options opt, ErrorHandler errorHandler) throws SAXException { for(ClassOutline c: outline.getClasses()) { ClassOutlineImpl ci = (ClassOutlineImpl)c; XSComponent schemaEl = ci.target.getSchemaComponent(); addXsdAnnotation(ci, schemaEl); addXsdFacets(ci, schemaEl); } return true; } public static void addXsdFacets(ClassOutlineImpl ci, XSComponent schemaEl) { JDefinedClass clazz = ci.implClass; for(FieldOutline f : ci.getDeclaredFields()) { XSComponent schema = f.getPropertyInfo().getSchemaComponent(); if(schema instanceof ParticleImpl) { ParticleImpl p = (ParticleImpl)schema; if(p.getTerm().isElementDecl()) { XSType type = p.getTerm().asElementDecl().getType(); if(type.isSimpleType()) { XSSimpleType stype = type.asSimpleType(); for(String fName : Constants.FACET_NAMES) { XSFacet fValue = stype.getFacet(fName); if(fValue != null) { String name = f.getPropertyInfo().getName(false); JFieldVar var = clazz.fields().get(name); JAnnotationUse anno = getAnnotation(var, Facets.class); Class<?> typeClazz = Constants.FACET_TYPES.get(fName); if(typeClazz == long.class) { anno.param(fValue.getName(), Long.parseLong(fValue.getValue().value)); } else if(typeClazz == String.class) { anno.param(fValue.getName(), fValue.getValue().value); } else if(typeClazz == WhiteSpace.class) { anno.param(fValue.getName(), WhiteSpace.valueOf(fValue.getValue().value)); } else if(typeClazz == String[].class) { // TODO for "enumeration" facet - is this needed? } } } } } else { // TODO - what to do in this case..? } } } } public static void addXsdAnnotation(ClassOutlineImpl ci, XSComponent schemaEl) { XSAnnotation anno = schemaEl.getAnnotation(); if(anno != null) { AnnotationImpl annoImpl = (AnnotationImpl)anno; BindInfo annoInfo = (BindInfo)annoImpl.getAnnotation(); if(annoInfo != null) { /* add @Documentation annotation */ final String doc = annoInfo.getDocumentation(); JAnnotationUse jAnno = null; if(doc != null) { jAnno = getAnnotation(ci.implClass, Annotation.class); JAnnotationUse annoUse = jAnno.annotationParam("documentation", Documentation.class); annoUse.param("value", doc); } /* add @AppInfo annotation */ for(BIDeclaration decl : annoInfo.getDecls()) { if(decl instanceof BIXPluginCustomization) { if(jAnno == null) { jAnno = getAnnotation(ci.implClass, Annotation.class); } JAnnotationUse annoUseAppInfo = jAnno.annotationParam("appinfo", AppInfo.class); BIXPluginCustomization plc = (BIXPluginCustomization) decl; annoUseAppInfo.param("value", XmlUtil.toStringWithStrippedNamespaces(plc.element)); /* * TODO: <appinfo>'s source=".." attribute is not available due to limitations in JAXB/XJC: * http://grepcode.com/file/repo1.maven.org/maven2/com.sun.xml.bind/jaxb-xjc/2.2.5/com/sun/tools/xjc/reader/xmlschema/bindinfo/BindInfo.java?av=f#148 */ } } } } } private static JAnnotationUse getAnnotation(JDefinedClass clazz, Class<? extends java.lang.annotation.Annotation> annoClass) { for(JAnnotationUse a : clazz.annotations()) { if(a.getAnnotationClass().fullName().equals(annoClass.getName())) { return a; } } JAnnotationUse jAnno = clazz.annotate(annoClass); return jAnno; } private static JAnnotationUse getAnnotation(JFieldVar var, Class<? extends java.lang.annotation.Annotation> annoClass) { for(JAnnotationUse a : var.annotations()) { if(a.getAnnotationClass().fullName().equals(annoClass.getName())) { return a; } } JAnnotationUse jAnno = var.annotate(annoClass); return jAnno; } }