1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.plugins.changes.jira;
20  
21  import javax.inject.Inject;
22  
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Locale;
26  import java.util.Map;
27  import java.util.ResourceBundle;
28  
29  import org.apache.commons.lang3.StringUtils;
30  import org.apache.maven.plugins.annotations.Mojo;
31  import org.apache.maven.plugins.annotations.Parameter;
32  import org.apache.maven.plugins.changes.AbstractChangesReport;
33  import org.apache.maven.plugins.changes.ProjectUtils;
34  import org.apache.maven.plugins.changes.issues.Issue;
35  import org.apache.maven.plugins.changes.issues.IssueUtils;
36  import org.apache.maven.plugins.changes.issues.IssuesReportHelper;
37  import org.apache.maven.plugins.changes.issues.IssuesReportRenderer;
38  import org.apache.maven.reporting.MavenReportException;
39  import org.apache.maven.settings.Settings;
40  import org.apache.maven.settings.crypto.SettingsDecrypter;
41  
42  
43  
44  
45  
46  
47  
48  @Mojo(name = "jira-changes", threadSafe = true)
49  public class JiraChangesReport extends AbstractChangesReport {
50      
51  
52  
53      private static final Map<String, Integer> JIRA_COLUMNS = new HashMap<>(16);
54  
55      static {
56          JIRA_COLUMNS.put("Assignee", IssuesReportHelper.COLUMN_ASSIGNEE);
57          JIRA_COLUMNS.put("Component", IssuesReportHelper.COLUMN_COMPONENT);
58          JIRA_COLUMNS.put("Created", IssuesReportHelper.COLUMN_CREATED);
59          JIRA_COLUMNS.put("Fix Version", IssuesReportHelper.COLUMN_FIX_VERSION);
60          JIRA_COLUMNS.put("Id", IssuesReportHelper.COLUMN_ID);
61          JIRA_COLUMNS.put("Key", IssuesReportHelper.COLUMN_KEY);
62          JIRA_COLUMNS.put("Priority", IssuesReportHelper.COLUMN_PRIORITY);
63          JIRA_COLUMNS.put("Reporter", IssuesReportHelper.COLUMN_REPORTER);
64          JIRA_COLUMNS.put("Resolution", IssuesReportHelper.COLUMN_RESOLUTION);
65          JIRA_COLUMNS.put("Status", IssuesReportHelper.COLUMN_STATUS);
66          JIRA_COLUMNS.put("Summary", IssuesReportHelper.COLUMN_SUMMARY);
67          JIRA_COLUMNS.put("Type", IssuesReportHelper.COLUMN_TYPE);
68          JIRA_COLUMNS.put("Updated", IssuesReportHelper.COLUMN_UPDATED);
69          JIRA_COLUMNS.put("Version", IssuesReportHelper.COLUMN_VERSION);
70      }
71  
72      
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83      @Parameter(defaultValue = "Key,Summary,Status,Resolution,Assignee")
84      private String columnNames;
85  
86      
87  
88  
89  
90  
91  
92      @Deprecated
93      @Parameter(property = "changes.useJql", defaultValue = "false")
94      private boolean useJql;
95  
96      
97  
98  
99  
100     @Parameter
101     private String component;
102 
103     
104 
105 
106 
107     @Parameter()
108     private String filter;
109 
110     
111 
112 
113 
114 
115 
116 
117     @Parameter
118     private String fixVersionIds;
119 
120     
121 
122 
123 
124 
125     @Parameter(defaultValue = "EEE, d MMM yyyy HH:mm:ss Z")
126     private String jiraDatePattern;
127 
128     
129 
130 
131     @Parameter
132     private String jiraPassword;
133 
134     
135 
136 
137     @Parameter
138     private String jiraUser;
139 
140     
141 
142 
143 
144 
145     @Parameter(property = "changes.jiraServerId")
146     private String jiraServerId;
147 
148     
149 
150 
151     @Parameter(defaultValue = "100")
152     private int maxEntries;
153 
154     
155 
156 
157 
158 
159 
160     @Parameter(defaultValue = "false")
161     private boolean onlyCurrentVersion;
162 
163     
164 
165 
166 
167 
168     @Parameter
169     private String priorityIds;
170 
171     
172 
173 
174 
175 
176 
177 
178 
179     @Parameter(defaultValue = "Fixed")
180     private String resolutionIds;
181 
182     
183 
184 
185     @Parameter(defaultValue = "${settings}", readonly = true, required = true)
186     private Settings settings;
187 
188     
189 
190 
191 
192 
193     @Parameter(property = "changes.jira.skip", defaultValue = "false")
194     private boolean skip;
195 
196     
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216     @Parameter(defaultValue = "Priority DESC, Created DESC")
217     private String sortColumnNames;
218 
219     
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233     @Parameter(defaultValue = "Closed")
234     private String statusIds;
235 
236     
237 
238 
239 
240 
241 
242 
243 
244     @Parameter
245     private String typeIds;
246 
247     
248 
249 
250 
251 
252 
253 
254 
255 
256 
257     @Parameter
258     private String versionPrefix;
259 
260     
261 
262 
263 
264 
265     @Deprecated
266     @Parameter
267     private String webPassword;
268 
269     
270 
271 
272 
273 
274     @Deprecated
275     @Parameter
276     private String webUser;
277 
278     
279 
280 
281     private RestJiraDownloader mockDownloader;
282 
283     
284 
285 
286     private final SettingsDecrypter settingsDecrypter;
287 
288     @Inject
289     public JiraChangesReport(SettingsDecrypter settingsDecrypter) {
290         this.settingsDecrypter = settingsDecrypter;
291     }
292 
293     
294     
295     
296 
297     
298 
299 
300     @Override
301     public boolean canGenerateReport() {
302         
303         if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) {
304             getLog().info("Skipping the JIRA Report in this project because it's not the Execution Root");
305             return false;
306         }
307         if (skip) {
308             return false;
309         }
310         if (mockDownloader != null) {
311             return true;
312         }
313         String message = ProjectUtils.validateIssueManagement(project, "JIRA", "JIRA Report");
314         if (message != null) {
315             getLog().warn(message);
316         }
317         return message == null;
318     }
319 
320     @Override
321     public void executeReport(Locale locale) throws MavenReportException {
322         
323         List<Integer> columnIds = IssuesReportHelper.getColumnIds(columnNames, JIRA_COLUMNS);
324         if (columnIds.isEmpty()) {
325             
326             throw new MavenReportException(
327                     "maven-changes-plugin: None of the configured columnNames '" + columnNames + "' are valid.");
328         }
329 
330         try {
331             
332             RestJiraDownloader issueDownloader;
333             if (mockDownloader != null) {
334                 issueDownloader = mockDownloader;
335             } else {
336                 issueDownloader = new RestJiraDownloader();
337             }
338             configureIssueDownloader(issueDownloader);
339             issueDownloader.doExecute();
340 
341             List<Issue> issueList = issueDownloader.getIssueList();
342 
343             if (StringUtils.isNotEmpty(versionPrefix)) {
344                 int originalNumberOfIssues = issueList.size();
345                 issueList = IssueUtils.filterIssuesWithVersionPrefix(issueList, versionPrefix);
346                 getLog().debug("Filtered out " + issueList.size() + " issues of " + originalNumberOfIssues
347                         + " that matched the versionPrefix '" + versionPrefix + "'.");
348             }
349 
350             if (onlyCurrentVersion) {
351                 String version = (versionPrefix == null ? "" : versionPrefix) + project.getVersion();
352                 issueList = IssueUtils.getIssuesForVersion(issueList, version);
353                 getLog().info("The JIRA Report will contain issues only for the current version.");
354             }
355 
356             
357             IssuesReportRenderer report = new IssuesReportRenderer(getSink(), getBundle(locale), columnIds, issueList);
358             report.render();
359 
360         } catch (Exception e) {
361             getLog().warn(e);
362         }
363     }
364 
365     @Override
366     public String getDescription(Locale locale) {
367         return getBundle(locale).getString("report.issues.description");
368     }
369 
370     @Override
371     public String getName(Locale locale) {
372         return getBundle(locale).getString("report.issues.name");
373     }
374 
375     @Override
376     @Deprecated
377     public String getOutputName() {
378         return "jira-changes";
379     }
380 
381     
382     
383     
384 
385     private ResourceBundle getBundle(Locale locale) {
386         return ResourceBundle.getBundle("jira-report", locale, this.getClass().getClassLoader());
387     }
388 
389     private void configureIssueDownloader(RestJiraDownloader issueDownloader) {
390         issueDownloader.setLog(getLog());
391 
392         issueDownloader.setMavenProject(project);
393 
394         issueDownloader.setNbEntries(maxEntries);
395 
396         issueDownloader.setComponent(component);
397 
398         issueDownloader.setFixVersionIds(fixVersionIds);
399 
400         issueDownloader.setStatusIds(statusIds);
401 
402         issueDownloader.setResolutionIds(resolutionIds);
403 
404         issueDownloader.setPriorityIds(priorityIds);
405 
406         issueDownloader.setSortColumnNames(sortColumnNames);
407 
408         issueDownloader.setFilter(filter);
409 
410         issueDownloader.setJiraDatePattern(jiraDatePattern);
411 
412         issueDownloader.setJiraServerId(jiraServerId);
413 
414         if (jiraUser != null) {
415             issueDownloader.setJiraUser(jiraUser);
416             issueDownloader.setJiraPassword(jiraPassword);
417         } else if (webUser != null) {
418             issueDownloader.setJiraUser(webUser);
419             issueDownloader.setJiraPassword(webPassword);
420         }
421 
422         issueDownloader.setTypeIds(typeIds);
423 
424         issueDownloader.setSettings(settings);
425         issueDownloader.setSettingsDecrypter(settingsDecrypter);
426 
427         issueDownloader.setOnlyCurrentVersion(onlyCurrentVersion);
428 
429         issueDownloader.setVersionPrefix(versionPrefix);
430     }
431 
432     public void setMockDownloader(RestJiraDownloader mockDownloader) {
433         this.mockDownloader = mockDownloader;
434     }
435 }