001    package org.apache.maven.lifecycle.internal;
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.execution.MavenSession;
023    import org.apache.maven.execution.ProjectDependencyGraph;
024    import org.apache.maven.lifecycle.MavenExecutionPlan;
025    import org.apache.maven.plugin.MojoExecution;
026    import org.apache.maven.plugin.descriptor.MojoDescriptor;
027    import org.apache.maven.project.MavenProject;
028    import org.codehaus.plexus.component.annotations.Component;
029    import org.codehaus.plexus.component.annotations.Requirement;
030    import org.codehaus.plexus.logging.Logger;
031    import org.codehaus.plexus.util.StringUtils;
032    
033    import java.util.Iterator;
034    import java.util.List;
035    import java.util.Map;
036    import java.util.Set;
037    import java.util.TreeSet;
038    
039    /**
040     * Logs debug output from the various lifecycle phases.
041     * 
042     * @since 3.0
043     * @author Benjamin Bentmann
044     * @author Jason van Zyl
045     * @author Kristian Rosenvold (extracted class only)
046     *         <p/>
047     *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
048     */
049    @Component( role = LifecycleDebugLogger.class )
050    public class LifecycleDebugLogger
051    {
052        @Requirement
053        private Logger logger;
054    
055    
056        @SuppressWarnings( { "UnusedDeclaration" } )
057        public LifecycleDebugLogger()
058        {
059        }
060    
061        public LifecycleDebugLogger( Logger logger )
062        {
063            this.logger = logger;
064        }
065    
066    
067        public void debug( String s )
068        {
069            logger.debug( s );
070        }
071    
072        public void info( String s )
073        {
074            logger.info( s );
075        }
076    
077        public void debugReactorPlan( ProjectBuildList projectBuilds )
078        {
079            if ( !logger.isDebugEnabled() )
080            {
081                return;
082            }
083    
084            logger.debug( "=== REACTOR BUILD PLAN ================================================" );
085    
086            for ( Iterator<ProjectSegment> it = projectBuilds.iterator(); it.hasNext(); )
087            {
088                ProjectSegment projectBuild = it.next();
089    
090                logger.debug( "Project: " + projectBuild.getProject().getId() );
091                logger.debug( "Tasks:   " + projectBuild.getTaskSegment().getTasks() );
092                logger.debug( "Style:   " + ( projectBuild.getTaskSegment().isAggregating() ? "Aggregating" : "Regular" ) );
093    
094                if ( it.hasNext() )
095                {
096                    logger.debug( "-----------------------------------------------------------------------" );
097                }
098            }
099    
100            logger.debug( "=======================================================================" );
101        }
102    
103    
104        public void debugProjectPlan( MavenProject currentProject, MavenExecutionPlan executionPlan )
105        {
106            if ( !logger.isDebugEnabled() )
107            {
108                return;
109            }
110    
111            logger.debug( "=== PROJECT BUILD PLAN ================================================" );
112            logger.debug( "Project:       " + BuilderCommon.getKey( currentProject ) );
113    
114            debugDependencyRequirements( executionPlan.getMojoExecutions() );
115    
116            logger.debug( "Repositories (dependencies): " + currentProject.getRemoteProjectRepositories() );
117            logger.debug( "Repositories (plugins)     : " + currentProject.getRemotePluginRepositories() );
118    
119            for ( ExecutionPlanItem mojoExecution : executionPlan )
120            {
121                debugMojoExecution( mojoExecution.getMojoExecution() );
122            }
123    
124            logger.debug( "=======================================================================" );
125        }
126    
127        private void debugMojoExecution( MojoExecution mojoExecution )
128        {
129            String mojoExecId =
130                mojoExecution.getGroupId() + ':' + mojoExecution.getArtifactId() + ':' + mojoExecution.getVersion() + ':'
131                    + mojoExecution.getGoal() + " (" + mojoExecution.getExecutionId() + ')';
132    
133            Map<String, List<MojoExecution>> forkedExecutions = mojoExecution.getForkedExecutions();
134            if ( !forkedExecutions.isEmpty() )
135            {
136                for ( Map.Entry<String, List<MojoExecution>> fork : forkedExecutions.entrySet() )
137                {
138                    logger.debug( "--- init fork of " + fork.getKey() + " for " + mojoExecId + " ---" );
139    
140                    debugDependencyRequirements( fork.getValue() );
141    
142                    for ( MojoExecution forkedExecution : fork.getValue() )
143                    {
144                        debugMojoExecution( forkedExecution );
145                    }
146    
147                    logger.debug( "--- exit fork of " + fork.getKey() + " for " + mojoExecId + " ---" );
148                }
149            }
150    
151            logger.debug( "-----------------------------------------------------------------------" );
152            logger.debug( "Goal:          " + mojoExecId );
153            logger.debug(
154                "Style:         " + ( mojoExecution.getMojoDescriptor().isAggregator() ? "Aggregating" : "Regular" ) );
155            logger.debug( "Configuration: " + mojoExecution.getConfiguration() );
156        }
157    
158        private void debugDependencyRequirements( List<MojoExecution> mojoExecutions )
159        {
160            Set<String> scopesToCollect = new TreeSet<String>();
161            Set<String> scopesToResolve = new TreeSet<String>();
162    
163            for ( MojoExecution mojoExecution : mojoExecutions )
164            {
165                MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
166    
167                String scopeToCollect = mojoDescriptor.getDependencyCollectionRequired();
168                if ( StringUtils.isNotEmpty( scopeToCollect ) )
169                {
170                    scopesToCollect.add( scopeToCollect );
171                }
172    
173                String scopeToResolve = mojoDescriptor.getDependencyResolutionRequired();
174                if ( StringUtils.isNotEmpty( scopeToResolve ) )
175                {
176                    scopesToResolve.add( scopeToResolve );
177                }
178            }
179    
180            logger.debug( "Dependencies (collect): " + scopesToCollect );
181            logger.debug( "Dependencies (resolve): " + scopesToResolve );
182        }
183    
184        public void logWeavePlan( MavenSession session )
185        {
186            if ( !logger.isInfoEnabled() )
187            {
188                return;
189            }
190    
191            final ProjectDependencyGraph dependencyGraph = session.getProjectDependencyGraph();
192            logger.info( "=== WEAVE CONCURRENCY BUILD PLAN ======================================" );
193            for ( MavenProject mavenProject : dependencyGraph.getSortedProjects() )
194            {
195    
196                StringBuilder item = new StringBuilder();
197                item.append( "Project: " );
198                item.append( mavenProject.getArtifactId() );
199                final List<MavenProject> upstreamProjects = dependencyGraph.getUpstreamProjects( mavenProject, false );
200                if ( upstreamProjects.size() > 0 )
201                {
202                    item.append( " ( " );
203                    for ( Iterator<MavenProject> it = upstreamProjects.iterator(); it.hasNext(); )
204                    {
205                        final MavenProject kid = it.next();
206                        item.append( kid.getArtifactId() );
207                        if ( it.hasNext() )
208                        {
209                            item.append( ", " );
210                        }
211                    }
212                    item.append( ")" );
213                }
214                logger.info( item.toString() );
215    
216            }
217            logger.info( "=======================================================================" );
218        }
219    }