View Javadoc

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 java.util.HashMap;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.maven.plugin.Mojo;
28  import org.codehaus.plexus.component.repository.ComponentDescriptor;
29  import org.codehaus.plexus.configuration.PlexusConfiguration;
30  import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
31  
32  /**
33   * The bean containing the Mojo descriptor.
34   * <br/>
35   * For more information about the usage tag, have a look to:
36   * <a href="http://maven.apache.org/developers/mojo-api-specification.html">
37   * 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   */
42  public class MojoDescriptor
43      extends ComponentDescriptor<Mojo>
44      implements Cloneable
45  {
46      /** The Plexus component type */
47      public static final String MAVEN_PLUGIN = "maven-plugin";
48  
49      /** "once-per-session" execution strategy */
50      public static final String SINGLE_PASS_EXEC_STRATEGY = "once-per-session";
51  
52      /** "always" execution strategy */
53      public static final String MULTI_PASS_EXEC_STRATEGY = "always";
54  
55      private static final String DEFAULT_INSTANTIATION_STRATEGY = "per-lookup";
56  
57      private static final String DEFAULT_LANGUAGE = "java";
58  
59      private List<Parameter> parameters;
60  
61      private Map<String, Parameter> parameterMap;
62  
63      /** By default, the execution strategy is "once-per-session" */
64      private String executionStrategy = SINGLE_PASS_EXEC_STRATEGY;
65  
66      /** The goal name of the Mojo */
67      private String goal;
68  
69      /** Reference the binded phase name of the Mojo */
70      private String phase;
71  
72      /** Specify the version when the Mojo was added to the API. Similar to Javadoc since. */
73      private String since;
74  
75      /** Reference the invocation phase of the Mojo */
76      private String executePhase;
77  
78      /** Reference the invocation goal of the Mojo */
79      private String executeGoal;
80  
81      /** Reference the invocation lifecycle of the Mojo */
82      private String executeLifecycle;
83  
84      /** Specify the version when the Mojo was deprecated to the API. Similar to Javadoc deprecated. */
85      private String deprecated;
86  
87      /** By default, no need to aggregate the Maven project and its child modules */
88      private boolean aggregator = false;
89  
90      // ----------------------------------------------------------------------
91      //
92      // ----------------------------------------------------------------------
93  
94      /** Specify the required dependencies in a specified scope */
95      private String dependencyResolutionRequired = null;
96  
97      /** The scope of (transitive) dependencies that should be collected but not resolved. */
98      private String dependencyCollectionRequired;
99  
100     /**  By default, the Mojo needs a Maven project to be executed */
101     private boolean projectRequired = true;
102 
103     /**  By default, the Mojo is assumed to work offline as well */
104     private boolean onlineRequired = false;
105 
106     /**  Plugin configuration */
107     private PlexusConfiguration mojoConfiguration;
108 
109     /**  Plugin descriptor */
110     private PluginDescriptor pluginDescriptor;
111 
112     /**  By default, the Mojo is inherited */
113     private boolean inheritedByDefault = true;
114 
115     /**  By default, the Mojo could not be invoke directly */
116     private boolean directInvocationOnly = false;
117 
118     /**  By default, the Mojo don't need reports to run */
119     private boolean requiresReports = false;
120 
121     /** By default, mojos are not threadsafe */
122     private boolean threadSafe = false;
123 
124     /**
125      * Default constructor.
126      */
127     public MojoDescriptor()
128     {
129         setInstantiationStrategy( DEFAULT_INSTANTIATION_STRATEGY );
130         setComponentFactory( DEFAULT_LANGUAGE );
131     }
132 
133     // ----------------------------------------------------------------------
134     //
135     // ----------------------------------------------------------------------
136 
137     /**
138      * @return the language of this Mojo, i.e. <code>java</code>
139      */
140     public String getLanguage()
141     {
142         return getComponentFactory();
143     }
144 
145     /**
146      * @param language the new language
147      */
148     public void setLanguage( String language )
149     {
150         setComponentFactory( language );
151     }
152 
153     /**
154      * @return <code>true</code> if the Mojo is deprecated, <code>false</code> otherwise.
155      */
156     public String getDeprecated()
157     {
158         return deprecated;
159     }
160 
161     /**
162      * @param deprecated <code>true</code> to deprecate the Mojo, <code>false</code> otherwise.
163      */
164     public void setDeprecated( String deprecated )
165     {
166         this.deprecated = deprecated;
167     }
168 
169     /**
170      * @return the list of parameters
171      */
172     public List<Parameter> getParameters()
173     {
174         return parameters;
175     }
176 
177     /**
178      * @param parameters the new list of parameters
179      * @throws DuplicateParameterException if any
180      */
181     public void setParameters( List<Parameter> parameters )
182         throws DuplicateParameterException
183     {
184         for ( Parameter parameter : parameters )
185         {
186             addParameter( parameter );
187         }
188     }
189 
190     /**
191      * @param parameter add a new parameter
192      * @throws DuplicateParameterException if any
193      */
194     public void addParameter( Parameter parameter )
195         throws DuplicateParameterException
196     {
197         if ( parameters != null && parameters.contains( parameter ) )
198         {
199             throw new DuplicateParameterException( parameter.getName()
200                 + " has been declared multiple times in mojo with goal: " + getGoal() + " (implementation: "
201                 + getImplementation() + ")" );
202         }
203 
204         if ( parameters == null )
205         {
206             parameters = new LinkedList<Parameter>();
207         }
208 
209         parameters.add( parameter );
210     }
211 
212     /**
213      * @return the list parameters as a Map
214      */
215     public Map<String, Parameter> getParameterMap()
216     {
217         if ( parameterMap == null )
218         {
219             parameterMap = new HashMap<String, Parameter>();
220 
221             if ( parameters != null )
222             {
223                 for ( Parameter pd : parameters )
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     public String getDependencyResolutionRequired()
246     {
247         return dependencyResolutionRequired;
248     }
249 
250     /**
251      * @return the required dependencies in a specified scope
252      * @TODO the name is not intelligible
253      */
254     @Deprecated
255     public String isDependencyResolutionRequired()
256     {
257         return dependencyResolutionRequired;
258     }
259 
260     public void setDependencyCollectionRequired( String requiresDependencyCollection )
261     {
262         this.dependencyCollectionRequired = requiresDependencyCollection;
263     }
264 
265     /**
266      * Gets the scope of (transitive) dependencies that should be collected. Dependency collection refers to the process
267      * of calculating the complete dependency tree in terms of artifact coordinates. In contrast to dependency
268      * resolution, this does not include the download of the files for the dependency artifacts.
269      *
270      * @return The scope of (transitive) dependencies that should be collected or {@code null} if none.
271      */
272     public String getDependencyCollectionRequired()
273     {
274         return dependencyCollectionRequired;
275     }
276 
277     // ----------------------------------------------------------------------
278     // Project requirement
279     // ----------------------------------------------------------------------
280 
281     /**
282      * @param requiresProject <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code>
283      * otherwise.
284      */
285     public void setProjectRequired( boolean requiresProject )
286     {
287         this.projectRequired = requiresProject;
288     }
289 
290     /**
291      * @return <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code> otherwise.
292      */
293     public boolean isProjectRequired()
294     {
295         return projectRequired;
296     }
297 
298     // ----------------------------------------------------------------------
299     // Online vs. Offline requirement
300     // ----------------------------------------------------------------------
301 
302     /**
303      * @param requiresOnline <code>true</code> if the Mojo is online, <code>false</code> otherwise.
304      */
305     public void setOnlineRequired( boolean requiresOnline )
306     {
307         this.onlineRequired = requiresOnline;
308     }
309 
310     /**
311      * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
312      */
313     // blech! this isn't even intelligible as a method name. provided for
314     // consistency...
315     public boolean isOnlineRequired()
316     {
317         return onlineRequired;
318     }
319 
320     /**
321      * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
322      */
323     // more english-friendly method...keep the code clean! :)
324     public boolean requiresOnline()
325     {
326         return onlineRequired;
327     }
328 
329     /**
330      * @return the binded phase name of the Mojo
331      */
332     public String getPhase()
333     {
334         return phase;
335     }
336 
337     /**
338      * @param phase the new binded phase name of the Mojo
339      */
340     public void setPhase( String phase )
341     {
342         this.phase = phase;
343     }
344 
345     /**
346      * @return the version when the Mojo was added to the API
347      */
348     public String getSince()
349     {
350         return since;
351     }
352 
353     /**
354      * @param since the new version when the Mojo was added to the API
355      */
356     public void setSince( String since )
357     {
358         this.since = since;
359     }
360 
361     /**
362      * @return The goal name of the Mojo
363      */
364     public String getGoal()
365     {
366         return goal;
367     }
368 
369     /**
370      * @param goal The new goal name of the Mojo
371      */
372     public void setGoal( String goal )
373     {
374         this.goal = goal;
375     }
376 
377     /**
378      * @return the invocation phase of the Mojo
379      */
380     public String getExecutePhase()
381     {
382         return executePhase;
383     }
384 
385     /**
386      * @param executePhase the new invocation phase of the Mojo
387      */
388     public void setExecutePhase( String executePhase )
389     {
390         this.executePhase = executePhase;
391     }
392 
393     /**
394      * @return <code>true</code> if the Mojo uses <code>always</code> for the <code>executionStrategy</code>
395      */
396     public boolean alwaysExecute()
397     {
398         return MULTI_PASS_EXEC_STRATEGY.equals( executionStrategy );
399     }
400 
401     /**
402      * @return the execution strategy
403      */
404     public String getExecutionStrategy()
405     {
406         return executionStrategy;
407     }
408 
409     /**
410      * @param executionStrategy the new execution strategy
411      */
412     public void setExecutionStrategy( String executionStrategy )
413     {
414         this.executionStrategy = executionStrategy;
415     }
416 
417     /**
418      * @return the mojo configuration
419      */
420     public PlexusConfiguration getMojoConfiguration()
421     {
422         if ( mojoConfiguration == null )
423         {
424             mojoConfiguration = new XmlPlexusConfiguration( "configuration" );
425         }
426         return mojoConfiguration;
427     }
428 
429     /**
430      * @param mojoConfiguration a new mojo configuration
431      */
432     public void setMojoConfiguration( PlexusConfiguration mojoConfiguration )
433     {
434         this.mojoConfiguration = mojoConfiguration;
435     }
436 
437     /** {@inheritDoc} */
438     public String getRole()
439     {
440         return Mojo.ROLE;
441     }
442 
443     /** {@inheritDoc} */
444     public String getRoleHint()
445     {
446         return getId();
447     }
448 
449     /**
450      * @return the id of the mojo, based on the goal name
451      */
452     public String getId()
453     {
454         return getPluginDescriptor().getId() + ":" + getGoal();
455     }
456 
457     /**
458      * @return the full goal name
459      * @see PluginDescriptor#getGoalPrefix()
460      * @see #getGoal()
461      */
462     public String getFullGoalName()
463     {
464         return getPluginDescriptor().getGoalPrefix() + ":" + getGoal();
465     }
466 
467     /** {@inheritDoc} */
468     public String getComponentType()
469     {
470         return MAVEN_PLUGIN;
471     }
472 
473     /**
474      * @return the plugin descriptor
475      */
476     public PluginDescriptor getPluginDescriptor()
477     {
478         return pluginDescriptor;
479     }
480 
481     /**
482      * @param pluginDescriptor the new plugin descriptor
483      */
484     public void setPluginDescriptor( PluginDescriptor pluginDescriptor )
485     {
486         this.pluginDescriptor = pluginDescriptor;
487     }
488 
489     /**
490      * @return <code>true</code> if the Mojo is herited, <code>false</code> otherwise.
491      */
492     public boolean isInheritedByDefault()
493     {
494         return inheritedByDefault;
495     }
496 
497     /**
498      * @param inheritedByDefault <code>true</code> if the Mojo is herited, <code>false</code> otherwise.
499      */
500     public void setInheritedByDefault( boolean inheritedByDefault )
501     {
502         this.inheritedByDefault = inheritedByDefault;
503     }
504 
505     /** {@inheritDoc} */
506     public boolean equals( Object object )
507     {
508         if ( this == object )
509         {
510             return true;
511         }
512 
513         if ( object instanceof MojoDescriptor )
514         {
515             MojoDescriptor other = (MojoDescriptor) object;
516 
517             if ( !compareObjects( getPluginDescriptor(), other.getPluginDescriptor() ) )
518             {
519                 return false;
520             }
521 
522             if ( !compareObjects( getGoal(), other.getGoal() ) )
523             {
524                 return false;
525             }
526 
527             return true;
528         }
529 
530         return false;
531     }
532 
533     private boolean compareObjects( Object first, Object second )
534     {
535         if ( ( first == null && second != null ) || ( first != null && second == null ) )
536         {
537             return false;
538         }
539 
540         return first.equals( second );
541     }
542 
543     /** {@inheritDoc} */
544     public int hashCode()
545     {
546         int result = 1;
547 
548         String goal = getGoal();
549 
550         if ( goal != null )
551         {
552             result += goal.hashCode();
553         }
554 
555         PluginDescriptor pd = getPluginDescriptor();
556 
557         if ( pd != null )
558         {
559             result -= pd.hashCode();
560         }
561 
562         return result;
563     }
564 
565     /**
566      * @return the invocation lifecycle of the Mojo
567      */
568     public String getExecuteLifecycle()
569     {
570         return executeLifecycle;
571     }
572 
573     /**
574      * @param executeLifecycle the new invocation lifecycle of the Mojo
575      */
576     public void setExecuteLifecycle( String executeLifecycle )
577     {
578         this.executeLifecycle = executeLifecycle;
579     }
580 
581     /**
582      * @param aggregator <code>true</code> if the Mojo uses the Maven project and its child modules,
583      * <code>false</code> otherwise.
584      */
585     public void setAggregator( boolean aggregator )
586     {
587         this.aggregator = aggregator;
588     }
589 
590     /**
591      * @return <code>true</code> if the Mojo uses the Maven project and its child modules,
592      * <code>false</code> otherwise.
593      */
594     public boolean isAggregator()
595     {
596         return aggregator;
597     }
598 
599     /**
600      * @return <code>true</code> if the Mojo could not be invoke directly, <code>false</code> otherwise.
601      */
602     public boolean isDirectInvocationOnly()
603     {
604         return directInvocationOnly;
605     }
606 
607     /**
608      * @param directInvocationOnly <code>true</code> if the Mojo could not be invoke directly,
609      * <code>false</code> otherwise.
610      */
611     public void setDirectInvocationOnly( boolean directInvocationOnly )
612     {
613         this.directInvocationOnly = directInvocationOnly;
614     }
615 
616     /**
617      * @return <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
618      */
619     public boolean isRequiresReports()
620     {
621         return requiresReports;
622     }
623 
624     /**
625      * @param requiresReports <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
626      */
627     public void setRequiresReports( boolean requiresReports )
628     {
629         this.requiresReports = requiresReports;
630     }
631 
632     /**
633      * @param executeGoal the new invocation goal of the Mojo
634      */
635     public void setExecuteGoal( String executeGoal )
636     {
637         this.executeGoal = executeGoal;
638     }
639 
640     /**
641      * @return the invocation goal of the Mojo
642      */
643     public String getExecuteGoal()
644     {
645         return executeGoal;
646     }
647 
648 
649     /**
650      * @return True if the <code>Mojo</code> is thread-safe and can be run safely in parallel
651      */
652     public boolean isThreadSafe()
653     {
654         return threadSafe;
655     }
656 
657     /**
658      * @param threadSafe indicates that the mojo is thread-safe and can be run safely in parallel
659      */
660     public void setThreadSafe( boolean threadSafe )
661     {
662         this.threadSafe = threadSafe;
663     }
664 
665     /**
666      * @return {@code true} if this mojo forks either a goal or the lifecycle, {@code false} otherwise.
667      */
668     public boolean isForking()
669     {
670         return ( getExecuteGoal() != null && getExecuteGoal().length() > 0 )
671             || ( getExecutePhase() != null && getExecutePhase().length() > 0 );
672     }
673 
674     /**
675      * Creates a shallow copy of this mojo descriptor.
676      */
677     @Override
678     public MojoDescriptor clone()
679     {
680         try
681         {
682             return (MojoDescriptor) super.clone();
683         }
684         catch ( CloneNotSupportedException e )
685         {
686             throw new UnsupportedOperationException( e );
687         }
688     }
689 
690 }