1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.uruma.component.writer;
17
18 import java.io.IOException;
19 import java.io.Writer;
20 import java.lang.reflect.Field;
21 import java.util.List;
22
23 import org.seasar.framework.util.FieldUtil;
24 import org.seasar.framework.util.StringUtil;
25 import org.seasar.uruma.annotation.ComponentAttribute;
26 import org.seasar.uruma.annotation.ComponentElement;
27 import org.seasar.uruma.component.Template;
28 import org.seasar.uruma.component.UIComponentContainer;
29 import org.seasar.uruma.component.UIElement;
30 import org.seasar.uruma.component.UIElementContainer;
31 import org.seasar.uruma.component.UIElementVisitor;
32 import org.seasar.uruma.core.UrumaConstants;
33 import org.seasar.uruma.util.AnnotationUtil;
34 import org.seasar.uruma.util.AssertionUtil;
35
36
37
38
39
40
41 public class UIElementWriter implements UIElementVisitor, UrumaConstants {
42 protected Writer writer;
43
44 private int indentLevel;
45
46 private static final String INDENT = " ";
47
48
49
50
51
52
53
54 public UIElementWriter(final Writer writer) {
55 AssertionUtil.assertNotNull("writer", writer);
56 this.writer = writer;
57 }
58
59
60
61
62 public void visit(final UIElement element) {
63 AssertionUtil.assertNotNull("element", element);
64
65 try {
66 writeStartTag(element, true);
67 } catch (IOException ex) {
68
69 ex.printStackTrace();
70 }
71 }
72
73
74
75
76 public void visit(final UIElementContainer container) {
77 AssertionUtil.assertNotNull("container", container);
78
79 try {
80 writeStartTag(container, false);
81
82 indent();
83 for (UIElement element : container.getChildren()) {
84 element.accept(this);
85 }
86 deindent();
87
88 writeEndTag(container);
89 } catch (IOException ex) {
90
91 ex.printStackTrace();
92 }
93 }
94
95
96
97
98 public void visit(final Template template) {
99 AssertionUtil.assertNotNull("template", template);
100 try {
101 writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
102 writer
103 .write("<template xmlns=\"http://uruma.sandbox.seasar.org\">\n");
104 indent();
105
106 UIComponentContainer root = template.getRootComponent();
107 if (root != null) {
108 root.accept(this);
109 }
110
111 deindent();
112 writer.write("</template>\n");
113 writer.flush();
114 } catch (IOException ex) {
115
116 }
117 }
118
119 protected void writeStartTag(final UIElement element,
120 final boolean startTagOnly) throws IOException {
121 String elementName = getElementName(element.getClass());
122 if (elementName == null) {
123
124 return;
125 }
126
127 writeIndent();
128 writer.write('<');
129 writer.write(elementName);
130
131 List<Field> fields = AnnotationUtil.getAnnotatedFields(element
132 .getClass(), ComponentAttribute.class);
133
134 for (Field field : fields) {
135 String attrName = getAttributeName(field);
136 String value = FieldUtil.getString(field, element);
137 if (value == null) {
138 ComponentAttribute attr = field
139 .getAnnotation(ComponentAttribute.class);
140 if (attr.required()) {
141 value = NULL_STRING;
142 }
143 }
144
145 if (value != null) {
146 writer.write(' ');
147 writer.write(attrName);
148 writer.write("=\"");
149 writer.write(value);
150 writer.write('"');
151 }
152 }
153
154 if (startTagOnly) {
155 writer.write(" />\n");
156 } else {
157 writer.write(" >\n");
158 }
159 writer.flush();
160 }
161
162 protected void writeEndTag(final UIElement element) throws IOException {
163 String elementName = getElementName(element.getClass());
164 if (elementName == null) {
165
166 return;
167 }
168
169 writeIndent();
170 writer.write("</");
171 writer.write(elementName);
172 writer.write(">\n");
173 writer.flush();
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187 protected String getElementName(final Class<?> clazz) {
188 ComponentElement anno = clazz.getAnnotation(ComponentElement.class);
189 if (anno == null) {
190 return null;
191 }
192
193 String elementName = anno.value();
194 if (NULL_STRING.equals(elementName)) {
195 String className = clazz.getSimpleName();
196 if (className.endsWith("Component")) {
197 elementName = className.substring(0, className.length()
198 - "Component".length());
199 elementName = StringUtil.decapitalize(elementName);
200 } else {
201 return null;
202 }
203 }
204
205 return elementName;
206 }
207
208 protected String getAttributeName(final Field field) {
209 ComponentAttribute attr = field.getAnnotation(ComponentAttribute.class);
210 if (attr == null) {
211 return null;
212 }
213
214 String attrName = attr.name();
215 if (NULL_STRING.equals(attrName)) {
216 attrName = field.getName();
217 }
218 return attrName;
219 }
220
221 protected void writeIndent() throws IOException {
222 StringBuffer buf = new StringBuffer(INDENT.length() * indentLevel);
223 for (int i = 0; i < indentLevel; i++) {
224 buf.append(INDENT);
225 }
226 writer.write(buf.toString());
227 }
228
229
230
231
232 public void resetIndent() {
233 indentLevel = 0;
234 }
235
236
237
238
239 public void indent() {
240 indentLevel++;
241 }
242
243
244
245
246 public void deindent() {
247 indentLevel--;
248 }
249 }