1 | |
package org.apache.maven.tools.plugin.javadoc; |
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
import java.util.ArrayList; |
23 | |
import java.util.Arrays; |
24 | |
import java.util.Collections; |
25 | |
import java.util.Enumeration; |
26 | |
import java.util.List; |
27 | |
import java.util.StringTokenizer; |
28 | |
|
29 | |
import javax.swing.text.AttributeSet; |
30 | |
import javax.swing.text.MutableAttributeSet; |
31 | |
import javax.swing.text.SimpleAttributeSet; |
32 | |
|
33 | |
import com.sun.javadoc.Tag; |
34 | |
import com.sun.tools.doclets.Taglet; |
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | 0 | public abstract class AbstractMojoTaglet |
50 | |
implements Taglet |
51 | |
{ |
52 | |
|
53 | |
public String toString( Tag tag ) |
54 | |
{ |
55 | 0 | if ( tag == null ) |
56 | |
{ |
57 | 0 | return null; |
58 | |
} |
59 | |
|
60 | 0 | String tagValue = getTagValue( tag ); |
61 | 0 | MutableAttributeSet tagAttributes = getTagAttributes( tag ); |
62 | |
|
63 | 0 | StringBuilder sb = new StringBuilder(); |
64 | |
|
65 | 0 | appendTag( sb, tag, tagAttributes, tagValue ); |
66 | |
|
67 | 0 | return sb.toString(); |
68 | |
} |
69 | |
|
70 | |
|
71 | |
public String toString( Tag[] tags ) |
72 | |
{ |
73 | 0 | if ( tags.length == 0 ) |
74 | |
{ |
75 | 0 | return null; |
76 | |
} |
77 | |
|
78 | 0 | StringBuilder sb = new StringBuilder(); |
79 | 0 | for ( int i = 0; i < tags.length; i++ ) |
80 | |
{ |
81 | 0 | String tagValue = getTagValue( tags[i] ); |
82 | 0 | MutableAttributeSet tagAttributes = getTagAttributes( tags[i] ); |
83 | |
|
84 | 0 | appendTag( sb, tags[i], tagAttributes, tagValue ); |
85 | |
} |
86 | |
|
87 | 0 | return sb.toString(); |
88 | |
} |
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | |
public abstract String getHeader(); |
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
|
102 | |
public abstract String getAllowedValue(); |
103 | |
|
104 | |
|
105 | |
|
106 | |
|
107 | |
|
108 | |
public abstract String[] getAllowedParameterNames(); |
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
public boolean hasAnnotationValue() |
115 | |
{ |
116 | 0 | return getAllowedValue() != null; |
117 | |
} |
118 | |
|
119 | |
|
120 | |
|
121 | |
|
122 | |
|
123 | |
public boolean hasAnnotationParameters() |
124 | |
{ |
125 | 0 | return getAllowedParameterNames() != null; |
126 | |
} |
127 | |
|
128 | |
|
129 | |
|
130 | |
|
131 | |
|
132 | |
private String getTagValue( Tag tag ) |
133 | |
{ |
134 | 0 | if ( tag == null ) |
135 | |
{ |
136 | 0 | throw new IllegalArgumentException( "tag should be not null" ); |
137 | |
} |
138 | |
|
139 | 0 | String text = tag.text(); |
140 | 0 | if ( isEmpty( text ) ) |
141 | |
{ |
142 | |
|
143 | 0 | return null; |
144 | |
} |
145 | |
|
146 | 0 | String tagValue = null; |
147 | 0 | StringTokenizer token = new StringTokenizer( text, " " ); |
148 | 0 | while ( token.hasMoreTokens() ) |
149 | |
{ |
150 | 0 | String nextToken = token.nextToken(); |
151 | |
|
152 | 0 | if ( nextToken.indexOf( '=' ) == -1 ) |
153 | |
{ |
154 | |
|
155 | 0 | tagValue = nextToken; |
156 | |
} |
157 | 0 | } |
158 | |
|
159 | 0 | return tagValue; |
160 | |
} |
161 | |
|
162 | |
|
163 | |
|
164 | |
|
165 | |
|
166 | |
private MutableAttributeSet getTagAttributes( Tag tag ) |
167 | |
{ |
168 | 0 | if ( tag == null ) |
169 | |
{ |
170 | 0 | throw new IllegalArgumentException( "tag should be not null" ); |
171 | |
} |
172 | |
|
173 | 0 | String text = tag.text(); |
174 | |
|
175 | 0 | StringTokenizer token = new StringTokenizer( text, " " ); |
176 | 0 | MutableAttributeSet tagAttributes = new SimpleAttributeSet(); |
177 | 0 | while ( token.hasMoreTokens() ) |
178 | |
{ |
179 | 0 | String nextToken = token.nextToken(); |
180 | |
|
181 | 0 | if ( nextToken.indexOf( '=' ) == -1 ) |
182 | |
{ |
183 | |
|
184 | 0 | continue; |
185 | |
} |
186 | |
|
187 | 0 | StringTokenizer token2 = new StringTokenizer( nextToken, "=" ); |
188 | 0 | if ( token2.countTokens() != 2 ) |
189 | |
{ |
190 | 0 | System.err.println( "The annotation '" + tag.name() + "' has no name/value pairs parameter: " |
191 | |
+ tag.name() + " " + text + " (" + tag.position().file() + ":" + tag.position().line() + ":" |
192 | |
+ tag.position().column() + ")" ); |
193 | 0 | tagAttributes.addAttribute( token2.nextToken(), "" ); |
194 | 0 | continue; |
195 | |
} |
196 | |
|
197 | 0 | String name = token2.nextToken(); |
198 | 0 | String value = token2.nextToken().replaceAll( "\"", "" ); |
199 | |
|
200 | 0 | if ( getAllowedParameterNames() != null && !Arrays.asList( getAllowedParameterNames() ).contains( name ) ) |
201 | |
{ |
202 | 0 | System.err.println( "The annotation '" + tag.name() + "' has wrong parameter name: " + tag.name() + " " |
203 | |
+ text + " (" + tag.position().file() + ":" + tag.position().line() + ":" + tag.position().column() |
204 | |
+ ")" ); |
205 | |
} |
206 | |
|
207 | 0 | tagAttributes.addAttribute( name, value ); |
208 | 0 | } |
209 | |
|
210 | 0 | return tagAttributes; |
211 | |
} |
212 | |
|
213 | |
|
214 | |
|
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
|
220 | |
|
221 | |
private void appendTag( StringBuilder sb, Tag tag, MutableAttributeSet tagAttributes, String tagValue ) |
222 | |
{ |
223 | 0 | if ( !hasAnnotationParameters() ) |
224 | |
{ |
225 | 0 | if ( tagAttributes.getAttributeCount() > 0 ) |
226 | |
{ |
227 | 0 | System.err.println( "The annotation '@" + getName() + "' should have no attribute (" |
228 | |
+ tag.position().file() + ":" + tag.position().line() + ":" + tag.position().column() + ")" ); |
229 | |
} |
230 | |
|
231 | 0 | if ( hasAnnotationValue() ) |
232 | |
{ |
233 | 0 | sb.append( "<DT><B>" ).append( getHeader() ).append( ":</B></DT>" ); |
234 | 0 | if ( isEveryValues( getAllowedValue() ) ) |
235 | |
{ |
236 | 0 | if ( isNotEmpty( tagValue ) ) |
237 | |
{ |
238 | 0 | sb.append( "<DD>" ).append( tagValue ).append( "</DD>" ); |
239 | |
} |
240 | |
else |
241 | |
{ |
242 | 0 | System.err.println( "The annotation '@" + getName() + "' is specified to have a value but " |
243 | |
+ "no value is defined (" + tag.position().file() + ":" + tag.position().line() + ":" |
244 | |
+ tag.position().column() + ")" ); |
245 | 0 | sb.append( "<DD>" ).append( "NOT DEFINED" ).append( "</DD>" ); |
246 | |
} |
247 | |
} |
248 | |
else |
249 | |
{ |
250 | 0 | List<String> l = getOnlyValues( getAllowedValue() ); |
251 | 0 | if ( isNotEmpty( tagValue ) ) |
252 | |
{ |
253 | 0 | if ( l.contains( tagValue ) ) |
254 | |
{ |
255 | 0 | sb.append( "<DD>" ).append( tagValue ).append( "</DD>" ); |
256 | |
} |
257 | |
else |
258 | |
{ |
259 | 0 | System.err.println( "The annotation '@" + getName() + "' is specified to be a value of " |
260 | |
+ l + " (" + tag.position().file() + ":" + tag.position().line() + ":" |
261 | |
+ tag.position().column() + ")" ); |
262 | 0 | sb.append( "<DD>" ).append( tagValue ).append( "</DD>" ); |
263 | |
} |
264 | |
} |
265 | |
else |
266 | |
{ |
267 | 0 | sb.append( "<DD>" ).append( l.get( 0 ) ).append( "</DD>" ); |
268 | |
} |
269 | 0 | } |
270 | |
} |
271 | |
else |
272 | |
{ |
273 | 0 | if ( isNotEmpty( tagValue ) ) |
274 | |
{ |
275 | 0 | System.err.println( "The annotation '@" + getName() + "' should have no value (" |
276 | |
+ tag.position().file() + ":" + tag.position().line() + ":" + tag.position().column() + ")" ); |
277 | |
} |
278 | 0 | sb.append( "<DT><B>" ).append( getHeader() ).append( "</B></DT>" ); |
279 | 0 | sb.append( "<DD></DD>" ); |
280 | |
} |
281 | |
} |
282 | |
else |
283 | |
{ |
284 | 0 | if ( hasAnnotationValue() ) |
285 | |
{ |
286 | 0 | sb.append( "<DT><B>" ).append( getHeader() ).append( ":</B></DT>" ); |
287 | 0 | if ( isEveryValues( getAllowedValue() ) ) |
288 | |
{ |
289 | 0 | if ( isNotEmpty( tagValue ) ) |
290 | |
{ |
291 | 0 | sb.append( "<DD>" ).append( tagValue ); |
292 | |
} |
293 | |
else |
294 | |
{ |
295 | 0 | System.err.println( "The annotation '@" + getName() + "' is specified to have a value but " |
296 | |
+ "no value is defined (" + tag.position().file() + ":" + tag.position().line() + ":" |
297 | |
+ tag.position().column() + ")" ); |
298 | 0 | sb.append( "<DD>" ).append( "NOT DEFINED" ); |
299 | |
} |
300 | |
} |
301 | |
else |
302 | |
{ |
303 | 0 | List<String> l = getOnlyValues( getAllowedValue() ); |
304 | 0 | if ( isNotEmpty( tagValue ) ) |
305 | |
{ |
306 | 0 | if ( l.contains( tagValue ) ) |
307 | |
{ |
308 | 0 | sb.append( "<DD>" ).append( tagValue ); |
309 | |
} |
310 | |
else |
311 | |
{ |
312 | 0 | System.err.println( "The annotation '@" + getName() + "' is specified to be a value in " |
313 | |
+ l + " (" + tag.position().file() + ":" + tag.position().line() + ":" |
314 | |
+ tag.position().column() + ")" ); |
315 | 0 | sb.append( "<DD>" ).append( tagValue ); |
316 | |
} |
317 | |
} |
318 | |
else |
319 | |
{ |
320 | 0 | sb.append( "<DD>" ).append( l.get( 0 ) ); |
321 | |
} |
322 | 0 | } |
323 | |
} |
324 | |
else |
325 | |
{ |
326 | 0 | if ( isNotEmpty( tagValue ) ) |
327 | |
{ |
328 | 0 | System.err.println( "The annotation '@" + getName() + "' should have no value (" |
329 | |
+ tag.position().file() + ":" + tag.position().line() + ":" + tag.position().column() + ")" ); |
330 | |
} |
331 | 0 | sb.append( "<DT><B>" ).append( getHeader() ).append( ":</B></DT>" ); |
332 | 0 | sb.append( "<DD>" ); |
333 | |
} |
334 | |
|
335 | 0 | appendAnnotationParameters( sb, tagAttributes ); |
336 | 0 | sb.append( "</DD>" ); |
337 | |
} |
338 | 0 | } |
339 | |
|
340 | |
|
341 | |
|
342 | |
|
343 | |
|
344 | |
|
345 | |
|
346 | |
private static void appendAnnotationParameters( StringBuilder sb, MutableAttributeSet att ) |
347 | |
{ |
348 | 0 | sb.append( "<DL>" ); |
349 | |
|
350 | 0 | Enumeration<?> names = att.getAttributeNames(); |
351 | 0 | while ( names.hasMoreElements() ) |
352 | |
{ |
353 | 0 | Object key = names.nextElement(); |
354 | 0 | Object value = att.getAttribute( key ); |
355 | |
|
356 | 0 | if ( value instanceof AttributeSet ) |
357 | |
{ |
358 | |
|
359 | |
} |
360 | |
else |
361 | |
{ |
362 | 0 | sb.append( "<DT><B>" ).append( key ).append( ":</B></DT>" ); |
363 | 0 | sb.append( "<DD>" ).append( value ).append( "</DD>" ); |
364 | |
} |
365 | 0 | } |
366 | |
|
367 | 0 | sb.append( "</DL>" ); |
368 | 0 | } |
369 | |
|
370 | |
|
371 | |
|
372 | |
|
373 | |
|
374 | |
private static boolean isEveryValues( String text ) |
375 | |
{ |
376 | 0 | return text.trim().equals( "*" ); |
377 | |
} |
378 | |
|
379 | |
|
380 | |
|
381 | |
|
382 | |
|
383 | |
|
384 | |
|
385 | |
|
386 | |
private static List<String> getOnlyValues( String text ) |
387 | |
{ |
388 | 0 | if ( text.indexOf( '|' ) == -1 ) |
389 | |
{ |
390 | 0 | return Collections.emptyList(); |
391 | |
} |
392 | |
|
393 | 0 | List<String> l = new ArrayList<String>(); |
394 | 0 | StringTokenizer token = new StringTokenizer( text, "|" ); |
395 | 0 | while ( token.hasMoreTokens() ) |
396 | |
{ |
397 | 0 | l.add( token.nextToken() ); |
398 | |
} |
399 | |
|
400 | 0 | return l; |
401 | |
} |
402 | |
|
403 | |
|
404 | |
|
405 | |
|
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
private static boolean isNotEmpty( String str ) |
411 | |
{ |
412 | 0 | return ( str != null && str.length() > 0 ); |
413 | |
} |
414 | |
|
415 | |
|
416 | |
|
417 | |
|
418 | |
|
419 | |
|
420 | |
|
421 | |
|
422 | |
private static boolean isEmpty( String str ) |
423 | |
{ |
424 | 0 | return ( str == null || str.trim().length() == 0 ); |
425 | |
} |
426 | |
} |