1 package org.codehaus.mojo.jaxb2.schemageneration.postprocessing.javadoc; 2 3 import org.codehaus.mojo.jaxb2.schemageneration.postprocessing.NodeProcessor; 4 import org.codehaus.mojo.jaxb2.schemageneration.postprocessing.javadoc.location.ClassLocation; 5 import org.codehaus.mojo.jaxb2.schemageneration.postprocessing.javadoc.location.FieldLocation; 6 import org.codehaus.mojo.jaxb2.schemageneration.postprocessing.javadoc.location.MethodLocation; 7 import org.codehaus.mojo.jaxb2.shared.Validate; 8 import org.w3c.dom.Element; 9 import org.w3c.dom.Node; 10 11 import java.util.SortedMap; 12 13 14 /** 15 * <p>Node processor that injects XSD documentation annotations consisting of JavaDoc harvested Java source code 16 * into SimpleTypes, Elements and Attributes typically produced by SchemaGen when generate XSDs for Java Enumerations. 17 * The documentation is injected as follows:</p> 18 * <ol> 19 * <li><strong>SimpleType</strong>: Class-level JavaDoc from the corresponding type is injected as an 20 * annotation directly inside the SimpleType.</li> 21 * <li><strong>Element</strong>: Field-level JavaDoc (or getter Method-level JavaDoc, in case the Field does 22 * not contain a JavaDoc annotation) from the corresponding member is injected as an 23 * annotation directly inside the element.</li> 24 * <li><strong>Attribute</strong>: Field-level JavaDoc (or getter Method-level JavaDoc, in case the Field does 25 * not contain a JavaDoc annotation) from the corresponding member is injected as an 26 * annotation directly inside the element.</li> 27 * </ol> 28 * <p>Thus, the following 'vanilla'-generated XSD:</p> 29 * <pre> 30 * <code> 31 * <xs:simpleType name="foodPreference"> 32 * <xs:restriction base="xs:string"> 33 * <xs:enumeration value="NONE"/> 34 * <xs:enumeration value="VEGAN"/> 35 * <xs:enumeration value="LACTO_VEGETARIAN"/> 36 * </xs:restriction> 37 * </xs:simpleType> 38 * </code> 39 * </pre> 40 * <p>... will be converted in a manner similar to the one below:</p> 41 * <pre> 42 * <code> 43 * <xs:simpleType name="foodPreference"> 44 * <xs:annotation> 45 * <xs:documentation><![CDATA[Simple enumeration example defining some Food preferences.]]></xs:documentation> 46 * </xs:annotation> 47 * <xs:restriction base="xs:string"> 48 * <xs:enumeration value="LACTO_VEGETARIAN"> 49 * <xs:annotation> 50 * <xs:documentation><![CDATA[Vegetarian who will not eat meats, but drinks milk.]]></xs:documentation> 51 * </xs:annotation> 52 * </xs:enumeration> 53 * <xs:enumeration value="NONE"> 54 * <xs:annotation> 55 * <xs:documentation><![CDATA[No special food preferences; eats everything.]]></xs:documentation> 56 * </xs:annotation> 57 * </xs:enumeration> 58 * <xs:enumeration value="VEGAN"> 59 * <xs:annotation> 60 * <xs:documentation><![CDATA[Vegan who will neither eat meats nor drink milk.]]></xs:documentation> 61 * </xs:annotation> 62 * </xs:enumeration> 63 * </xs:restriction> 64 * </xs:simpleType> 65 * </code> 66 * </pre> 67 * <p>... given that the Java class <code>FoodPreference</code> has JavaDoc on its class and fields 68 * corresponding to the injected XSD annotation/documentation elements.</p> 69 * 70 * @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a>, jGuru Europe AB 71 */ 72 public class XsdEnumerationAnnotationProcessor implements NodeProcessor { 73 74 // Internal state 75 private SortedMap<ClassLocation, JavaDocData> classJavaDocs; 76 private SortedMap<FieldLocation, JavaDocData> fieldJavaDocs; 77 private SortedMap<MethodLocation, JavaDocData> methodJavaDocs; 78 private JavaDocRenderer renderer; 79 80 /** 81 * Creates an XsdEnumerationAnnotationProcessor that uses the supplied/generated SearchableDocumentation to read all 82 * JavaDoc structures and the supplied JavaDocRenderer to render JavaDocs into XSD documentation annotations. 83 * 84 * @param docs A non-null SearchableDocumentation, produced from the source code of the JAXB compilation unit. 85 * @param renderer A non-null JavaDocRenderer, used to render the JavaDocData within the SearchableDocumentation. 86 */ 87 public XsdEnumerationAnnotationProcessor(final SearchableDocumentation docs, final JavaDocRenderer renderer) { 88 89 // Check sanity 90 Validate.notNull(docs, "docs"); 91 Validate.notNull(renderer, "renderer"); 92 93 // Assign internal state 94 this.classJavaDocs = docs.getAll(ClassLocation.class); 95 this.fieldJavaDocs = docs.getAll(FieldLocation.class); 96 this.methodJavaDocs = docs.getAll(MethodLocation.class); 97 this.renderer = renderer; 98 } 99 100 /** 101 * <p>Only accept simpleTypes which are restrictions to either <code>xs:string</code> or <code>xs:integer</code>. 102 * The former is generated by JAXB when the Java Enum uses String values, and the latter is used 103 * for ordinal values.</p> 104 * 105 * {@inheritDoc} 106 */ 107 @Override 108 public boolean accept(final Node aNode) { 109 110 // Only deal with Element nodes. 111 if (aNode.getNodeType() != Node.ELEMENT_NODE) { 112 return false; 113 } 114 115 // We should accept: 116 // 117 // 1) A simpleType Element 118 // 2) An enumeration Element 119 final Element theElement = (Element) aNode; 120 121 final String localName = theElement.getLocalName(); 122 if (localName != null) { 123 124 final String trimmed = localName.trim(); 125 return trimmed.equalsIgnoreCase("enumeration") 126 || trimmed.equalsIgnoreCase("simpleType"); 127 } 128 129 /* 130 <xs:simpleType name="foodPreference"> 131 <!-- ClassLocation JavaDocData insertion point --> 132 133 <xs:restriction base="xs:string"> 134 135 <!-- FieldLocation or MethodLocation JavaDocData insertion point (within child) --> 136 <xs:enumeration value="NONE"/> 137 138 <!-- FieldLocation or MethodLocation JavaDocData insertion point (within child) --> 139 <xs:enumeration value="LACTO_VEGETARIAN"/> 140 141 <!-- FieldLocation or MethodLocation JavaDocData insertion point (within child) --> 142 <xs:enumeration value="VEGAN"/> 143 144 </xs:restriction> 145 </xs:simpleType> 146 */ 147 148 /* 149 <xs:simpleType name="foodPreference"> 150 <xs:restriction base="xs:string"> 151 <xs:enumeration value="NONE"/> 152 <xs:enumeration value="LACTO_VEGETARIAN"/> 153 <xs:enumeration value="VEGAN"/> 154 </xs:restriction> 155 </xs:simpleType> 156 157 <xs:simpleType name="americanCoin"> 158 <xs:restriction base="xs:int"> 159 <xs:enumeration value="25"/> 160 <xs:enumeration value="1"/> 161 <xs:enumeration value="5"/> 162 <xs:enumeration value="10"/> 163 </xs:restriction> 164 </xs:simpleType> 165 */ 166 167 // All done. 168 return false; 169 } 170 171 /** 172 * {@inheritDoc} 173 */ 174 @Override 175 public void process(final Node aNode) { 176 DomHelper.insertXmlDocumentationAnnotationsFor(aNode, classJavaDocs, fieldJavaDocs, methodJavaDocs, renderer); 177 } 178 }