1 package org.apache.maven.plugin.jira;
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.plugin.MojoExecutionException;
23 import org.apache.maven.plugin.issues.Issue;
24 import org.apache.maven.plugin.issues.IssueUtils;
25 import org.apache.maven.plugin.logging.Log;
26 import org.apache.maven.project.MavenProject;
27 import org.apache.maven.settings.Proxy;
28 import org.apache.maven.settings.Settings;
29 import org.apache.maven.wagon.proxy.ProxyInfo;
30
31 import java.io.File;
32 import java.net.MalformedURLException;
33 import java.net.URL;
34 import java.util.List;
35
36 /**
37 * Abstract API, more or less, to retrieving issue information from JIRA.
38 * Intended to have subclasses for the old (RSS) and new (REST) ways of doing things.
39 *
40 * @author mfranken@xebia.com
41 * @author jruiz@exist.com
42 * @version $Id: AbstractJiraDownloader.java 1412155 2012-11-21 15:47:19Z bimargulies $
43 */
44 public abstract class AbstractJiraDownloader
45 {
46 protected static final String UTF_8 = "UTF-8";
47
48 /** Log for debug output. */
49 protected Log log;
50 /** Output file for xml document. */
51 protected File output;
52 /** The maximum number of entries to show. */
53 protected int nbEntriesMax;
54 /** The filter to apply to query to JIRA. */
55 protected String filter;
56 /** Ids of fix versions to show, as comma separated string. */
57 protected String fixVersionIds;
58 /** Ids of status to show, as comma separated string. */
59 protected String statusIds;
60 /** Ids of resolution to show, as comma separated string. */
61 protected String resolutionIds;
62 /** Ids of priority to show, as comma separated string. */
63 protected String priorityIds;
64 /** The component to show. */
65 protected String component;
66 /** Ids of types to show, as comma separated string. */
67 protected String typeIds;
68 /** Column names to sort by, as comma separated string. */
69 protected String sortColumnNames;
70 /** The username to log into JIRA. */
71 protected String jiraUser;
72 /** The password to log into JIRA. */
73 protected String jiraPassword;
74 /** The username to log into webserver. */
75 protected String webUser;
76 /** The password to log into webserver. */
77 protected String webPassword;
78 /** The maven project. */
79 protected MavenProject project;
80 /** The maven settings. */
81 protected Settings settings;
82 /** Use JQL, JIRA query language, instead of URL parameter based queries.
83 * Note that this is down here to make it easier for the mojo to deal with
84 * both new and old flavors. */
85 protected boolean useJql;
86 /** Filter the JIRA query based on the current version */
87 protected boolean onlyCurrentVersion;
88 /** The versionPrefix to apply to the POM version */
89 protected String versionPrefix;
90 /** The pattern used to parse dates from the JIRA xml file. */
91 protected String jiraDatePattern;
92 protected String proxyHost;
93 protected int proxyPort;
94 protected String proxyUser;
95 protected String proxyPass;
96
97 /**
98 * Execute the query on the JIRA server.
99 *
100 * @throws Exception on error
101 */
102 public abstract void doExecute() throws Exception;
103
104
105 /**
106 * Check to see if we think that JIRA authentication is needed.
107 *
108 * @return <code>true</code> if jiraUser and jiraPassword are set, otherwise <code>false</code>
109 */
110 protected boolean isJiraAuthenticationConfigured()
111 {
112 return ( jiraUser != null ) && ( jiraUser.length() > 0 ) && ( jiraPassword != null );
113 }
114
115
116 protected void getProxyInfo( String jiraUrl )
117 {
118 // see whether there is any proxy defined in maven
119 Proxy proxy = null;
120
121 if ( project == null )
122 {
123 getLog().error( "No project set. No proxy info available." );
124
125 return;
126 }
127
128 if ( settings != null )
129 {
130 proxy = settings.getActiveProxy();
131 }
132
133 if ( proxy != null )
134 {
135
136 ProxyInfo proxyInfo = new ProxyInfo();
137 proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
138
139 // Get the host out of the JIRA URL
140 URL url = null;
141 try
142 {
143 url = new URL( jiraUrl );
144 }
145 catch( MalformedURLException e )
146 {
147 getLog().error( "Invalid JIRA URL: " + jiraUrl + ". " + e.getMessage() );
148 }
149 String jiraHost = null;
150 if ( url != null )
151 {
152 jiraHost = url.getHost();
153 }
154
155 // Validation of proxy method copied from org.apache.maven.wagon.proxy.ProxyUtils.
156 // @todo Can use original when maven-changes-plugin requires a more recent version of Maven
157
158 //if ( ProxyUtils.validateNonProxyHosts( proxyInfo, jiraHost ) )
159 if ( JiraHelper.validateNonProxyHosts( proxyInfo, jiraHost ) )
160 {
161 return;
162 }
163
164 proxyHost = settings.getActiveProxy().getHost();
165 proxyPort = settings.getActiveProxy().getPort();
166 proxyUser = settings.getActiveProxy().getUsername();
167 proxyPass = settings.getActiveProxy().getPassword();
168 }
169 }
170
171 /**
172 * Override this method if you need to get issues for a specific Fix For.
173 *
174 * @return A Fix For id or <code>null</code> if you don't have that need
175 */
176 protected String getFixFor()
177 {
178 if ( onlyCurrentVersion && useJql )
179 {
180 // Let JIRA do the filtering of the current version instead of the JIRA mojo.
181 // This way JIRA returns less issues and we do not run into the "nbEntriesMax" limit that easily.
182
183 String version = ( versionPrefix == null ? "" : versionPrefix ) + project.getVersion();
184
185 // Remove "-SNAPSHOT" from the end of the version, if it's there
186 if ( version.endsWith( IssueUtils.SNAPSHOT_SUFFIX ) )
187 {
188 return version.substring( 0, version.length() - IssueUtils.SNAPSHOT_SUFFIX.length() );
189 }
190 else
191 {
192 return version;
193 }
194 }
195 else
196 {
197 return null;
198 }
199 }
200
201
202 public abstract List<Issue> getIssueList() throws MojoExecutionException;
203
204 public void setJiraDatePattern( String jiraDatePattern )
205 {
206 this.jiraDatePattern = jiraDatePattern;
207 }
208
209 /**
210 * Set the output file for the log.
211 *
212 * @param thisOutput the output file
213 */
214 public void setOutput( File thisOutput )
215 {
216 this.output = thisOutput;
217 }
218
219 public File getOutput()
220 {
221 return this.output;
222 }
223
224 /**
225 * Sets the project.
226 *
227 * @param thisProject The project to set
228 */
229 public void setMavenProject( Object thisProject )
230 {
231 this.project = (MavenProject) thisProject;
232 }
233
234 /**
235 * Sets the maximum number of Issues to show.
236 *
237 * @param nbEntries The maximum number of Issues
238 */
239 public void setNbEntries( final int nbEntries )
240 {
241 nbEntriesMax = nbEntries;
242 }
243
244 /**
245 * Sets the statusIds.
246 *
247 * @param thisStatusIds The id(s) of the status to show, as comma separated string
248 */
249 public void setStatusIds( String thisStatusIds )
250 {
251 statusIds = thisStatusIds;
252 }
253
254 /**
255 * Sets the priorityIds.
256 *
257 * @param thisPriorityIds The id(s) of the priority to show, as comma separated string
258 */
259 public void setPriorityIds( String thisPriorityIds )
260 {
261 priorityIds = thisPriorityIds;
262 }
263
264 /**
265 * Sets the resolutionIds.
266 *
267 * @param thisResolutionIds The id(s) of the resolution to show, as comma separated string
268 */
269 public void setResolutionIds( String thisResolutionIds )
270 {
271 resolutionIds = thisResolutionIds;
272 }
273
274 /**
275 * Sets the sort column names.
276 *
277 * @param thisSortColumnNames The column names to sort by
278 */
279 public void setSortColumnNames( String thisSortColumnNames )
280 {
281 sortColumnNames = thisSortColumnNames;
282 }
283
284 /**
285 * Sets the password for authentication against the webserver.
286 *
287 * @param thisWebPassword The password of the webserver
288 */
289 public void setWebPassword( String thisWebPassword )
290 {
291 this.webPassword = thisWebPassword;
292 }
293
294 /**
295 * Sets the username for authentication against the webserver.
296 *
297 * @param thisWebUser The username of the webserver
298 */
299 public void setWebUser( String thisWebUser )
300 {
301 this.webUser = thisWebUser;
302 }
303
304 /**
305 * Sets the password to log into a secured JIRA.
306 *
307 * @param thisJiraPassword The password for JIRA
308 */
309 public void setJiraPassword( final String thisJiraPassword )
310 {
311 this.jiraPassword = thisJiraPassword;
312 }
313
314 /**
315 * Sets the username to log into a secured JIRA.
316 *
317 * @param thisJiraUser The username for JIRA
318 */
319 public void setJiraUser( String thisJiraUser )
320 {
321 this.jiraUser = thisJiraUser;
322 }
323
324 /**
325 * Sets the filter to apply to query to JIRA.
326 *
327 * @param thisFilter The filter to query JIRA
328 */
329 public void setFilter( String thisFilter )
330 {
331 this.filter = thisFilter;
332 }
333
334 /**
335 * Sets the component(s) to apply to query JIRA.
336 *
337 * @param theseComponents The id(s) of components to show, as comma separated string
338 */
339 public void setComponent( String theseComponents )
340 {
341 this.component = theseComponents;
342 }
343
344 /**
345 * Sets the fix version id(s) to apply to query JIRA.
346 *
347 * @param theseFixVersionIds The id(s) of fix versions to show, as comma separated string
348 */
349 public void setFixVersionIds( String theseFixVersionIds )
350 {
351 this.fixVersionIds = theseFixVersionIds;
352 }
353
354 /**
355 * Sets the typeIds.
356 *
357 * @param theseTypeIds The id(s) of the types to show, as comma separated string
358 */
359 public void setTypeIds( String theseTypeIds )
360 {
361 typeIds = theseTypeIds;
362 }
363
364 public void setLog( Log log )
365 {
366 this.log = log;
367 }
368
369 protected Log getLog()
370 {
371 return log;
372 }
373
374 public void setSettings( Settings settings )
375 {
376 this.settings = settings;
377 }
378
379 public boolean isUseJql()
380 {
381 return useJql;
382 }
383
384 public void setUseJql( boolean useJql )
385 {
386 this.useJql = useJql;
387 }
388
389 public boolean isOnlyCurrentVersion()
390 {
391 return onlyCurrentVersion;
392 }
393
394 public void setOnlyCurrentVersion( boolean onlyCurrentVersion )
395 {
396 this.onlyCurrentVersion = onlyCurrentVersion;
397 }
398
399 public String getVersionPrefix()
400 {
401 return versionPrefix;
402 }
403
404 public void setVersionPrefix( String versionPrefix )
405 {
406 this.versionPrefix = versionPrefix;
407 }
408 }