1 package org.apache.maven.plugin.descriptor;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import org.apache.maven.plugin.Mojo;
23 import org.codehaus.plexus.component.repository.ComponentDescriptor;
24 import org.codehaus.plexus.configuration.PlexusConfiguration;
25 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
26
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.Map;
32
33 /**
34 * The bean containing the Mojo descriptor.
35 * <br/>
36 * For more information about the usage tag, have a look to:
37 * <a href="http://maven.apache.org/developers/mojo-api-specification.html">http://maven.apache.org/developers/mojo-api-specification.html</a>
38 *
39 * @todo is there a need for the delegation of MavenMojoDescriptor to this?
40 * Why not just extend ComponentDescriptor here?
41 * @version $Id: MojoDescriptor.java 743587 2009-02-12 01:32:50Z jdcasey $
42 */
43 public class MojoDescriptor
44 extends ComponentDescriptor
45 implements Cloneable
46 {
47 /** The Plexus component type */
48 public static String MAVEN_PLUGIN = "maven-plugin";
49
50 /** "once-per-session" execution strategy */
51 public static final String SINGLE_PASS_EXEC_STRATEGY = "once-per-session";
52
53 /** "always" execution strategy */
54 public static final String MULTI_PASS_EXEC_STRATEGY = "always";
55
56 private static final String DEFAULT_INSTANTIATION_STRATEGY = "per-lookup";
57
58 private static final String DEFAULT_LANGUAGE = "java";
59
60 private List parameters;
61
62 private Map parameterMap;
63
64 /** By default, the execution strategy is "once-per-session" */
65 private String executionStrategy = SINGLE_PASS_EXEC_STRATEGY;
66
67 /** The goal name of the Mojo */
68 private String goal;
69
70 /** Reference the binded phase name of the Mojo */
71 private String phase;
72
73 /** Specify the version when the Mojo was added to the API. Similar to Javadoc since. */
74 private String since;
75
76 /** Reference the invocation phase of the Mojo */
77 private String executePhase;
78
79 /** Reference the invocation goal of the Mojo */
80 private String executeGoal;
81
82 /** Reference the invocation lifecycle of the Mojo */
83 private String executeLifecycle;
84
85 /** Specify the version when the Mojo was deprecated to the API. Similar to Javadoc deprecated. */
86 private String deprecated;
87
88 /** By default, no need to aggregate the Maven project and its child modules */
89 private boolean aggregator = false;
90
91 // ----------------------------------------------------------------------
92 //
93 // ----------------------------------------------------------------------
94
95 /** Specify the required dependencies in a specified scope */
96 private String dependencyResolutionRequired = null;
97
98 /** By default, the Mojo needs a Maven project to be executed */
99 private boolean projectRequired = true;
100
101 /** By default, the Mojo is online */
102 private boolean onlineRequired = false;
103
104 /** Plugin configuration */
105 private PlexusConfiguration mojoConfiguration;
106
107 /** Plugin descriptor */
108 private PluginDescriptor pluginDescriptor;
109
110 /** By default, the Mojo is herited */
111 private boolean inheritedByDefault = true;
112
113 /** By default, the Mojo could not be invoke directly */
114 private boolean directInvocationOnly = false;
115
116 /** By default, the Mojo don't need reports to run */
117 private boolean requiresReports = false;
118
119 /**
120 * Default constructor.
121 */
122 public MojoDescriptor()
123 {
124 setInstantiationStrategy( DEFAULT_INSTANTIATION_STRATEGY );
125 setComponentFactory( DEFAULT_LANGUAGE );
126 }
127
128 // ----------------------------------------------------------------------
129 //
130 // ----------------------------------------------------------------------
131
132 /**
133 * @return the language of this Mojo, i.e. <code>java</code>
134 */
135 public String getLanguage()
136 {
137 return getComponentFactory();
138 }
139
140 /**
141 * @param language the new language
142 */
143 public void setLanguage( String language )
144 {
145 setComponentFactory( language );
146 }
147
148 /**
149 * @return <code>true</code> if the Mojo is deprecated, <code>false</code> otherwise.
150 */
151 public String getDeprecated()
152 {
153 return deprecated;
154 }
155
156 /**
157 * @param deprecated <code>true</code> to deprecate the Mojo, <code>false</code> otherwise.
158 */
159 public void setDeprecated( String deprecated )
160 {
161 this.deprecated = deprecated;
162 }
163
164 /**
165 * @return the list of parameters
166 */
167 public List getParameters()
168 {
169 return parameters;
170 }
171
172 /**
173 * @param parameters the new list of parameters
174 * @throws DuplicateParameterException if any
175 */
176 public void setParameters( List parameters )
177 throws DuplicateParameterException
178 {
179 for ( Iterator it = parameters.iterator(); it.hasNext(); )
180 {
181 Parameter parameter = (Parameter) it.next();
182 addParameter( parameter );
183 }
184 }
185
186 /**
187 * @param parameter add a new parameter
188 * @throws DuplicateParameterException if any
189 */
190 public void addParameter( Parameter parameter )
191 throws DuplicateParameterException
192 {
193 if ( parameters != null && parameters.contains( parameter ) )
194 {
195 throw new DuplicateParameterException( parameter.getName() +
196 " has been declared multiple times in mojo with goal: " + getGoal() + " (implementation: " +
197 getImplementation() + ")" );
198 }
199
200 if ( parameters == null )
201 {
202 parameters = new LinkedList();
203 }
204
205 parameters.add( parameter );
206
207 parameterMap = null;
208 }
209
210 /**
211 * @return the list parameters as a Map
212 */
213 public Map getParameterMap()
214 {
215 if ( parameterMap == null )
216 {
217 parameterMap = new HashMap();
218
219 if ( parameters != null )
220 {
221 for ( Iterator iterator = parameters.iterator(); iterator.hasNext(); )
222 {
223 Parameter pd = (Parameter) iterator.next();
224
225 parameterMap.put( pd.getName(), pd );
226 }
227 }
228 }
229
230 return parameterMap;
231 }
232
233 // ----------------------------------------------------------------------
234 // Dependency requirement
235 // ----------------------------------------------------------------------
236
237 /**
238 * @param requiresDependencyResolution the new required dependencies in a specified scope
239 */
240 public void setDependencyResolutionRequired( String requiresDependencyResolution )
241 {
242 this.dependencyResolutionRequired = requiresDependencyResolution;
243 }
244
245 /**
246 * @return the required dependencies in a specified scope
247 * @TODO the name is not intelligible
248 */
249 public String isDependencyResolutionRequired()
250 {
251 return dependencyResolutionRequired;
252 }
253
254 // ----------------------------------------------------------------------
255 // Project requirement
256 // ----------------------------------------------------------------------
257
258 /**
259 * @param requiresProject <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code> otherwise.
260 */
261 public void setProjectRequired( boolean requiresProject )
262 {
263 this.projectRequired = requiresProject;
264 }
265
266 /**
267 * @return <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code> otherwise.
268 */
269 public boolean isProjectRequired()
270 {
271 return projectRequired;
272 }
273
274 // ----------------------------------------------------------------------
275 // Online vs. Offline requirement
276 // ----------------------------------------------------------------------
277
278 /**
279 * @param requiresOnline <code>true</code> if the Mojo is online, <code>false</code> otherwise.
280 */
281 public void setOnlineRequired( boolean requiresOnline )
282 {
283 this.onlineRequired = requiresOnline;
284 }
285
286 /**
287 * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
288 */
289 // blech! this isn't even intelligible as a method name. provided for
290 // consistency...
291 public boolean isOnlineRequired()
292 {
293 return onlineRequired;
294 }
295
296 /**
297 * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
298 */
299 // more english-friendly method...keep the code clean! :)
300 public boolean requiresOnline()
301 {
302 return onlineRequired;
303 }
304
305 /**
306 * @return the binded phase name of the Mojo
307 */
308 public String getPhase()
309 {
310 return phase;
311 }
312
313 /**
314 * @param phase the new binded phase name of the Mojo
315 */
316 public void setPhase( String phase )
317 {
318 this.phase = phase;
319 }
320
321 /**
322 * @return the version when the Mojo was added to the API
323 */
324 public String getSince()
325 {
326 return since;
327 }
328
329 /**
330 * @param since the new version when the Mojo was added to the API
331 */
332 public void setSince( String since )
333 {
334 this.since = since;
335 }
336
337 /**
338 * @return The goal name of the Mojo
339 */
340 public String getGoal()
341 {
342 return goal;
343 }
344
345 /**
346 * @param goal The new goal name of the Mojo
347 */
348 public void setGoal( String goal )
349 {
350 this.goal = goal;
351 }
352
353 /**
354 * @return the invocation phase of the Mojo
355 */
356 public String getExecutePhase()
357 {
358 return executePhase;
359 }
360
361 /**
362 * @param executePhase the new invocation phase of the Mojo
363 */
364 public void setExecutePhase( String executePhase )
365 {
366 this.executePhase = executePhase;
367 }
368
369 /**
370 * @return <code>true</code> if the Mojo uses <code>always</code> for the <code>executionStrategy</code>
371 */
372 public boolean alwaysExecute()
373 {
374 return MULTI_PASS_EXEC_STRATEGY.equals( executionStrategy );
375 }
376
377 /**
378 * @return the execution strategy
379 */
380 public String getExecutionStrategy()
381 {
382 return executionStrategy;
383 }
384
385 /**
386 * @param executionStrategy the new execution strategy
387 */
388 public void setExecutionStrategy( String executionStrategy )
389 {
390 this.executionStrategy = executionStrategy;
391 }
392
393 /**
394 * @return the mojo configuration
395 */
396 public PlexusConfiguration getMojoConfiguration()
397 {
398 if ( mojoConfiguration == null )
399 {
400 mojoConfiguration = new XmlPlexusConfiguration( "configuration" );
401 }
402 return mojoConfiguration;
403 }
404
405 /**
406 * @param mojoConfiguration a new mojo configuration
407 */
408 public void setMojoConfiguration( PlexusConfiguration mojoConfiguration )
409 {
410 this.mojoConfiguration = mojoConfiguration;
411 }
412
413 /** {@inheritDoc} */
414 public String getRole()
415 {
416 return Mojo.ROLE;
417 }
418
419 /** {@inheritDoc} */
420 public String getRoleHint()
421 {
422 return getId();
423 }
424
425 /**
426 * @return the id of the mojo, based on the goal name
427 */
428 public String getId()
429 {
430 return getPluginDescriptor().getId() + ":" + getGoal();
431 }
432
433 /**
434 * @return the full goal name
435 * @see PluginDescriptor#getGoalPrefix()
436 * @see #getGoal()
437 */
438 public String getFullGoalName()
439 {
440 return getPluginDescriptor().getGoalPrefix() + ":" + getGoal();
441 }
442
443 /** {@inheritDoc} */
444 public String getComponentType()
445 {
446 return MAVEN_PLUGIN;
447 }
448
449 /**
450 * @return the plugin descriptor
451 */
452 public PluginDescriptor getPluginDescriptor()
453 {
454 return pluginDescriptor;
455 }
456
457 /**
458 * @param pluginDescriptor the new plugin descriptor
459 */
460 public void setPluginDescriptor( PluginDescriptor pluginDescriptor )
461 {
462 this.pluginDescriptor = pluginDescriptor;
463 }
464
465 /**
466 * @return <code>true</code> if the Mojo is herited, <code>false</code> otherwise.
467 */
468 public boolean isInheritedByDefault()
469 {
470 return inheritedByDefault;
471 }
472
473 /**
474 * @param inheritedByDefault <code>true</code> if the Mojo is herited, <code>false</code> otherwise.
475 */
476 public void setInheritedByDefault( boolean inheritedByDefault )
477 {
478 this.inheritedByDefault = inheritedByDefault;
479 }
480
481 /** {@inheritDoc} */
482 public boolean equals( Object object )
483 {
484 if ( this == object )
485 {
486 return true;
487 }
488
489 if ( object instanceof MojoDescriptor )
490 {
491 MojoDescriptor other = (MojoDescriptor) object;
492
493 if ( !compareObjects( getPluginDescriptor(), other.getPluginDescriptor() ) )
494 {
495 return false;
496 }
497
498 if ( !compareObjects( getGoal(), other.getGoal() ) )
499 {
500 return false;
501 }
502
503 return true;
504 }
505
506 return false;
507 }
508
509 private boolean compareObjects( Object first, Object second )
510 {
511 if ( ( first == null && second != null ) || ( first != null && second == null ) )
512 {
513 return false;
514 }
515
516 if ( !first.equals( second ) )
517 {
518 return false;
519 }
520
521 return true;
522 }
523
524 /** {@inheritDoc} */
525 public int hashCode()
526 {
527 int result = 1;
528
529 String goal = getGoal();
530
531 if ( goal != null )
532 {
533 result += goal.hashCode();
534 }
535
536 PluginDescriptor pd = getPluginDescriptor();
537
538 if ( pd != null )
539 {
540 result -= pd.hashCode();
541 }
542
543 return result;
544 }
545
546 /**
547 * @return the invocation lifecycle of the Mojo
548 */
549 public String getExecuteLifecycle()
550 {
551 return executeLifecycle;
552 }
553
554 /**
555 * @param executeLifecycle the new invocation lifecycle of the Mojo
556 */
557 public void setExecuteLifecycle( String executeLifecycle )
558 {
559 this.executeLifecycle = executeLifecycle;
560 }
561
562 /**
563 * @param aggregator <code>true</code> if the Mojo uses the Maven project and its child modules, <code>false</code> otherwise.
564 */
565 public void setAggregator( boolean aggregator )
566 {
567 this.aggregator = aggregator;
568 }
569
570 /**
571 * @return <code>true</code> if the Mojo uses the Maven project and its child modules, <code>false</code> otherwise.
572 */
573 public boolean isAggregator()
574 {
575 return aggregator;
576 }
577
578 /**
579 * @return <code>true</code> if the Mojo could not be invoke directly, <code>false</code> otherwise.
580 */
581 public boolean isDirectInvocationOnly()
582 {
583 return directInvocationOnly;
584 }
585
586 /**
587 * @param directInvocationOnly <code>true</code> if the Mojo could not be invoke directly, <code>false</code> otherwise.
588 */
589 public void setDirectInvocationOnly( boolean directInvocationOnly )
590 {
591 this.directInvocationOnly = directInvocationOnly;
592 }
593
594 /**
595 * @return <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
596 */
597 public boolean isRequiresReports()
598 {
599 return requiresReports;
600 }
601
602 /**
603 * @param requiresReports <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
604 */
605 public void setRequiresReports( boolean requiresReports )
606 {
607 this.requiresReports = requiresReports;
608 }
609
610 /**
611 * @param executeGoal the new invocation goal of the Mojo
612 */
613 public void setExecuteGoal( String executeGoal )
614 {
615 this.executeGoal = executeGoal;
616 }
617
618 /**
619 * @return the invocation goal of the Mojo
620 */
621 public String getExecuteGoal()
622 {
623 return executeGoal;
624 }
625 }