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