001    package org.apache.maven.plugin.plugin;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.maven.artifact.Artifact;
023    import org.apache.maven.artifact.repository.ArtifactRepository;
024    import org.apache.maven.doxia.sink.Sink;
025    import org.apache.maven.doxia.siterenderer.Renderer;
026    import org.apache.maven.model.Plugin;
027    import org.apache.maven.model.ReportPlugin;
028    import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
029    import org.apache.maven.plugin.descriptor.MojoDescriptor;
030    import org.apache.maven.plugin.descriptor.PluginDescriptor;
031    import org.apache.maven.plugins.annotations.Component;
032    import org.apache.maven.plugins.annotations.Execute;
033    import org.apache.maven.plugins.annotations.LifecyclePhase;
034    import org.apache.maven.plugins.annotations.Mojo;
035    import org.apache.maven.plugins.annotations.Parameter;
036    import org.apache.maven.project.MavenProject;
037    import org.apache.maven.reporting.AbstractMavenReport;
038    import org.apache.maven.reporting.AbstractMavenReportRenderer;
039    import org.apache.maven.reporting.MavenReportException;
040    import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
041    import org.apache.maven.tools.plugin.PluginToolsRequest;
042    import org.apache.maven.tools.plugin.extractor.ExtractionException;
043    import org.apache.maven.tools.plugin.generator.GeneratorException;
044    import org.apache.maven.tools.plugin.generator.GeneratorUtils;
045    import org.apache.maven.tools.plugin.generator.PluginXdocGenerator;
046    import org.apache.maven.tools.plugin.scanner.MojoScanner;
047    import org.apache.maven.tools.plugin.util.PluginUtils;
048    import org.codehaus.plexus.util.StringUtils;
049    import org.codehaus.plexus.util.xml.Xpp3Dom;
050    
051    import java.io.File;
052    import java.util.ArrayList;
053    import java.util.Iterator;
054    import java.util.List;
055    import java.util.Locale;
056    import java.util.Map;
057    import java.util.ResourceBundle;
058    import java.util.Set;
059    
060    /**
061     * Generates the Plugin's documentation report.
062     *
063     * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
064     * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
065     * @version $Id: PluginReport.java 1405633 2012-11-04 20:50:33Z rfscholte $
066     * @since 2.0
067     */
068    @Mojo( name = "report", threadSafe = true )
069    @Execute( phase = LifecyclePhase.PROCESS_CLASSES )
070    public class PluginReport
071        extends AbstractMavenReport
072    {
073        /**
074         * Report output directory.
075         */
076        @Parameter( defaultValue = "${project.build.directory}/generated-site/xdoc" )
077        private File outputDirectory;
078    
079        /**
080         * Doxia Site Renderer.
081         */
082        @Component
083        private Renderer siteRenderer;
084    
085        /**
086         * The Maven Project.
087         */
088        @Component
089        private MavenProject project;
090    
091        /**
092         * Mojo scanner tools.
093         */
094        @Component
095        protected MojoScanner mojoScanner;
096    
097        /**
098         * The file encoding of the source files.
099         *
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            return outputDirectory.getPath();
199        }
200    
201        /**
202         * {@inheritDoc}
203         */
204        protected MavenProject getProject()
205        {
206            return project;
207        }
208    
209        /**
210         * {@inheritDoc}
211         */
212        public boolean canGenerateReport()
213        {
214            return "maven-plugin".equals( project.getPackaging() );
215        }
216    
217        /**
218         * {@inheritDoc}
219         */
220        @SuppressWarnings( "unchecked" )
221        protected void executeReport( Locale locale )
222            throws MavenReportException
223        {
224            if ( !canGenerateReport() )
225            {
226                return;
227            }
228            if ( skip || skipReport )
229            {
230                getLog().info( "Maven Plugin Plugin Report generation skipped." );
231                return;
232            }
233    
234            // Copy from AbstractGeneratorMojo#execute()
235            String defaultGoalPrefix = PluginDescriptor.getGoalPrefixFromArtifactId( project.getArtifactId() );
236            if ( goalPrefix == null )
237            {
238                goalPrefix = defaultGoalPrefix;
239            }
240            else
241            {
242                getLog().warn( "\n\nGoal prefix is specified as: '" + goalPrefix + "'. Maven currently expects it to be '"
243                                   + defaultGoalPrefix + "'.\n" );
244            }
245    
246            // TODO: could use this more, eg in the writing of the plugin descriptor!
247            PluginDescriptor pluginDescriptor = new PluginDescriptor();
248    
249            pluginDescriptor.setGroupId( project.getGroupId() );
250    
251            pluginDescriptor.setArtifactId( project.getArtifactId() );
252    
253            pluginDescriptor.setVersion( project.getVersion() );
254    
255            pluginDescriptor.setGoalPrefix( goalPrefix );
256    
257            try
258            {
259                pluginDescriptor.setDependencies( GeneratorUtils.toComponentDependencies( project.getRuntimeDependencies() ) );
260    
261                PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
262                request.setEncoding( encoding );
263                request.setSkipErrorNoDescriptorsFound( true );
264                request.setDependencies( dependencies );
265                request.setLocal( this.local );
266                request.setRemoteRepos( this.remoteRepos );
267    
268    
269                try
270                {
271                    mojoScanner.populatePluginDescriptor( request );
272                }
273                catch ( InvalidPluginDescriptorException e )
274                {
275                    // this is OK, it happens to lifecycle plugins. Allow generation to proceed.
276                    getLog().debug( "Plugin without mojos.", e );
277    
278                }
279    
280                // Generate the plugin's documentation
281                generatePluginDocumentation( pluginDescriptor, locale );
282    
283                // Write the overview
284                PluginOverviewRenderer r =
285                    new PluginOverviewRenderer( project, requirements, getSink(), pluginDescriptor, locale );
286                r.render();
287            }
288    
289            catch ( ExtractionException e )
290            {
291                throw new MavenReportException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
292                                                e );
293            }
294        }
295    
296        /**
297         * {@inheritDoc}
298         */
299        public String getDescription( Locale locale )
300        {
301            return getBundle( locale ).getString( "report.plugin.description" );
302        }
303    
304        /**
305         * {@inheritDoc}
306         */
307        public String getName( Locale locale )
308        {
309            return getBundle( locale ).getString( "report.plugin.name" );
310        }
311    
312        /**
313         * {@inheritDoc}
314         */
315        public String getOutputName()
316        {
317            return "plugin-info";
318        }
319    
320        /**
321         * @param pluginDescriptor not null
322         * @param locale           not null
323         * @throws MavenReportException if any
324         */
325        private void generatePluginDocumentation( PluginDescriptor pluginDescriptor, Locale locale )
326            throws MavenReportException
327        {
328            try
329            {
330                File outputDir = new File( getOutputDirectory() );
331                outputDir.mkdirs();
332    
333                PluginXdocGenerator generator = new PluginXdocGenerator( project, locale );
334                PluginToolsRequest pluginToolsRequest = new DefaultPluginToolsRequest( project, pluginDescriptor );
335                generator.execute( outputDir, pluginToolsRequest );
336            }
337            catch ( GeneratorException e )
338            {
339                throw new MavenReportException( "Error writing plugin documentation", e );
340            }
341    
342        }
343    
344        /**
345         * @param locale not null
346         * @return the bundle for this report
347         */
348        protected static ResourceBundle getBundle( Locale locale )
349        {
350            return ResourceBundle.getBundle( "plugin-report", locale, PluginReport.class.getClassLoader() );
351        }
352    
353        /**
354         * Generates an overview page with the list of goals
355         * and a link to the goal's page.
356         */
357        static class PluginOverviewRenderer
358            extends AbstractMavenReportRenderer
359        {
360            private final MavenProject project;
361    
362            private final Requirements requirements;
363    
364            private final PluginDescriptor pluginDescriptor;
365    
366            private final Locale locale;
367    
368            /**
369             * @param project          not null
370             * @param requirements     not null
371             * @param sink             not null
372             * @param pluginDescriptor not null
373             * @param locale           not null
374             */
375            public PluginOverviewRenderer( MavenProject project, Requirements requirements, Sink sink,
376                                           PluginDescriptor pluginDescriptor, Locale locale )
377            {
378                super( sink );
379    
380                this.project = project;
381    
382                this.requirements = ( requirements == null ? new Requirements() : requirements );
383    
384                this.pluginDescriptor = pluginDescriptor;
385    
386                this.locale = locale;
387            }
388    
389            /**
390             * {@inheritDoc}
391             */
392            public String getTitle()
393            {
394                return getBundle( locale ).getString( "report.plugin.title" );
395            }
396    
397            /**
398             * {@inheritDoc}
399             */
400            @SuppressWarnings( { "unchecked", "rawtypes" } )
401            public void renderBody()
402            {
403                startSection( getTitle() );
404    
405                if ( !( pluginDescriptor.getMojos() != null && pluginDescriptor.getMojos().size() > 0 ) )
406                {
407                    paragraph( getBundle( locale ).getString( "report.plugin.goals.nogoal" ) );
408                    endSection();
409                    return;
410                }
411    
412                paragraph( getBundle( locale ).getString( "report.plugin.goals.intro" ) );
413    
414                boolean hasMavenReport = false;
415                for ( Iterator<MojoDescriptor> i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
416                {
417                    MojoDescriptor mojo = i.next();
418    
419                    if ( GeneratorUtils.isMavenReport( mojo.getImplementation(), project ) )
420                    {
421                        hasMavenReport = true;
422                    }
423                }
424    
425                startTable();
426    
427                String goalColumnName = getBundle( locale ).getString( "report.plugin.goals.column.goal" );
428                String isMavenReport = getBundle( locale ).getString( "report.plugin.goals.column.isMavenReport" );
429                String descriptionColumnName = getBundle( locale ).getString( "report.plugin.goals.column.description" );
430                if ( hasMavenReport )
431                {
432                    tableHeader( new String[]{ goalColumnName, isMavenReport, descriptionColumnName } );
433                }
434                else
435                {
436                    tableHeader( new String[]{ goalColumnName, descriptionColumnName } );
437                }
438    
439                List<MojoDescriptor> mojos = new ArrayList<MojoDescriptor>();
440                mojos.addAll( pluginDescriptor.getMojos() );
441                PluginUtils.sortMojos( mojos );
442                for ( MojoDescriptor mojo : mojos )
443                {
444                    String goalName = mojo.getFullGoalName();
445    
446                    /*
447                     * Added ./ to define a relative path
448                     * @see AbstractMavenReportRenderer#getValidHref(java.lang.String)
449                     */
450                    String goalDocumentationLink = "./" + mojo.getGoal() + "-mojo.html";
451    
452                    String description;
453                    if ( StringUtils.isNotEmpty( mojo.getDeprecated() ) )
454                    {
455                        description =
456                            "<strong>" + getBundle( locale ).getString( "report.plugin.goal.deprecated" ) + "</strong> "
457                                + GeneratorUtils.makeHtmlValid( mojo.getDeprecated() );
458                    }
459                    else if ( StringUtils.isNotEmpty( mojo.getDescription() ) )
460                    {
461                        description = GeneratorUtils.makeHtmlValid( mojo.getDescription() );
462                    }
463                    else
464                    {
465                        description = getBundle( locale ).getString( "report.plugin.goal.nodescription" );
466                    }
467    
468                    sink.tableRow();
469                    tableCell( createLinkPatternedText( goalName, goalDocumentationLink ) );
470                    if ( hasMavenReport )
471                    {
472                        if ( GeneratorUtils.isMavenReport( mojo.getImplementation(), project ) )
473                        {
474                            sink.tableCell();
475                            sink.text( getBundle( locale ).getString( "report.plugin.isReport" ) );
476                            sink.tableCell_();
477                        }
478                        else
479                        {
480                            sink.tableCell();
481                            sink.text( getBundle( locale ).getString( "report.plugin.isNotReport" ) );
482                            sink.tableCell_();
483                        }
484                    }
485                    tableCell( description, true );
486                    sink.tableRow_();
487                }
488    
489                endTable();
490    
491                startSection( getBundle( locale ).getString( "report.plugin.systemrequirements" ) );
492    
493                paragraph( getBundle( locale ).getString( "report.plugin.systemrequirements.intro" ) );
494    
495                startTable();
496    
497                String maven = discoverMavenRequirement( project, requirements );
498                sink.tableRow();
499                tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.maven" ) );
500                tableCell( ( maven != null
501                    ? maven
502                    : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
503                sink.tableRow_();
504    
505                String jdk = discoverJdkRequirement( project, requirements );
506                sink.tableRow();
507                tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.jdk" ) );
508                tableCell(
509                    ( jdk != null ? jdk : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
510                sink.tableRow_();
511    
512                sink.tableRow();
513                tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.memory" ) );
514                tableCell( ( StringUtils.isNotEmpty( requirements.getMemory() )
515                    ? requirements.getMemory()
516                    : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
517                sink.tableRow_();
518    
519                sink.tableRow();
520                tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.diskspace" ) );
521                tableCell( ( StringUtils.isNotEmpty( requirements.getDiskSpace() )
522                    ? requirements.getDiskSpace()
523                    : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
524                sink.tableRow_();
525    
526                if ( requirements.getOthers() != null && requirements.getOthers().size() > 0 )
527                {
528                    for ( Iterator it = requirements.getOthers().keySet().iterator(); it.hasNext(); )
529                    {
530                        String key = it.next().toString();
531    
532                        sink.tableRow();
533                        tableCell( key );
534                        tableCell( ( StringUtils.isNotEmpty( requirements.getOthers().getProperty( key ) )
535                            ? requirements.getOthers().getProperty( key )
536                            : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
537                        sink.tableRow_();
538                    }
539                }
540                endTable();
541    
542                endSection();
543    
544                renderUsageSection( hasMavenReport );
545    
546                endSection();
547            }
548    
549            /**
550             * Render the section about the usage of the plugin.
551             *
552             * @param hasMavenReport If the plugin has a report or not
553             */
554            private void renderUsageSection( boolean hasMavenReport )
555            {
556                startSection( getBundle( locale ).getString( "report.plugin.usage" ) );
557    
558                // Configuration
559                sink.paragraph();
560                text( getBundle( locale ).getString( "report.plugin.usage.intro" ) );
561                sink.paragraph_();
562    
563                StringBuilder sb = new StringBuilder();
564                sb.append( "<project>" ).append( '\n' );
565                sb.append( "  ..." ).append( '\n' );
566                sb.append( "  <build>" ).append( '\n' );
567                sb.append(
568                    "    <!-- " + getBundle( locale ).getString( "report.plugin.usage.pluginManagement" ) + " -->" ).append(
569                    '\n' );
570                sb.append( "    <pluginManagement>" ).append( '\n' );
571                sb.append( "      <plugins>" ).append( '\n' );
572                sb.append( "        <plugin>" ).append( '\n' );
573                sb.append( "          <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
574                    '\n' );
575                sb.append( "          <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
576                    "</artifactId>" ).append( '\n' );
577                sb.append( "          <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
578                    '\n' );
579                sb.append( "        </plugin>" ).append( '\n' );
580                sb.append( "        ..." ).append( '\n' );
581                sb.append( "      </plugins>" ).append( '\n' );
582                sb.append( "    </pluginManagement>" ).append( '\n' );
583                sb.append( "    <!-- " + getBundle( locale ).getString( "report.plugin.usage.plugins" ) + " -->" ).append(
584                    '\n' );
585                sb.append( "    <plugins>" ).append( '\n' );
586                sb.append( "      <plugin>" ).append( '\n' );
587                sb.append( "        <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
588                    '\n' );
589                sb.append( "        <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
590                    "</artifactId>" ).append( '\n' );
591                sb.append( "        <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
592                    '\n' );
593                sb.append( "      </plugin>" ).append( '\n' );
594                sb.append( "      ..." ).append( '\n' );
595                sb.append( "    </plugins>" ).append( '\n' );
596                sb.append( "  </build>" ).append( '\n' );
597    
598                if ( hasMavenReport )
599                {
600                    sb.append( "  ..." ).append( '\n' );
601                    sb.append(
602                        "  <!-- " + getBundle( locale ).getString( "report.plugin.usage.reporting" ) + " -->" ).append(
603                        '\n' );
604                    sb.append( "  <reporting>" ).append( '\n' );
605                    sb.append( "    <plugins>" ).append( '\n' );
606                    sb.append( "      <plugin>" ).append( '\n' );
607                    sb.append( "        <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
608                        '\n' );
609                    sb.append( "        <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
610                        "</artifactId>" ).append( '\n' );
611                    sb.append( "        <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
612                        '\n' );
613                    sb.append( "      </plugin>" ).append( '\n' );
614                    sb.append( "      ..." ).append( '\n' );
615                    sb.append( "    </plugins>" ).append( '\n' );
616                    sb.append( "  </reporting>" ).append( '\n' );
617                }
618    
619                sb.append( "  ..." ).append( '\n' );
620                sb.append( "</project>" ).append( '\n' );
621    
622                verbatimText( sb.toString() );
623    
624                sink.paragraph();
625                linkPatternedText( getBundle( locale ).getString( "report.plugin.configuration.end" ) );
626                sink.paragraph_();
627    
628                endSection();
629            }
630    
631            /**
632             * Try to lookup on the Maven prerequisites property.
633             * If not specified, uses the value defined by the user.
634             *
635             * @param project      not null
636             * @param requirements not null
637             * @return the Maven version
638             */
639            private static String discoverMavenRequirement( MavenProject project, Requirements requirements )
640            {
641                String maven = requirements.getMaven();
642                if ( maven == null )
643                {
644                    maven = ( project.getPrerequisites() != null ? project.getPrerequisites().getMaven() : null );
645                }
646                if ( maven == null )
647                {
648                    maven = "2.0";
649                }
650    
651                return maven;
652            }
653    
654            /**
655             * Try to lookup on the <code>org.apache.maven.plugins:maven-compiler-plugin</code> plugin to
656             * find the value of the <code>target</code> option.
657             * If not specified, uses the value defined by the user.
658             * If not specified, uses the value of the system property <code>java.specification.version</code>.
659             *
660             * @param project      not null
661             * @param requirements not null
662             * @return the JDK version
663             */
664            private static String discoverJdkRequirement( MavenProject project, Requirements requirements )
665            {
666                String jdk = requirements.getJdk();
667                if ( jdk == null )
668                {
669                    jdk = discoverJdkRequirementFromPlugins( project.getBuild().getPluginsAsMap() );
670                }
671                if ( jdk == null && project.getPluginManagement() != null )
672                {
673                        jdk = discoverJdkRequirementFromPlugins( project.getPluginManagement().getPluginsAsMap() );
674                }
675                if ( jdk == null )
676                {
677                    jdk = "Unknown";
678                }
679    
680                return jdk;
681            }
682    
683            /**
684             * @param pluginsAsMap could be null
685             * @return the value of the <code>target</code> in the configuration of <code>maven-compiler-plugin</code>.
686             */
687            @SuppressWarnings( "rawtypes" )
688            private static String discoverJdkRequirementFromPlugins( Map pluginsAsMap )
689            {
690                if ( pluginsAsMap == null )
691                {
692                    return null;
693                }
694    
695                String jdk = null;
696                String backupJdk = null;
697                for ( Iterator it = pluginsAsMap.keySet().iterator(); it.hasNext(); )
698                {
699                    String key = it.next().toString();
700    
701                    if ( !key.equals( "org.apache.maven.plugins:maven-compiler-plugin" ) )
702                    {
703                        continue;
704                    }
705    
706                    Object value = pluginsAsMap.get( key );
707                    Xpp3Dom pluginConf = null;
708    
709                    backupJdk = "Default version for maven-compiler-plugin";
710                    if ( value instanceof Plugin )
711                    {
712                        Plugin plugin = (Plugin) value;
713                        backupJdk = "Default target for maven-compiler-plugin version " + plugin.getVersion();
714                        pluginConf = (Xpp3Dom) plugin.getConfiguration();
715                    }
716    
717                    if ( value instanceof ReportPlugin )
718                    {
719                        ReportPlugin reportPlugin = (ReportPlugin) value;
720                        backupJdk = "Default target for maven-compiler-plugin version " + reportPlugin.getVersion();
721                        pluginConf = (Xpp3Dom) reportPlugin.getConfiguration();
722                    }
723    
724                    if ( pluginConf == null )
725                    {
726                        continue;
727                    }
728    
729                    if ( pluginConf.getChild( "target" ) == null )
730                    {
731                        continue;
732                    }
733    
734                    jdk = pluginConf.getChild( "target" ).getValue();
735                }
736    
737                if ( jdk == null )
738                {
739                    return backupJdk;
740                }
741                else
742                {
743                    return jdk;
744                }
745            }
746        }
747    }