View Javadoc

1   package org.apache.maven.plugin.changelog;
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.doxia.sink.Sink;
23  import org.apache.maven.scm.ChangeFile;
24  import org.apache.maven.scm.ChangeSet;
25  import org.apache.maven.scm.command.changelog.ChangeLogSet;
26  
27  import java.util.Collection;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.LinkedList;
31  import java.util.List;
32  import java.util.Locale;
33  import java.util.ResourceBundle;
34  
35  /**
36   * Generate a developer activity report.
37   *
38   * @version $Id: DeveloperActivityReport.java 939126 2010-04-28 22:52:04Z dennisl $
39   * @goal dev-activity
40   */
41  public class DeveloperActivityReport
42      extends ChangeLogReport
43  {
44      /**
45       * Used to hold data while creating the report
46       */
47      private HashMap commits;
48  
49      private HashMap files;
50  
51      /** {@inheritDoc} */
52      public String getDescription( Locale locale )
53      {
54          return getBundle( locale ).getString( "report.dev-activity.description" );
55      }
56  
57      /** {@inheritDoc} */
58      public String getName( Locale locale )
59      {
60          return getBundle( locale ).getString( "report.dev-activity.name" );
61      }
62  
63      /** {@inheritDoc} */
64      public String getOutputName()
65      {
66          return "dev-activity";
67      }
68  
69      /** {@inheritDoc} */
70      protected void doGenerateEmptyReport( ResourceBundle bundle, Sink sink )
71      {
72          sink.head();
73          sink.title();
74          sink.text( bundle.getString( "report.dev-activity.header" ) );
75          sink.title_();
76          sink.head_();
77  
78          sink.body();
79          sink.section1();
80  
81          sink.sectionTitle1();
82          sink.text( bundle.getString( "report.dev-activity.mainTitle" ) );
83          sink.sectionTitle1_();
84  
85          sink.paragraph();
86          sink.text( "No sources found to create a report." );
87          sink.paragraph_();
88  
89          sink.section1_();
90  
91          sink.body_();
92          sink.flush();
93          sink.close();
94      }
95  
96      /** {@inheritDoc} */
97      protected void doGenerateReport( List changeLogSets, ResourceBundle bundle, Sink sink )
98      {
99          sink.head();
100         sink.title();
101         sink.text( bundle.getString( "report.dev-activity.header" ) );
102         sink.title_();
103         sink.head_();
104 
105         sink.body();
106         sink.section1();
107         sink.sectionTitle1();
108         sink.text( bundle.getString( "report.dev-activity.mainTitle" ) );
109         sink.sectionTitle1_();
110 
111         if ( developers.isEmpty() )
112         {
113             sink.paragraph();
114             sink.text( bundle.getString( "report.dev-activity.noDevelopers" ) );
115             sink.paragraph_();
116         }
117         else
118         {
119             for ( Iterator sets = changeLogSets.iterator(); sets.hasNext(); )
120             {
121                 ChangeLogSet set = (ChangeLogSet) sets.next();
122                 doChangedSets( set, bundle, sink );
123             }
124         }
125 
126         sink.section1_();
127         sink.body_();
128         sink.flush();
129         sink.close();
130     }
131 
132     /**
133      * generates a section of the report referring to a changeset
134      *
135      * @param set    the current ChangeSet to generate this section of the report
136      * @param bundle the resource bundle to retrieve report phrases from
137      * @param sink   the report formatting tool
138      */
139     private void doChangedSets( ChangeLogSet set, ResourceBundle bundle, Sink sink )
140     {
141         sink.section2();
142 
143         doChangeSetTitle( set, bundle, sink );
144 
145         doSummary( set, bundle, sink );
146 
147         sink.table();
148 
149         sink.tableRow();
150         sink.tableHeaderCell();
151         sink.text( bundle.getString( "report.dev-activity.developer" ) );
152         sink.tableHeaderCell_();
153         sink.tableHeaderCell();
154         sink.text( bundle.getString( "report.TotalCommits" ) );
155         sink.tableHeaderCell_();
156         sink.tableHeaderCell();
157         sink.text( bundle.getString( "report.dev-activity.filesChanged" ) );
158         sink.tableHeaderCell_();
159         sink.tableRow_();
160 
161         doDeveloperRows( set, sink );
162 
163         sink.table_();
164 
165         sink.section2_();
166     }
167 
168     /**
169      * generates the report section table of the developers
170      *
171      * @param set  change log set generate the developer activity
172      * @param sink the report formatting tool
173      */
174     private void doDeveloperRows( ChangeLogSet set, Sink sink )
175     {
176         initDeveloperDetails( set );
177 
178         for( Iterator i = commits.keySet().iterator(); i.hasNext(); )
179         {
180             String author = (String) i.next();
181 
182             LinkedList devCommits = (LinkedList) commits.get( author );
183             HashMap devFiles = (HashMap) files.get( author );
184 
185             sink.tableRow();
186             sink.tableCell();
187 
188             sinkAuthorDetails( sink, author );
189 
190             sink.tableCell_();
191 
192             sink.tableCell();
193             sink.text( "" + devCommits.size() );
194             sink.tableCell_();
195 
196             sink.tableCell();
197             sink.text( "" + devFiles.size() );
198             sink.tableCell_();
199 
200             sink.tableRow_();
201         }
202     }
203 
204     /**
205      * counts the number of commits and files changed for each developer
206      *
207      * @param set the change log set to generate the developer details from
208      */
209     private void initDeveloperDetails( ChangeLogSet set )
210     {
211         commits = new HashMap();
212 
213         files = new HashMap();
214 
215         countDevCommits( set.getChangeSets() );
216 
217         countDevFiles( set.getChangeSets() );
218     }
219 
220     /**
221      * counts the number of commits of each developer
222      *
223      * @param entries the change log entries used to search and count developer commits
224      */
225     private void countDevCommits( Collection entries )
226     {
227         for ( Iterator i = entries.iterator(); i.hasNext(); )
228         {
229             ChangeSet entry = (ChangeSet) i.next();
230 
231             String developer = entry.getAuthor();
232 
233             LinkedList list;
234 
235             if ( commits.containsKey( developer ) )
236             {
237                 list = (LinkedList) commits.get( developer );
238             }
239             else
240             {
241                 list = new LinkedList();
242             }
243 
244             list.add( entry );
245 
246             commits.put( developer, list );
247         }
248     }
249 
250     /**
251      * counts the number of files changed by each developer
252      *
253      * @param entries the change log entries used to search and count file changes
254      */
255     private void countDevFiles( Collection entries )
256     {
257         for ( Iterator i2 = entries.iterator(); i2.hasNext(); )
258         {
259             ChangeSet entry = (ChangeSet) i2.next();
260 
261             String developer = entry.getAuthor();
262 
263             HashMap filesMap;
264 
265             if ( files.containsKey( developer ) )
266             {
267                 filesMap = (HashMap) files.get( developer );
268             }
269             else
270             {
271                 filesMap = new HashMap();
272             }
273 
274             for ( Iterator i3 = entry.getFiles().iterator(); i3.hasNext(); )
275             {
276                 ChangeFile file = (ChangeFile) i3.next();
277 
278                 filesMap.put( file.getName(), file );
279             }
280 
281             files.put( developer, filesMap );
282         }
283     }
284 }