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") || trimmed.equalsIgnoreCase("simpleType");
126 }
127
128 /*
129 <xs:simpleType name="foodPreference">
130 <!-- ClassLocation JavaDocData insertion point -->
131
132 <xs:restriction base="xs:string">
133
134 <!-- FieldLocation or MethodLocation JavaDocData insertion point (within child) -->
135 <xs:enumeration value="NONE"/>
136
137 <!-- FieldLocation or MethodLocation JavaDocData insertion point (within child) -->
138 <xs:enumeration value="LACTO_VEGETARIAN"/>
139
140 <!-- FieldLocation or MethodLocation JavaDocData insertion point (within child) -->
141 <xs:enumeration value="VEGAN"/>
142
143 </xs:restriction>
144 </xs:simpleType>
145 */
146
147 /*
148 <xs:simpleType name="foodPreference">
149 <xs:restriction base="xs:string">
150 <xs:enumeration value="NONE"/>
151 <xs:enumeration value="LACTO_VEGETARIAN"/>
152 <xs:enumeration value="VEGAN"/>
153 </xs:restriction>
154 </xs:simpleType>
155
156 <xs:simpleType name="americanCoin">
157 <xs:restriction base="xs:int">
158 <xs:enumeration value="25"/>
159 <xs:enumeration value="1"/>
160 <xs:enumeration value="5"/>
161 <xs:enumeration value="10"/>
162 </xs:restriction>
163 </xs:simpleType>
164 */
165
166 // All done.
167 return false;
168 }
169
170 /**
171 * {@inheritDoc}
172 */
173 @Override
174 public void process(final Node aNode) {
175 DomHelper.insertXmlDocumentationAnnotationsFor(aNode, classJavaDocs, fieldJavaDocs, methodJavaDocs, renderer);
176 }
177 }