View Javadoc
1   package org.apache.maven.plugin.plugin;
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.artifact.Artifact;
23  import org.apache.maven.artifact.repository.ArtifactRepository;
24  import org.apache.maven.doxia.sink.Sink;
25  import org.apache.maven.doxia.siterenderer.Renderer;
26  import org.apache.maven.model.Plugin;
27  import org.apache.maven.model.ReportPlugin;
28  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
29  import org.apache.maven.plugin.descriptor.MojoDescriptor;
30  import org.apache.maven.plugin.descriptor.PluginDescriptor;
31  import org.apache.maven.plugins.annotations.Component;
32  import org.apache.maven.plugins.annotations.Execute;
33  import org.apache.maven.plugins.annotations.LifecyclePhase;
34  import org.apache.maven.plugins.annotations.Mojo;
35  import org.apache.maven.plugins.annotations.Parameter;
36  import org.apache.maven.project.MavenProject;
37  import org.apache.maven.reporting.AbstractMavenReport;
38  import org.apache.maven.reporting.AbstractMavenReportRenderer;
39  import org.apache.maven.reporting.MavenReportException;
40  import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
41  import org.apache.maven.tools.plugin.PluginToolsRequest;
42  import org.apache.maven.tools.plugin.extractor.ExtractionException;
43  import org.apache.maven.tools.plugin.generator.GeneratorException;
44  import org.apache.maven.tools.plugin.generator.GeneratorUtils;
45  import org.apache.maven.tools.plugin.generator.PluginXdocGenerator;
46  import org.apache.maven.tools.plugin.scanner.MojoScanner;
47  import org.apache.maven.tools.plugin.util.PluginUtils;
48  import org.codehaus.plexus.util.StringUtils;
49  import org.codehaus.plexus.util.xml.Xpp3Dom;
50  
51  import java.io.File;
52  import java.util.ArrayList;
53  import java.util.Iterator;
54  import java.util.List;
55  import java.util.Locale;
56  import java.util.Map;
57  import java.util.ResourceBundle;
58  import java.util.Set;
59  
60  /**
61   * Generates the Plugin's documentation report.
62   *
63   * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
64   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
65   * @version $Id: PluginReport.html 907040 2014-04-27 09:50:12Z hboutemy $
66   * @since 2.0
67   */
68  @Mojo( name = "report", threadSafe = true )
69  @Execute( phase = LifecyclePhase.PROCESS_CLASSES )
70  public class PluginReport
71      extends AbstractMavenReport
72  {
73      /**
74       * Report output directory for mojo pages.
75       */
76      @Parameter( defaultValue = "${project.build.directory}/generated-site/xdoc" )
77      private File outputDirectory;
78  
79      /**
80       * Doxia Site Renderer.
81       */
82      @Component
83      private Renderer siteRenderer;
84  
85      /**
86       * The Maven Project.
87       */
88      @Component
89      private MavenProject project;
90  
91      /**
92       * Mojo scanner tools.
93       */
94      @Component
95      protected MojoScanner mojoScanner;
96  
97      /**
98       * The file encoding of the source files.
99       *
100      * @since 2.7
101      */
102     @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
103     private String encoding;
104 
105     /**
106      * Specify some requirements to execute this plugin.
107      * Example:
108      * <pre>
109      * &lt;requirements&gt;
110      *   &lt;maven&gt;2.0&lt;/maven&gt;
111      *   &lt;jdk&gt;1.4&lt;/jdk&gt;
112      *   &lt;memory&gt;256m&lt;/memory&gt;
113      *   &lt;diskSpace&gt;1m&lt;/diskSpace&gt;
114      *   &lt;others&gt;
115      *     &lt;property&gt;
116      *       &lt;name&gt;SVN&lt;/name&gt;
117      *       &lt;value&gt;1.4.6&lt;/value&gt;
118      *     &lt;/property&gt;
119      *   &lt;/others&gt;
120      * &lt;/requirements&gt;
121      * </pre>
122      */
123     @Parameter
124     private Requirements requirements;
125 
126     /**
127      * The goal prefix that will appear before the ":".
128      * By default, this plugin applies a heuristic to derive a heuristic from
129      * the plugin's artifactId.
130      * <p/>
131      * It removes any occurrences of the regular expression <strong>-?maven-?</strong>,
132      * and then removes any occurrences of <strong>-?plugin-?</strong>.
133      * <p>
134      * For example, horsefeature-maven-plugin becomes horsefeature.
135      * </p>
136      * <p>
137      * (There is a special for maven-plugin-plugin; it is mapped to 'plugin'.
138      * </p>
139      *
140      * @since 2.4
141      */
142     @Parameter( property = "goalPrefix" )
143     protected String goalPrefix;
144 
145     /**
146      * Set this to "true" to skip invoking any goals or reports of the plugin.
147      *
148      * @since 2.8
149      */
150     @Parameter( defaultValue = "false", property = "maven.plugin.skip" )
151     private boolean skip;
152 
153     /**
154      * Set this to "true" to skip generating the report.
155      *
156      * @since 2.8
157      */
158     @Parameter( defaultValue = "false", property = "maven.plugin.report.skip" )
159     private boolean skipReport;
160 
161     /**
162      * The set of dependencies for the current project
163      *
164      * @since 3.0
165      */
166     @Parameter( defaultValue = "${project.artifacts}", required = true, readonly = true )
167     protected Set<Artifact> dependencies;
168 
169     /**
170      * List of Remote Repositories used by the resolver
171      *
172      * @since 3.0
173      */
174     @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
175     protected List<ArtifactRepository> remoteRepos;
176 
177     /**
178      * Location of the local repository.
179      *
180      * @since 3.0
181      */
182     @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
183     protected ArtifactRepository local;
184 
185     /**
186      * {@inheritDoc}
187      */
188     protected Renderer getSiteRenderer()
189     {
190         return siteRenderer;
191     }
192 
193     /**
194      * {@inheritDoc}
195      */
196     protected String getOutputDirectory()
197     {
198         // PLUGIN-191: output directory of plugin.html, not *-mojo.xml
199         return project.getReporting().getOutputDirectory();
200     }
201 
202     /**
203      * {@inheritDoc}
204      */
205     protected MavenProject getProject()
206     {
207         return project;
208     }
209 
210     /**
211      * {@inheritDoc}
212      */
213     public boolean canGenerateReport()
214     {
215         return "maven-plugin".equals( project.getPackaging() );
216     }
217 
218     /**
219      * {@inheritDoc}
220      */
221     @SuppressWarnings( "unchecked" )
222     protected void executeReport( Locale locale )
223         throws MavenReportException
224     {
225         if ( !canGenerateReport() )
226         {
227             return;
228         }
229         if ( skip || skipReport )
230         {
231             getLog().info( "Maven Plugin Plugin Report generation skipped." );
232             return;
233         }
234 
235         // Copy from AbstractGeneratorMojo#execute()
236         String defaultGoalPrefix = PluginDescriptor.getGoalPrefixFromArtifactId( project.getArtifactId() );
237         if ( goalPrefix == null )
238         {
239             goalPrefix = defaultGoalPrefix;
240         }
241         else
242         {
243             getLog().warn( "\n\nGoal prefix is specified as: '" + goalPrefix + "'. Maven currently expects it to be '"
244                                + defaultGoalPrefix + "'.\n" );
245         }
246 
247         // TODO: could use this more, eg in the writing of the plugin descriptor!
248         PluginDescriptor pluginDescriptor = new PluginDescriptor();
249 
250         pluginDescriptor.setGroupId( project.getGroupId() );
251 
252         pluginDescriptor.setArtifactId( project.getArtifactId() );
253 
254         pluginDescriptor.setVersion( project.getVersion() );
255 
256         pluginDescriptor.setGoalPrefix( goalPrefix );
257 
258         try
259         {
260             pluginDescriptor.setDependencies( GeneratorUtils.toComponentDependencies( project.getRuntimeDependencies() ) );
261 
262             PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
263             request.setEncoding( encoding );
264             request.setSkipErrorNoDescriptorsFound( true );
265             request.setDependencies( dependencies );
266             request.setLocal( this.local );
267             request.setRemoteRepos( this.remoteRepos );
268 
269 
270             try
271             {
272                 mojoScanner.populatePluginDescriptor( request );
273             }
274             catch ( InvalidPluginDescriptorException e )
275             {
276                 // this is OK, it happens to lifecycle plugins. Allow generation to proceed.
277                 getLog().debug( "Plugin without mojos.", e );
278 
279             }
280 
281             // Generate the plugin's documentation
282             generatePluginDocumentation( pluginDescriptor, locale );
283 
284             // Write the overview
285             PluginOverviewRenderer r =
286                 new PluginOverviewRenderer( project, requirements, getSink(), pluginDescriptor, locale );
287             r.render();
288         }
289 
290         catch ( ExtractionException e )
291         {
292             throw new MavenReportException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
293                                             e );
294         }
295     }
296 
297     /**
298      * {@inheritDoc}
299      */
300     public String getDescription( Locale locale )
301     {
302         return getBundle( locale ).getString( "report.plugin.description" );
303     }
304 
305     /**
306      * {@inheritDoc}
307      */
308     public String getName( Locale locale )
309     {
310         return getBundle( locale ).getString( "report.plugin.name" );
311     }
312 
313     /**
314      * {@inheritDoc}
315      */
316     public String getOutputName()
317     {
318         return "plugin-info";
319     }
320 
321     /**
322      * @param pluginDescriptor not null
323      * @param locale           not null
324      * @throws MavenReportException if any
325      */
326     private void generatePluginDocumentation( PluginDescriptor pluginDescriptor, Locale locale )
327         throws MavenReportException
328     {
329         try
330         {
331             File outputDir = outputDirectory;
332             outputDir.mkdirs();
333 
334             PluginXdocGenerator generator = new PluginXdocGenerator( project, locale );
335             PluginToolsRequest pluginToolsRequest = new DefaultPluginToolsRequest( project, pluginDescriptor );
336             generator.execute( outputDir, pluginToolsRequest );
337         }
338         catch ( GeneratorException e )
339         {
340             throw new MavenReportException( "Error writing plugin documentation", e );
341         }
342 
343     }
344 
345     /**
346      * @param locale not null
347      * @return the bundle for this report
348      */
349     protected static ResourceBundle getBundle( Locale locale )
350     {
351         return ResourceBundle.getBundle( "plugin-report", locale, PluginReport.class.getClassLoader() );
352     }
353 
354     /**
355      * Generates an overview page with the list of goals
356      * and a link to the goal's page.
357      */
358     static class PluginOverviewRenderer
359         extends AbstractMavenReportRenderer
360     {
361         private final MavenProject project;
362 
363         private final Requirements requirements;
364 
365         private final PluginDescriptor pluginDescriptor;
366 
367         private final Locale locale;
368 
369         /**
370          * @param project          not null
371          * @param requirements     not null
372          * @param sink             not null
373          * @param pluginDescriptor not null
374          * @param locale           not null
375          */
376         public PluginOverviewRenderer( MavenProject project, Requirements requirements, Sink sink,
377                                        PluginDescriptor pluginDescriptor, Locale locale )
378         {
379             super( sink );
380 
381             this.project = project;
382 
383             this.requirements = ( requirements == null ? new Requirements() : requirements );
384 
385             this.pluginDescriptor = pluginDescriptor;
386 
387             this.locale = locale;
388         }
389 
390         /**
391          * {@inheritDoc}
392          */
393         public String getTitle()
394         {
395             return getBundle( locale ).getString( "report.plugin.title" );
396         }
397 
398         /**
399          * {@inheritDoc}
400          */
401         @SuppressWarnings( { "unchecked", "rawtypes" } )
402         public void renderBody()
403         {
404             startSection( getTitle() );
405 
406             if ( !( pluginDescriptor.getMojos() != null && pluginDescriptor.getMojos().size() > 0 ) )
407             {
408                 paragraph( getBundle( locale ).getString( "report.plugin.goals.nogoal" ) );
409                 endSection();
410                 return;
411             }
412 
413             paragraph( getBundle( locale ).getString( "report.plugin.goals.intro" ) );
414 
415             boolean hasMavenReport = false;
416             for ( Iterator<MojoDescriptor> i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
417             {
418                 MojoDescriptor mojo = i.next();
419 
420                 if ( GeneratorUtils.isMavenReport( mojo.getImplementation(), project ) )
421                 {
422                     hasMavenReport = true;
423                 }
424             }
425 
426             startTable();
427 
428             String goalColumnName = getBundle( locale ).getString( "report.plugin.goals.column.goal" );
429             String isMavenReport = getBundle( locale ).getString( "report.plugin.goals.column.isMavenReport" );
430             String descriptionColumnName = getBundle( locale ).getString( "report.plugin.goals.column.description" );
431             if ( hasMavenReport )
432             {
433                 tableHeader( new String[]{ goalColumnName, isMavenReport, descriptionColumnName } );
434             }
435             else
436             {
437                 tableHeader( new String[]{ goalColumnName, descriptionColumnName } );
438             }
439 
440             List<MojoDescriptor> mojos = new ArrayList<MojoDescriptor>();
441             mojos.addAll( pluginDescriptor.getMojos() );
442             PluginUtils.sortMojos( mojos );
443             for ( MojoDescriptor mojo : mojos )
444             {
445                 String goalName = mojo.getFullGoalName();
446 
447                 /*
448                  * Added ./ to define a relative path
449                  * @see AbstractMavenReportRenderer#getValidHref(java.lang.String)
450                  */
451                 String goalDocumentationLink = "./" + mojo.getGoal() + "-mojo.html";
452 
453                 String description;
454                 if ( StringUtils.isNotEmpty( mojo.getDeprecated() ) )
455                 {
456                     description =
457                         "<strong>" + getBundle( locale ).getString( "report.plugin.goal.deprecated" ) + "</strong> "
458                             + GeneratorUtils.makeHtmlValid( mojo.getDeprecated() );
459                 }
460                 else if ( StringUtils.isNotEmpty( mojo.getDescription() ) )
461                 {
462                     description = GeneratorUtils.makeHtmlValid( mojo.getDescription() );
463                 }
464                 else
465                 {
466                     description = getBundle( locale ).getString( "report.plugin.goal.nodescription" );
467                 }
468 
469                 sink.tableRow();
470                 tableCell( createLinkPatternedText( goalName, goalDocumentationLink ) );
471                 if ( hasMavenReport )
472                 {
473                     if ( GeneratorUtils.isMavenReport( mojo.getImplementation(), project ) )
474                     {
475                         sink.tableCell();
476                         sink.text( getBundle( locale ).getString( "report.plugin.isReport" ) );
477                         sink.tableCell_();
478                     }
479                     else
480                     {
481                         sink.tableCell();
482                         sink.text( getBundle( locale ).getString( "report.plugin.isNotReport" ) );
483                         sink.tableCell_();
484                     }
485                 }
486                 tableCell( description, true );
487                 sink.tableRow_();
488             }
489 
490             endTable();
491 
492             startSection( getBundle( locale ).getString( "report.plugin.systemrequirements" ) );
493 
494             paragraph( getBundle( locale ).getString( "report.plugin.systemrequirements.intro" ) );
495 
496             startTable();
497 
498             String maven = discoverMavenRequirement( project, requirements );
499             sink.tableRow();
500             tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.maven" ) );
501             tableCell( ( maven != null
502                 ? maven
503                 : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
504             sink.tableRow_();
505 
506             String jdk = discoverJdkRequirement( project, requirements );
507             sink.tableRow();
508             tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.jdk" ) );
509             tableCell(
510                 ( jdk != null ? jdk : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
511             sink.tableRow_();
512 
513             sink.tableRow();
514             tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.memory" ) );
515             tableCell( ( StringUtils.isNotEmpty( requirements.getMemory() )
516                 ? requirements.getMemory()
517                 : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
518             sink.tableRow_();
519 
520             sink.tableRow();
521             tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.diskspace" ) );
522             tableCell( ( StringUtils.isNotEmpty( requirements.getDiskSpace() )
523                 ? requirements.getDiskSpace()
524                 : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
525             sink.tableRow_();
526 
527             if ( requirements.getOthers() != null && requirements.getOthers().size() > 0 )
528             {
529                 for ( Iterator it = requirements.getOthers().keySet().iterator(); it.hasNext(); )
530                 {
531                     String key = it.next().toString();
532 
533                     sink.tableRow();
534                     tableCell( key );
535                     tableCell( ( StringUtils.isNotEmpty( requirements.getOthers().getProperty( key ) )
536                         ? requirements.getOthers().getProperty( key )
537                         : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
538                     sink.tableRow_();
539                 }
540             }
541             endTable();
542 
543             endSection();
544 
545             renderUsageSection( hasMavenReport );
546 
547             endSection();
548         }
549 
550         /**
551          * Render the section about the usage of the plugin.
552          *
553          * @param hasMavenReport If the plugin has a report or not
554          */
555         private void renderUsageSection( boolean hasMavenReport )
556         {
557             startSection( getBundle( locale ).getString( "report.plugin.usage" ) );
558 
559             // Configuration
560             sink.paragraph();
561             text( getBundle( locale ).getString( "report.plugin.usage.intro" ) );
562             sink.paragraph_();
563 
564             StringBuilder sb = new StringBuilder();
565             sb.append( "<project>" ).append( '\n' );
566             sb.append( "  ..." ).append( '\n' );
567             sb.append( "  <build>" ).append( '\n' );
568             sb.append(
569                 "    <!-- " + getBundle( locale ).getString( "report.plugin.usage.pluginManagement" ) + " -->" ).append(
570                 '\n' );
571             sb.append( "    <pluginManagement>" ).append( '\n' );
572             sb.append( "      <plugins>" ).append( '\n' );
573             sb.append( "        <plugin>" ).append( '\n' );
574             sb.append( "          <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
575                 '\n' );
576             sb.append( "          <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
577                 "</artifactId>" ).append( '\n' );
578             sb.append( "          <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
579                 '\n' );
580             sb.append( "        </plugin>" ).append( '\n' );
581             sb.append( "        ..." ).append( '\n' );
582             sb.append( "      </plugins>" ).append( '\n' );
583             sb.append( "    </pluginManagement>" ).append( '\n' );
584             sb.append( "    <!-- " + getBundle( locale ).getString( "report.plugin.usage.plugins" ) + " -->" ).append(
585                 '\n' );
586             sb.append( "    <plugins>" ).append( '\n' );
587             sb.append( "      <plugin>" ).append( '\n' );
588             sb.append( "        <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
589                 '\n' );
590             sb.append( "        <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
591                 "</artifactId>" ).append( '\n' );
592             sb.append( "        <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
593                 '\n' );
594             sb.append( "      </plugin>" ).append( '\n' );
595             sb.append( "      ..." ).append( '\n' );
596             sb.append( "    </plugins>" ).append( '\n' );
597             sb.append( "  </build>" ).append( '\n' );
598 
599             if ( hasMavenReport )
600             {
601                 sb.append( "  ..." ).append( '\n' );
602                 sb.append(
603                     "  <!-- " + getBundle( locale ).getString( "report.plugin.usage.reporting" ) + " -->" ).append(
604                     '\n' );
605                 sb.append( "  <reporting>" ).append( '\n' );
606                 sb.append( "    <plugins>" ).append( '\n' );
607                 sb.append( "      <plugin>" ).append( '\n' );
608                 sb.append( "        <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
609                     '\n' );
610                 sb.append( "        <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
611                     "</artifactId>" ).append( '\n' );
612                 sb.append( "        <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
613                     '\n' );
614                 sb.append( "      </plugin>" ).append( '\n' );
615                 sb.append( "      ..." ).append( '\n' );
616                 sb.append( "    </plugins>" ).append( '\n' );
617                 sb.append( "  </reporting>" ).append( '\n' );
618             }
619 
620             sb.append( "  ..." ).append( '\n' );
621             sb.append( "</project>" ).append( '\n' );
622 
623             verbatimText( sb.toString() );
624 
625             sink.paragraph();
626             linkPatternedText( getBundle( locale ).getString( "report.plugin.configuration.end" ) );
627             sink.paragraph_();
628 
629             endSection();
630         }
631 
632         /**
633          * Try to lookup on the Maven prerequisites property.
634          * If not specified, uses the value defined by the user.
635          *
636          * @param project      not null
637          * @param requirements not null
638          * @return the Maven version
639          */
640         private static String discoverMavenRequirement( MavenProject project, Requirements requirements )
641         {
642             String maven = requirements.getMaven();
643             if ( maven == null )
644             {
645                 maven = ( project.getPrerequisites() != null ? project.getPrerequisites().getMaven() : null );
646             }
647             if ( maven == null )
648             {
649                 maven = "2.0";
650             }
651 
652             return maven;
653         }
654 
655         /**
656          * Try to lookup on the <code>org.apache.maven.plugins:maven-compiler-plugin</code> plugin to
657          * find the value of the <code>target</code> option.
658          * If not specified, uses the value defined by the user.
659          * If not specified, uses the value of the system property <code>java.specification.version</code>.
660          *
661          * @param project      not null
662          * @param requirements not null
663          * @return the JDK version
664          */
665         private static String discoverJdkRequirement( MavenProject project, Requirements requirements )
666         {
667             String jdk = requirements.getJdk();
668             if ( jdk == null )
669             {
670                 jdk = discoverJdkRequirementFromPlugins( project.getBuild().getPluginsAsMap() );
671             }
672             if ( jdk == null && project.getPluginManagement() != null )
673             {
674                     jdk = discoverJdkRequirementFromPlugins( project.getPluginManagement().getPluginsAsMap() );
675             }
676             if ( jdk == null )
677             {
678                 jdk = "Unknown";
679             }
680 
681             return jdk;
682         }
683 
684         /**
685          * @param pluginsAsMap could be null
686          * @return the value of the <code>target</code> in the configuration of <code>maven-compiler-plugin</code>.
687          */
688         @SuppressWarnings( "rawtypes" )
689         private static String discoverJdkRequirementFromPlugins( Map pluginsAsMap )
690         {
691             if ( pluginsAsMap == null )
692             {
693                 return null;
694             }
695 
696             String jdk = null;
697             String backupJdk = null;
698             for ( Iterator it = pluginsAsMap.keySet().iterator(); it.hasNext(); )
699             {
700                 String key = it.next().toString();
701 
702                 if ( !key.equals( "org.apache.maven.plugins:maven-compiler-plugin" ) )
703                 {
704                     continue;
705                 }
706 
707                 Object value = pluginsAsMap.get( key );
708                 Xpp3Dom pluginConf = null;
709 
710                 backupJdk = "Default version for maven-compiler-plugin";
711                 if ( value instanceof Plugin )
712                 {
713                     Plugin plugin = (Plugin) value;
714                     backupJdk = "Default target for maven-compiler-plugin version " + plugin.getVersion();
715                     pluginConf = (Xpp3Dom) plugin.getConfiguration();
716                 }
717 
718                 if ( value instanceof ReportPlugin )
719                 {
720                     ReportPlugin reportPlugin = (ReportPlugin) value;
721                     backupJdk = "Default target for maven-compiler-plugin version " + reportPlugin.getVersion();
722                     pluginConf = (Xpp3Dom) reportPlugin.getConfiguration();
723                 }
724 
725                 if ( pluginConf == null )
726                 {
727                     continue;
728                 }
729 
730                 if ( pluginConf.getChild( "target" ) == null )
731                 {
732                     continue;
733                 }
734 
735                 jdk = pluginConf.getChild( "target" ).getValue();
736             }
737 
738             if ( jdk == null )
739             {
740                 return backupJdk;
741             }
742             else
743             {
744                 return jdk;
745             }
746         }
747     }
748 }