package com.sun.tools.xjc.addon.ejb3cmp; import com.sun.codemodel.ClassType; import com.sun.codemodel.JAnnotationUse; import com.sun.codemodel.JClass; import com.sun.codemodel.JClassAlreadyExistsException; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JMethod; import com.sun.codemodel.JType; import com.sun.tools.xjc.Plugin; import com.sun.tools.xjc.model.CCustomizations; import com.sun.tools.xjc.model.CPluginCustomization; import com.sun.tools.xjc.model.CPropertyInfo; import com.sun.tools.xjc.outline.FieldOutline; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.sun.tools.xjc.Options; import com.sun.tools.xjc.outline.ClassOutline; import com.sun.tools.xjc.outline.Outline; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.ErrorHandler; public class EJB3Plugin extends Plugin { public static final String NS = "http://jaxb.dev.java.net/plugin/ejb3-cmp"; private boolean isSetTransient = false; private boolean isEntity = false; public List getCustomizationURIs() { return Collections.singletonList(NS); } public boolean isCustomizationTagName(String nsUri, String localName) { ArrayList list = new ArrayList(); list.add("annotate"); list.add("annotation"); list.add("param"); list.add("Entity"); list.add("isSetTransient"); return (nsUri.equals(Const.NS) && list.contains(localName)); } public String getOptionName() { return "Xejb3-cmp"; } public String getUsage() { return " -Xejb3-cmp : inject specified EJB3.0 Annotations into the generated code"; } // meat of the processing public boolean run(Outline outline, Options opt, ErrorHandler errorHandler) { for (ClassOutline co : outline.getClasses()) { this.isSetTransient=false; this.isEntity=false; annotateClass(outline, co); for( CPropertyInfo p : co.target.getProperties() ) { if (this.isSetTransient=true) { String fieldName = p.getName(true); String methodName = "isSet"+fieldName; String className = "javax.persistence.Transient"; JType[] jTypeArray = new JType[]{}; // value with JType for isSet JAnnotationUse juse = getMethodAnnotation(outline, co, className, methodName, jTypeArray); } annotateMethod(outline, co, p); } } return true; } private void annotateClass(Outline outline, ClassOutline co) { CCustomizations cList = co.target.getCustomizations(); for (CPluginCustomization c : cList) { Element e = c.element; if (e.getLocalName().equals("Entity")){ String className = "javax.persistence.Entity"; JAnnotationUse juse = getClassAnnotation(outline, co, className); this.isEntity=true; c.markAsAcknowledged(); } if (e.getLocalName().equals("annotate")){ NodeList nlist = e.getElementsByTagNameNS(Const.NS, "annotation"); for(int i = 0; i < nlist.getLength(); i++){ Element annotationLevel = (Element) nlist.item(i); if (annotationLevel.hasAttribute("className")) { String className = annotationLevel.getAttribute("className"); if ((className.equals("javax.persistence.Entity")==true)&&(this.isEntity==true)){ System.out.println("Entity already declared for class"); c.markAsAcknowledged(); } else{ JAnnotationUse juse = getClassAnnotation(outline, co, className); juse = addParams(juse, annotationLevel); c.markAsAcknowledged(); } } } } if (e.getLocalName().equals("isSetTransient")) { c.markAsAcknowledged(); this.isSetTransient=true; } } } private void annotateMethod(Outline outline, ClassOutline co, CPropertyInfo p) { CCustomizations cList = p.getCustomizations(); for (CPluginCustomization c : cList) { c.markAsAcknowledged(); Element e = c.element; if (e.getLocalName().equals("annotate")){ NodeList nlist = e.getElementsByTagNameNS(Const.NS, "annotation"); for(int i = 0; i < nlist.getLength(); i++){ Element annotationLevel = (Element) nlist.item(i); if (annotationLevel.hasAttribute("className")) { String className = annotationLevel.getAttribute("className"); String fieldName = p.getName(true); FieldOutline fe = outline.getField(p); JType jtype = fe.getRawType(); JType[] jTypeArray = new JType[]{}; // value with JType for getter if (annotationLevel.hasAttribute("type")){ String type = annotationLevel.getAttribute("type"); if (type.equals("get")){ c.markAsAcknowledged(); String methodName = "get"+fieldName; JAnnotationUse juse = getMethodAnnotation(outline, co, className, methodName, jTypeArray); juse = addParams(juse, annotationLevel); } if (type.equals("set")){ c.markAsAcknowledged(); String methodName = "set"+fieldName; jTypeArray = new JType[]{jtype}; // value with JType for setter JAnnotationUse juse = getMethodAnnotation(outline, co, className, methodName, jTypeArray); juse = addParams(juse, annotationLevel); } if (type.equals("get-set")){ c.markAsAcknowledged(); String methodName = "get"+fieldName; JAnnotationUse juse = getMethodAnnotation(outline, co, className, methodName, jTypeArray); juse = addParams(juse, annotationLevel); methodName = "set"+fieldName; jTypeArray = new JType[]{jtype}; // value with JType for setter juse = getMethodAnnotation(outline, co, className, methodName, jTypeArray); juse = addParams(juse, annotationLevel); } if (type.equals("isSet")){ if ((className.equals("javax.persistence.Transient")==true)&&(this.isSetTransient==true)){ System.out.println("isSetTransient already declared in class"); c.markAsAcknowledged(); } else{ c.markAsAcknowledged(); String methodName = "isSet"+fieldName; JAnnotationUse juse = getMethodAnnotation(outline, co, className, methodName, jTypeArray); juse = addParams(juse, annotationLevel); } } } } } } } } private JAnnotationUse addParams(JAnnotationUse juse, Element annotationLevel){ NodeList nlist = annotationLevel.getElementsByTagNameNS(Const.NS, "param"); for(int i = 0; i < nlist.getLength(); i++){ Element paramLevel = (Element) nlist.item(i); if (paramLevel.hasAttribute("label")) { if (paramLevel.hasAttribute("stringValue")) { String param = paramLevel.getAttribute("label"); String value = paramLevel.getAttribute("stringValue"); juse.param(param, value); } if (paramLevel.hasAttribute("enumValue")) { try{ String param = paramLevel.getAttribute("label"); String value = paramLevel.getAttribute("enumValue"); Class className = Class.forName(paramLevel.getAttribute("enumClass")); juse.param(param, Enum.valueOf(className, value)); } catch(ClassNotFoundException cnfe) { cnfe.printStackTrace(); } } if (paramLevel.hasAttribute("className")) { try{ String param = paramLevel.getAttribute("label"); Class className = Class.forName(paramLevel.getAttribute("className")); juse.param(param, className); } catch(ClassNotFoundException cnfe) { cnfe.printStackTrace(); } } } } return juse; } private JAnnotationUse getMethodAnnotation(Outline outline, ClassOutline co, String className, String methodName, JType[] jTypeArray) { JDefinedClass jdclass = co.implClass; JClass annotation =null; try { annotation = outline.getCodeModel().ref(className); } catch (ClassNotFoundException ce) { try { annotation = outline.getCodeModel()._class(className,ClassType.ANNOTATION_TYPE_DECL); } catch (JClassAlreadyExistsException x) { annotation = x.getExistingClass(); } } JMethod method = jdclass.getMethod(methodName, jTypeArray); return method.annotate(annotation); } private JAnnotationUse getClassAnnotation(Outline outline, ClassOutline co, String className) { JClass annotation =null; try { annotation = outline.getCodeModel().ref(className); } catch (ClassNotFoundException ce) { try { annotation = outline.getCodeModel()._class(className,ClassType.ANNOTATION_TYPE_DECL); } catch (JClassAlreadyExistsException x) { annotation = x.getExistingClass(); } } return co.implClass.annotate(annotation); } }