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 1626316 2014-09-19 19:57:39Z mfriedenhagen $
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 protected int connectionTimeout;
97 protected int receiveTimout;
98
99 /**
100 * Execute the query on the JIRA server.
101 *
102 * @throws Exception on error
103 */
104 public abstract void doExecute() throws Exception;
105
106
107 /**
108 * Check to see if we think that JIRA authentication is needed.
109 *
110 * @return <code>true</code> if jiraUser and jiraPassword are set, otherwise <code>false</code>
111 */
112 protected boolean isJiraAuthenticationConfigured()
113 {
114 return ( jiraUser != null ) && ( jiraUser.length() > 0 ) && ( jiraPassword != null );
115 }
116
117
118 protected void getProxyInfo( String jiraUrl )
119 {
120 // see whether there is any proxy defined in maven
121 Proxy proxy = null;
122
123 if ( project == null )
124 {
125 getLog().error( "No project set. No proxy info available." );
126
127 return;
128 }
129
130 if ( settings != null )
131 {
132 proxy = settings.getActiveProxy();
133 }
134
135 if ( proxy != null )
136 {
137
138 ProxyInfo proxyInfo = new ProxyInfo();
139 proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
140
141 // Get the host out of the JIRA URL
142 URL url = null;
143 try
144 {
145 url = new URL( jiraUrl );
146 }
147 catch ( MalformedURLException e )
148 {
149 getLog().error( "Invalid JIRA URL: " + jiraUrl + ". " + e.getMessage() );
150 }
151 String jiraHost = null;
152 if ( url != null )
153 {
154 jiraHost = url.getHost();
155 }
156
157 // Validation of proxy method copied from org.apache.maven.wagon.proxy.ProxyUtils.
158 // @todo Can use original when maven-changes-plugin requires a more recent version of Maven
159
160 //if ( ProxyUtils.validateNonProxyHosts( proxyInfo, jiraHost ) )
161 if ( JiraHelper.validateNonProxyHosts( proxyInfo, jiraHost ) )
162 {
163 return;
164 }
165
166 proxyHost = settings.getActiveProxy().getHost();
167 proxyPort = settings.getActiveProxy().getPort();
168 proxyUser = settings.getActiveProxy().getUsername();
169 proxyPass = settings.getActiveProxy().getPassword();
170 }
171 }
172
173 /**
174 * Override this method if you need to get issues for a specific Fix For.
175 *
176 * @return A Fix For id or <code>null</code> if you don't have that need
177 */
178 protected String getFixFor()
179 {
180 if ( onlyCurrentVersion && useJql )
181 {
182 // Let JIRA do the filtering of the current version instead of the JIRA mojo.
183 // This way JIRA returns less issues and we do not run into the "nbEntriesMax" limit that easily.
184
185 String version = ( versionPrefix == null ? "" : versionPrefix ) + project.getVersion();
186
187 // Remove "-SNAPSHOT" from the end of the version, if it's there
188 if ( version.endsWith( IssueUtils.SNAPSHOT_SUFFIX ) )
189 {
190 return version.substring( 0, version.length() - IssueUtils.SNAPSHOT_SUFFIX.length() );
191 }
192 else
193 {
194 return version;
195 }
196 }
197 else
198 {
199 return null;
200 }
201 }
202
203
204 public abstract List<Issue> getIssueList() throws MojoExecutionException;
205
206 public void setJiraDatePattern( String jiraDatePattern )
207 {
208 this.jiraDatePattern = jiraDatePattern;
209 }
210
211 /**
212 * Set the output file for the log.
213 *
214 * @param thisOutput the output file
215 */
216 public void setOutput( File thisOutput )
217 {
218 this.output = thisOutput;
219 }
220
221 public File getOutput()
222 {
223 return this.output;
224 }
225
226 /**
227 * Sets the project.
228 *
229 * @param thisProject The project to set
230 */
231 public void setMavenProject( Object thisProject )
232 {
233 this.project = (MavenProject) thisProject;
234 }
235
236 /**
237 * Sets the maximum number of Issues to show.
238 *
239 * @param nbEntries The maximum number of Issues
240 */
241 public void setNbEntries( final int nbEntries )
242 {
243 nbEntriesMax = nbEntries;
244 }
245
246 /**
247 * Sets the statusIds.
248 *
249 * @param thisStatusIds The id(s) of the status to show, as comma separated string
250 */
251 public void setStatusIds( String thisStatusIds )
252 {
253 statusIds = thisStatusIds;
254 }
255
256 /**
257 * Sets the priorityIds.
258 *
259 * @param thisPriorityIds The id(s) of the priority to show, as comma separated string
260 */
261 public void setPriorityIds( String thisPriorityIds )
262 {
263 priorityIds = thisPriorityIds;
264 }
265
266 /**
267 * Sets the resolutionIds.
268 *
269 * @param thisResolutionIds The id(s) of the resolution to show, as comma separated string
270 */
271 public void setResolutionIds( String thisResolutionIds )
272 {
273 resolutionIds = thisResolutionIds;
274 }
275
276 /**
277 * Sets the sort column names.
278 *
279 * @param thisSortColumnNames The column names to sort by
280 */
281 public void setSortColumnNames( String thisSortColumnNames )
282 {
283 sortColumnNames = thisSortColumnNames;
284 }
285
286 /**
287 * Sets the password for authentication against the webserver.
288 *
289 * @param thisWebPassword The password of the webserver
290 */
291 public void setWebPassword( String thisWebPassword )
292 {
293 this.webPassword = thisWebPassword;
294 }
295
296 /**
297 * Sets the username for authentication against the webserver.
298 *
299 * @param thisWebUser The username of the webserver
300 */
301 public void setWebUser( String thisWebUser )
302 {
303 this.webUser = thisWebUser;
304 }
305
306 /**
307 * Sets the password to log into a secured JIRA.
308 *
309 * @param thisJiraPassword The password for JIRA
310 */
311 public void setJiraPassword( final String thisJiraPassword )
312 {
313 this.jiraPassword = thisJiraPassword;
314 }
315
316 /**
317 * Sets the username to log into a secured JIRA.
318 *
319 * @param thisJiraUser The username for JIRA
320 */
321 public void setJiraUser( String thisJiraUser )
322 {
323 this.jiraUser = thisJiraUser;
324 }
325
326 /**
327 * Sets the filter to apply to query to JIRA.
328 *
329 * @param thisFilter The filter to query JIRA
330 */
331 public void setFilter( String thisFilter )
332 {
333 this.filter = thisFilter;
334 }
335
336 /**
337 * Sets the component(s) to apply to query JIRA.
338 *
339 * @param theseComponents The id(s) of components to show, as comma separated string
340 */
341 public void setComponent( String theseComponents )
342 {
343 this.component = theseComponents;
344 }
345
346 /**
347 * Sets the fix version id(s) to apply to query JIRA.
348 *
349 * @param theseFixVersionIds The id(s) of fix versions to show, as comma separated string
350 */
351 public void setFixVersionIds( String theseFixVersionIds )
352 {
353 this.fixVersionIds = theseFixVersionIds;
354 }
355
356 /**
357 * Sets the typeIds.
358 *
359 * @param theseTypeIds The id(s) of the types to show, as comma separated string
360 */
361 public void setTypeIds( String theseTypeIds )
362 {
363 typeIds = theseTypeIds;
364 }
365
366 public void setLog( Log log )
367 {
368 this.log = log;
369 }
370
371 protected Log getLog()
372 {
373 return log;
374 }
375
376 public void setSettings( Settings settings )
377 {
378 this.settings = settings;
379 }
380
381 public boolean isUseJql()
382 {
383 return useJql;
384 }
385
386 public void setUseJql( boolean useJql )
387 {
388 this.useJql = useJql;
389 }
390
391 public boolean isOnlyCurrentVersion()
392 {
393 return onlyCurrentVersion;
394 }
395
396 public void setOnlyCurrentVersion( boolean onlyCurrentVersion )
397 {
398 this.onlyCurrentVersion = onlyCurrentVersion;
399 }
400
401 public String getVersionPrefix()
402 {
403 return versionPrefix;
404 }
405
406 public void setVersionPrefix( String versionPrefix )
407 {
408 this.versionPrefix = versionPrefix;
409 }
410
411 public void setConnectionTimeout( int connectionTimeout ) {
412 this.connectionTimeout = connectionTimeout;
413 }
414
415 public void setReceiveTimout( int receiveTimout ) {
416 this.receiveTimout = receiveTimout;
417 }
418 }