1
2
3
4
5
6
7
8
9
10
11
12 package org.hyphenType.documentation;
13
14 import java.io.PrintStream;
15 import java.lang.annotation.Annotation;
16 import java.lang.reflect.Constructor;
17 import java.lang.reflect.InvocationTargetException;
18 import java.lang.reflect.Method;
19 import java.util.MissingResourceException;
20 import java.util.ResourceBundle;
21
22 import org.hyphenType.datastructure.Options;
23 import org.hyphenType.datastructure.annotations.ArgumentsObject;
24 import org.hyphenType.exceptions.InvalidOptionsInterfaceException;
25 import org.hyphenType.exit.ExitStatusConstant;
26 import org.hyphenType.lexerparser.LexerParser;
27 import org.hyphenType.util.DefaultAnnotation;
28 import org.hyphenType.util.I18NResourceBundle;
29 import org.hyphenType.util.soc.StringObjectConversion;
30 import org.hyphenType.util.soc.StringParsingError;
31
32
33
34
35
36
37
38
39 public abstract class DocumentationFormatterEngine<T extends Options<?>, V extends Annotation> {
40
41
42
43
44 private LexerParser<T> lexPar;
45
46
47
48 private V annotation;
49
50
51
52 private ResourceBundle rb;
53
54
55
56
57 protected DocumentationFormatterEngine() {
58 }
59
60
61
62
63
64 private void setLexerParser(final LexerParser<T> lexerParser) {
65 lexPar = lexerParser;
66 }
67
68
69
70
71
72 private void setAnnotation(final V formatterAnnotation) {
73 annotation = formatterAnnotation;
74
75 }
76
77
78
79
80
81 private void setResourceBundle(final ResourceBundle resourceBundle) {
82 rb = resourceBundle;
83 }
84
85
86
87
88 public final V getAnnotation() {
89 return annotation;
90 }
91
92
93
94
95
96
97
98
99 public final String getMessage(final String key, final String defaultValue) {
100 try {
101 return rb.getString(key);
102 } catch (MissingResourceException e) {
103 return defaultValue;
104 }
105 }
106
107
108
109
110 public final void printDocumentation() {
111 printDocumentation(System.out, lexPar, annotation);
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public final void printDocumentation(final PrintStream pw) {
128 printDocumentation(pw, lexPar, annotation);
129 pw.flush();
130 }
131
132
133
134
135
136
137
138
139
140 protected abstract void printDocumentation(PrintStream pw, LexerParser<T> parser, V formatterAnnotation);
141
142
143
144
145
146
147
148
149
150
151
152
153 protected final String getOptionsInterfaceValue(final String key, final String defaultValue) throws StringParsingError {
154 String result = getOptionsInterfaceValue(key);
155 if (result == null) {
156 return defaultValue;
157 }
158 return result;
159 }
160
161
162
163
164
165
166
167
168
169
170 protected final String getOptionsInterfaceValue(final String key) throws StringParsingError {
171 String rbKey;
172 if (key.equals("")) {
173 rbKey = lexPar.getOptionsInterface().getName();
174 } else {
175 rbKey = lexPar.getOptionsInterface().getName() + "." + key;
176 }
177
178 if (rb.containsKey(rbKey)) {
179 return rb.getString(rbKey);
180 } else {
181 return null;
182 }
183 }
184
185
186
187
188
189
190
191
192 protected final String getStatusCodeUserDescription(final Enum<?> statusCode) throws StringParsingError {
193
194 ExitStatusConstant exitStatusDocumentation = DefaultAnnotation.getAnnotation(statusCode, ExitStatusConstant.class);
195 DefaultAnnotation.fillWithResourceBundle(exitStatusDocumentation, rb);
196
197 if(exitStatusDocumentation.userDescription()==null || exitStatusDocumentation.userDescription().equals("")) {
198 return statusCode.toString();
199 } else {
200 return exitStatusDocumentation.userDescription();
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215 @SuppressWarnings("unchecked")
216 public static DocumentationFormatterEngine preferredFormatter(final Class<? extends Options<?>> optionsInterface) {
217
218
219
220
221
222
223
224
225
226
227
228 ArgumentsObject ao = DefaultAnnotation.getAnnotation(optionsInterface, ArgumentsObject.class);
229 Class<? extends Annotation> formatterAnnotationClass = (Class<? extends Annotation>) ao.preferredDocumentationFormatter();
230 return buildFormatter(optionsInterface, formatterAnnotationClass);
231 }
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248 @SuppressWarnings("unchecked")
249 public static <A extends Options<?>, B extends Annotation> DocumentationFormatterEngine<A, B> buildFormatter(final Class<A> optionsInterface, final Class<B> formatterAnnotationClass) {
250
251 Class<? extends DocumentationFormatterEngine<A, B>> formatterClass = (Class<? extends DocumentationFormatterEngine<A, B>>) formatterAnnotationClass.getEnclosingClass();
252
253 try {
254
255 B annotationObj = DefaultAnnotation.getAnnotation(optionsInterface, formatterAnnotationClass);
256 ResourceBundle rb = new I18NResourceBundle(optionsInterface);
257
258 for (Method m : formatterAnnotationClass.getMethods()) {
259 if (m.getDeclaringClass().equals(formatterAnnotationClass)) {
260
261 if (rb.containsKey(formatterAnnotationClass.getName() + "." + m.getName())) {
262 try {
263 DefaultAnnotation.set(annotationObj, m, StringObjectConversion.fromString(m.getReturnType(), rb.getString(formatterAnnotationClass.getName() + "." + m.getName())));
264 } catch (StringParsingError e) {
265
266 e.printStackTrace();
267 }
268 } else {
269 if (m.invoke(annotationObj) != null) {
270 DefaultAnnotation.set(annotationObj, m, m.invoke(annotationObj));
271 }
272 }
273 } else {
274 if (m.getDefaultValue() != null) {
275 DefaultAnnotation.set(annotationObj, m, m.getDefaultValue());
276 }
277 }
278 }
279
280 Constructor<DocumentationFormatterEngine<A, B>> constructor = (Constructor<DocumentationFormatterEngine<A, B>>) formatterClass.getConstructor();
281 DocumentationFormatterEngine<A, B> engine = constructor.newInstance();
282 engine.setLexerParser(new LexerParser(optionsInterface));
283 engine.setAnnotation(annotationObj);
284 engine.setResourceBundle(rb);
285 return engine;
286
287 } catch (SecurityException e) {
288
289 e.printStackTrace();
290 } catch (NoSuchMethodException e) {
291
292 e.printStackTrace();
293 } catch (IllegalArgumentException e) {
294
295 e.printStackTrace();
296 } catch (InstantiationException e) {
297
298 e.printStackTrace();
299 } catch (IllegalAccessException e) {
300
301 e.printStackTrace();
302 } catch (InvocationTargetException e) {
303
304 e.printStackTrace();
305 } catch (InvalidOptionsInterfaceException e) {
306
307 e.printStackTrace();
308 }
309 return null;
310 }
311 }