1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.apt;
21
22 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
23 import com.sun.mirror.apt.Filer;
24 import com.sun.mirror.declaration.Declaration;
25 import com.sun.mirror.declaration.MethodDeclaration;
26 import com.sun.mirror.declaration.PackageDeclaration;
27 import org.apache.commons.io.IOUtils;
28 import org.apache.commons.lang.ClassUtils;
29 import org.apache.myfaces.tobago.apt.annotation.BodyContent;
30 import org.apache.myfaces.tobago.apt.annotation.BodyContentDescription;
31 import org.apache.myfaces.tobago.apt.annotation.Tag;
32 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
33 import org.apache.myfaces.tobago.apt.annotation.Taglib;
34 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
35 import org.w3c.dom.Document;
36 import org.w3c.dom.Element;
37
38 import javax.xml.transform.OutputKeys;
39 import javax.xml.transform.Transformer;
40 import javax.xml.transform.TransformerException;
41 import javax.xml.transform.TransformerFactory;
42 import javax.xml.transform.dom.DOMSource;
43 import javax.xml.transform.stream.StreamResult;
44 import java.io.File;
45 import java.io.IOException;
46 import java.io.Writer;
47 import java.util.Locale;
48
49 public class TobagoAnnotationVisitor extends TaglibAnnotationVisitor {
50
51 public TobagoAnnotationVisitor(AnnotationProcessorEnvironment env) {
52 super(env);
53 }
54
55 @Override
56 protected void writeTaglib(PackageDeclaration packageDeclaration, Taglib taglibAnnotation, Document document)
57 throws IOException, TransformerException {
58 Writer writer = null;
59 try {
60 getEnv().getMessager().printNotice("Create DOM");
61 String fileName = taglibAnnotation.fileName().substring(0, taglibAnnotation.fileName().length() - 3) + "xml";
62
63 writer = getEnv().getFiler().createTextFile(
64 Filer.Location.SOURCE_TREE, packageDeclaration.getQualifiedName(), new File(fileName), null);
65 TransformerFactory transFactory = TransformerFactory.newInstance();
66 transFactory.setAttribute("indent-number", 2);
67 Transformer transformer = transFactory.newTransformer();
68
69
70
71
72 transformer.setOutputProperty(OutputKeys.METHOD, "xml");
73 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
74 transformer.transform(new DOMSource(document), new StreamResult(writer));
75 getEnv().getMessager().printNotice("Write to file " + packageDeclaration.getQualifiedName() + "." + fileName);
76 } finally {
77 IOUtils.closeQuietly(writer);
78 }
79 }
80
81 @Override
82 protected Element createTag(Declaration decl, Tag tag, String className, Document document, boolean deprecated) {
83 Element tagElement = document.createElement("tag");
84 addDescription(decl, tagElement, document, false);
85 addLeafTextElement(tag.name(), "name", tagElement, document);
86 addLeafTextElement(className, "tag-class", tagElement, document);
87
88 BodyContent bodyContent = tag.bodyContent();
89 BodyContentDescription contentDescription = decl.getAnnotation(BodyContentDescription.class);
90
91 if (contentDescription != null) {
92 if (bodyContent.equals(BodyContent.JSP)
93 && contentDescription.contentType().length() > 0) {
94 throw new IllegalArgumentException(
95 "contentType " + contentDescription.contentType() + " for bodyContent JSP not allowed!");
96 } else if (bodyContent.equals(BodyContent.TAGDEPENDENT)
97 && contentDescription.contentType().length() == 0) {
98 throw new IllegalArgumentException("contentType should set for tagdependent bodyContent");
99 }
100 }
101
102 addLeafTextElement(bodyContent.toString(), "body-content", tagElement, document);
103 if (contentDescription != null) {
104 Element bodyContentDescription = document.createElement("body-content-description");
105 for (int i = 0; i < contentDescription.anyClassOf().length; i++) {
106 Element clazz = document.createElement("class");
107 String typeClass = contentDescription.anyClassOf()[i];
108 addLeafTextElement(ClassUtils.getShortClassName(typeClass), "name", clazz, document);
109 addLeafTextElement(ClassUtils.getPackageName(typeClass), "package", clazz, document);
110 bodyContentDescription.appendChild(clazz);
111 }
112 if (contentDescription.anyTagOf().length() > 0) {
113 addLeafTextElement(contentDescription.anyTagOf(), "tags", bodyContentDescription, document);
114 }
115 if (contentDescription.contentType().length() > 0) {
116 addLeafTextElement(contentDescription.contentType(), "content-type", bodyContentDescription, document);
117 }
118 tagElement.appendChild(bodyContentDescription);
119 }
120
121 return tagElement;
122 }
123
124 @Override
125 protected void addAttribute(MethodDeclaration method, Element tagElement, Document document) {
126 TagAttribute tagAttribute = method.getAnnotation(TagAttribute.class);
127 if (tagAttribute != null) {
128 UIComponentTagAttribute uiTagAttribute = null;
129 try {
130 uiTagAttribute = method.getAnnotation(UIComponentTagAttribute.class);
131 } catch (RuntimeException e) {
132 e.printStackTrace();
133 }
134 String simpleName = method.getSimpleName();
135 if (simpleName.startsWith("set")) {
136 Element attribute = document.createElement("attribute");
137 addDescription(method, attribute, document);
138 addLeafTextElement(simpleName.substring(3, 4).toLowerCase(Locale.ENGLISH)
139 + simpleName.substring(4), "name", attribute, document);
140 addLeafTextElement(Boolean.toString(tagAttribute.required()), "required", attribute, document);
141 addLeafTextElement(Boolean.toString(tagAttribute.rtexprvalue()), "rtexprvalue", attribute, document);
142 if (uiTagAttribute != null) {
143 addLeafTextElement(uiTagAttribute.expression().toString(), "ui-attribute-expression", attribute, document);
144
145 String[] uiTypeClasses = uiTagAttribute.type();
146 if (uiTypeClasses.length > 0) {
147 Element uiAttributeType = document.createElement("ui-attribute-type");
148 for (String typeClass : uiTypeClasses) {
149 Element clazz = document.createElement("class");
150 addLeafTextElement(ClassUtils.getShortClassName(typeClass), "name", clazz, document);
151 addLeafTextElement(ClassUtils.getPackageName(typeClass), "package", clazz, document);
152 uiAttributeType.appendChild(clazz);
153 }
154 attribute.appendChild(uiAttributeType);
155 }
156 if (uiTagAttribute.defaultValue().length() > 0) {
157 addLeafTextElement(uiTagAttribute.defaultValue(), "ui-attribute-default-value", attribute, document);
158 }
159
160 }
161
162 tagElement.appendChild(attribute);
163 } else {
164 throw new IllegalArgumentException("Only setter allowed found: " + simpleName);
165 }
166 }
167 }
168 }