001package 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
022import org.apache.maven.project.MavenProject;
023
024import java.util.ArrayList;
025import java.util.Collections;
026import java.util.List;
027
028/**
029 * @since 3.0
030 * @author Kristian Rosenvold
031 *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
032 */
033public class BuildLogItem
034{
035    private final ExecutionPlanItem executionPlanItem;
036
037    private final MavenProject project;
038
039    private final long startTime;
040
041    private long endTime;
042
043    private final List<DependencyLogEntry> dependencies =
044        Collections.synchronizedList( new ArrayList<DependencyLogEntry>() );
045
046    public BuildLogItem( MavenProject project, ExecutionPlanItem executionPlanItem )
047    {
048        this.executionPlanItem = executionPlanItem;
049        this.project = project;
050        startTime = System.currentTimeMillis();
051
052    }
053
054
055    public MavenProject getProject()
056    {
057        return project;
058    }
059
060    public void setComplete()
061    {
062        endTime = System.currentTimeMillis();
063    }
064
065    public void addWait( MavenProject upstreamProject, ExecutionPlanItem inSchedule, long startWait )
066    {
067        long now = System.currentTimeMillis();
068        dependencies.add( new DependencyLogEntry( upstreamProject, inSchedule, startWait, now, null ) );
069    }
070
071    public void addDependency( MavenProject upstreamProject, String message )
072    {
073        dependencies.add( new DependencyLogEntry( upstreamProject, message ) );
074    }
075
076    public String toString( long rootStart )
077    {
078        StringBuilder result = new StringBuilder();
079        result.append( String.format( "%1d  %2d ", startTime - rootStart, endTime - rootStart ) );
080        result.append( project.getName() );
081        result.append( " " );
082        result.append( getMojoExecutionDescription( executionPlanItem ) );
083        if ( dependencies.size() > 0 )
084        {
085            result.append( "\n" );
086            for ( DependencyLogEntry waitLogEntry : dependencies )
087            {
088                result.append( "    " );
089                result.append( waitLogEntry.toString() );
090                result.append( "\n" );
091            }
092        }
093        return result.toString();
094    }
095
096
097    public Object toGraph( long rootStart )
098    {
099        StringBuilder result = new StringBuilder();
100        if ( dependencies.size() > 0 )
101        {
102            for ( DependencyLogEntry waitLogEntry : dependencies )
103            {
104                result.append( "        " );
105                result.append( nodeKey( project, executionPlanItem ) );
106                result.append( " ->   " );
107                result.append( waitLogEntry.toNodeKey() );
108                result.append( waitLogEntry.toNodeDescription( rootStart ) );
109                result.append( "\n" );
110            }
111        }
112        else
113        {
114            result.append( "        " );
115            result.append( nodeKey( project, executionPlanItem ) );
116            result.append( "\n" );
117        }
118        return result.toString();
119    }
120
121    private static String nodeKey( MavenProject mavenProject, ExecutionPlanItem executionPlanItem )
122    {
123        String key = mavenProject.getArtifactId();
124        if ( executionPlanItem != null )
125        {
126            key += "_" + getMojoExecutionDescription( executionPlanItem );
127        }
128        return key.replace( ".", "_" ).replace( ":", "_" );
129    }
130
131    private static String getMojoExecutionDescription( ExecutionPlanItem executionPlanItem )
132    {
133        if ( executionPlanItem.getMojoExecution() != null )
134        {
135            return executionPlanItem.getMojoExecution().getArtifactId() + getLifeCyclePhase( executionPlanItem );
136        }
137        else
138        {
139            return "";
140        }
141    }
142
143    private static String getLifeCyclePhase( ExecutionPlanItem executionPlanItem )
144    {
145        return executionPlanItem.getLifecyclePhase() != null ? "[" + executionPlanItem.getLifecyclePhase() + "]" : "";
146    }
147
148
149    class DependencyLogEntry
150    {
151        private final ExecutionPlanItem executionPlanItem;
152
153        private final MavenProject upstreamProject;
154
155        private final Long start;
156
157        private final Long stop;
158
159        private final String message;
160
161        DependencyLogEntry( MavenProject upstreamProject, ExecutionPlanItem executionPlanItem, Long start, Long stop,
162                            String message )
163        {
164            this.upstreamProject = upstreamProject;
165            this.executionPlanItem = executionPlanItem;
166            this.start = start;
167            this.stop = stop;
168            this.message = message;
169        }
170
171        DependencyLogEntry( MavenProject upstreamProject, String message )
172        {
173            this( upstreamProject, null, null, null, message );
174        }
175
176        public String toString()
177        {
178            return upstreamProject.getName() + ":" + getExecutionPlanItem() + getElapsed() + getMessage();
179        }
180
181        public String toNodeKey()
182        {
183            return nodeKey( upstreamProject, executionPlanItem );
184        }
185
186        public String toNodeDescription( long rootStart )
187        {
188            return "";
189        }
190
191
192        private String getMessage()
193        {
194            return message != null ? message : "";
195        }
196
197        private String getExecutionPlanItem()
198        {
199            if ( executionPlanItem != null )
200            {
201                return getMojoExecutionDescription( executionPlanItem );
202            }
203            else
204            {
205                return "";
206            }
207        }
208
209        private String getElapsed()
210        {
211            if ( start != null && stop != null )
212            {
213                long elapsed = stop - start;
214                return elapsed > 0 ? ", wait=" + elapsed : "";
215            }
216            return "";
217        }
218    }
219
220}