1 package org.apache.maven.tools.plugin.generator;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.plugin.descriptor.MojoDescriptor;
23 import org.apache.maven.plugin.descriptor.Parameter;
24 import org.apache.maven.plugin.descriptor.PluginDescriptor;
25 import org.codehaus.plexus.util.IOUtil;
26 import org.codehaus.plexus.util.StringUtils;
27 import org.codehaus.plexus.util.xml.XMLWriter;
28
29 import java.io.File;
30 import java.io.FileWriter;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.Iterator;
34 import java.util.List;
35
36 /**
37 * @todo add example usage tag that can be shown in the doco
38 */
39 public class PluginXdocGenerator
40 implements Generator
41 {
42
43 public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor )
44 throws IOException
45 {
46 for ( Iterator it = pluginDescriptor.getMojos().iterator(); it.hasNext(); )
47 {
48 MojoDescriptor descriptor = (MojoDescriptor) it.next();
49 processMojoDescriptor( descriptor, destinationDirectory );
50 }
51 }
52
53 protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, File destinationDirectory )
54 throws IOException
55 {
56 FileWriter writer = null;
57 try
58 {
59 writer = new FileWriter( new File( destinationDirectory, getMojoFilename( mojoDescriptor, "xml" ) ) );
60
61 writeBody( writer, mojoDescriptor );
62
63 writer.flush();
64 }
65 finally
66 {
67 IOUtil.close( writer );
68 }
69 }
70
71 private String getMojoFilename( MojoDescriptor mojo, String ext )
72 {
73 return mojo.getGoal() + "-mojo." + ext;
74 }
75
76 private void writeBody( FileWriter writer, MojoDescriptor mojoDescriptor )
77 {
78 XMLWriter w = new PrettyPrintXMLWriter( writer );
79
80 w.startElement( "document" );
81
82
83
84
85
86 w.startElement( "properties" );
87
88 w.startElement( "title" );
89
90
91 w.writeText( mojoDescriptor.getPluginDescriptor().getArtifactId() + " - " + mojoDescriptor.getFullGoalName() );
92
93 w.endElement();
94
95 w.endElement();
96
97
98
99
100
101 w.startElement( "body" );
102
103 w.startElement( "section" );
104
105 w.addAttribute( "name", mojoDescriptor.getFullGoalName() );
106
107 w.startElement( "p" );
108
109 if ( mojoDescriptor.getDescription() != null )
110 {
111 w.writeMarkup( mojoDescriptor.getDescription() );
112 }
113 else
114 {
115 w.writeText( "No description." );
116 }
117
118 w.endElement();
119
120 writeGoalAttributes( mojoDescriptor, w );
121
122 writeGoalParameterTable( mojoDescriptor, w );
123
124 w.endElement();
125
126 w.endElement();
127
128 w.endElement();
129 }
130
131 private void writeGoalAttributes( MojoDescriptor mojoDescriptor, XMLWriter w )
132 {
133 w.startElement( "p" );
134 w.writeMarkup( "<b>Mojo Attributes</b>:" );
135 w.startElement( "ul" );
136
137 String value = mojoDescriptor.getDeprecated();
138 if ( StringUtils.isNotEmpty( value ) )
139 {
140 w.startElement( "li" );
141 w.writeMarkup( "This plugin goal has been deprecated: " + value + "" );
142 w.endElement();
143 }
144
145 if ( mojoDescriptor.isProjectRequired() )
146 {
147 w.startElement( "li" );
148 w.writeMarkup( "Requires a Maven 2.0 project to execute." );
149 w.endElement();
150 }
151
152 if ( mojoDescriptor.isAggregator() )
153 {
154 w.startElement( "li" );
155 w.writeMarkup( "Executes as an aggregator plugin." );
156 w.endElement();
157 }
158
159 if ( mojoDescriptor.isDirectInvocationOnly() )
160 {
161 w.startElement( "li" );
162 w.writeMarkup( "Executes by direct invocation only." );
163 w.endElement();
164 }
165
166 value = mojoDescriptor.isDependencyResolutionRequired();
167 if ( StringUtils.isNotEmpty( value ) )
168 {
169 w.startElement( "li" );
170 w.writeMarkup( "Requires dependency resolution of artifacts in scope: <code>" + value + "</code>" );
171 w.endElement();
172 }
173
174 value = mojoDescriptor.getPhase();
175 if ( StringUtils.isNotEmpty( value ) )
176 {
177 w.startElement( "li" );
178 w.writeMarkup( "Automatically executes within the lifecycle phase: <code>" + value + "</code>" );
179 w.endElement();
180 }
181
182 value = mojoDescriptor.getExecutePhase();
183 if ( StringUtils.isNotEmpty( value ) )
184 {
185 w.startElement( "li" );
186 w.writeMarkup(
187 "Invokes the execution of the lifecycle phase <code>" + value + "</code> prior to executing itself." );
188 w.endElement();
189 }
190
191 value = mojoDescriptor.getExecuteGoal();
192 if ( StringUtils.isNotEmpty( value ) )
193 {
194 w.startElement( "li" );
195 w.writeMarkup(
196 "Invokes the execution of this plugin's goal <code>" + value + "</code> prior to executing itself." );
197 w.endElement();
198 }
199
200 value = mojoDescriptor.getExecuteLifecycle();
201 if ( StringUtils.isNotEmpty( value ) )
202 {
203 w.startElement( "li" );
204 w.writeMarkup( "Executes in its own lifecycle: <code>" + value + "</code>" );
205 w.endElement();
206 }
207
208 if ( mojoDescriptor.isOnlineRequired() )
209 {
210 w.startElement( "li" );
211 w.writeMarkup( "Requires that mvn runs in online mode." );
212 w.endElement();
213 }
214
215 if ( !mojoDescriptor.isInheritedByDefault() )
216 {
217 w.startElement( "li" );
218 w.writeMarkup( "Is NOT inherited by default in multi-project builds." );
219 w.endElement();
220 }
221
222 w.endElement();
223 w.endElement();
224 }
225
226 private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w )
227 {
228 List parameterList = mojoDescriptor.getParameters();
229
230
231 List list = filterParameters( parameterList );
232
233 if ( list != null && list.size() > 0 )
234 {
235 writeParameterSummary( list, w );
236
237 writeParameterDetails( list, w );
238 }
239 }
240
241 private List filterParameters( List parameterList )
242 {
243 List filtered = new ArrayList();
244
245 for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); )
246 {
247 Parameter parameter = (Parameter) parameters.next();
248
249 if ( parameter.isEditable() )
250 {
251 String expression = parameter.getExpression();
252
253 if ( expression == null || !expression.startsWith( "${component." ) )
254 {
255 filtered.add( parameter );
256 }
257 }
258 }
259
260 return filtered;
261 }
262
263 private void writeParameterDetails( List parameterList, XMLWriter w )
264 {
265 w.startElement( "subsection" );
266 w.addAttribute( "name", "Parameter Details" );
267
268 for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); )
269 {
270 Parameter parameter = (Parameter) parameters.next();
271
272 w.startElement( "p" );
273 w.writeMarkup( "<b><a name=\"" + parameter.getName() + "\">" + parameter.getName() + "</a></b>" );
274 w.endElement();
275
276 String description = parameter.getDescription();
277 if ( StringUtils.isEmpty( description ) )
278 {
279 description = "No Description.";
280 }
281 w.startElement( "p" );
282 w.writeMarkup( description );
283 w.endElement();
284
285 w.startElement( "ul" );
286
287 writeDetail( "Type", parameter.getType(), w );
288
289 if ( parameter.isRequired() )
290 {
291 writeDetail( "Required", "Yes", w );
292 }
293 else
294 {
295 writeDetail( "Required", "No", w );
296 }
297
298 writeDetail( "Expression", parameter.getExpression(), w );
299
300 writeDetail( "Default", parameter.getDefaultValue(), w );
301
302 w.endElement();
303
304 if ( parameters.hasNext() )
305 {
306 w.writeMarkup( "<hr/>" );
307 }
308 }
309
310 w.endElement();
311 }
312
313 private void writeDetail( String param, String value, XMLWriter w )
314 {
315 if ( StringUtils.isNotEmpty( value ) )
316 {
317 w.startElement( "li" );
318 w.writeMarkup( "<b>" + param + "</b>: <code>" );
319 w.writeText( value );
320 w.writeMarkup( "</code>" );
321 w.endElement();
322 }
323 }
324
325 private void writeParameterSummary( List parameterList, XMLWriter w )
326 {
327 List requiredParams = getParametersByRequired( true, parameterList );
328 if ( requiredParams.size() > 0 )
329 {
330 writeParameterList( "Required Parameters", requiredParams, w );
331 }
332
333 List optionalParams = getParametersByRequired( false, parameterList );
334 if ( optionalParams.size() > 0 )
335 {
336 writeParameterList( "Optional Parameters", optionalParams, w );
337 }
338 }
339
340 private void writeParameterList( String title, List parameterList, XMLWriter w )
341 {
342 w.startElement( "subsection" );
343 w.addAttribute( "name", title );
344
345 w.startElement( "table" );
346
347 w.startElement( "tr" );
348 w.startElement( "th" );
349 w.writeText( "Name" );
350 w.endElement();
351 w.startElement( "th" );
352 w.writeText( "Type" );
353 w.endElement();
354 w.startElement( "th" );
355 w.writeText( "Description" );
356 w.endElement();
357 w.endElement();
358
359 for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); )
360 {
361 Parameter parameter = (Parameter) parameters.next();
362
363 w.startElement( "tr" );
364 w.startElement( "td" );
365 w.writeMarkup( "<b><a href=\"#" + parameter.getName() + "\">" + parameter.getName() + "</a></b>" );
366 w.endElement();
367 w.startElement( "td" );
368 int index = parameter.getType().lastIndexOf( "." );
369 w.writeMarkup( "<code>" + parameter.getType().substring( index + 1 ) + "</code>" );
370 w.endElement();
371 w.startElement( "td" );
372 String description = parameter.getDescription();
373 if ( StringUtils.isEmpty( description ) )
374 {
375 description = "No description.";
376 }
377 w.writeMarkup( description );
378
379 if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) )
380 {
381 w.writeMarkup( " Default value is <code>" );
382 w.writeText( parameter.getDefaultValue() );
383 w.writeMarkup( "</code>." );
384 }
385 w.endElement();
386 w.endElement();
387 }
388
389 w.endElement();
390 w.endElement();
391 }
392
393 private List getParametersByRequired( boolean required, List parameterList )
394 {
395 List list = new ArrayList();
396
397 for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); )
398 {
399 Parameter parameter = (Parameter) parameters.next();
400
401 if ( parameter.isRequired() == required )
402 {
403 list.add( parameter );
404 }
405 }
406
407 return list;
408 }
409 }
410