1 /* 2 * Copyright 2008-2010 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package de.smartics.maven.issues.bugzilla; 18 19 import java.net.MalformedURLException; 20 import java.net.URL; 21 22 import org.apache.maven.reporting.MavenReportException; 23 import org.codehaus.plexus.util.StringUtils; 24 25 import de.smartics.maven.issues.ArtifactVersionRange; 26 import de.smartics.maven.issues.QueryData; 27 28 /** 29 * The data used to construct issue queries for Bugzilla. 30 * 31 * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a> 32 * @version $Revision:591 $ 33 */ 34 public class BugzillaQueryData implements QueryData 35 { 36 // ********************************* Fields ********************************* 37 38 // --- constants ------------------------------------------------------------ 39 40 // --- members -------------------------------------------------------------- 41 42 /** 43 * Defines the filter parameters to restrict which issues are retrieved from 44 * Bugzilla. The filter parameter must use the same format of url parameters 45 * that is used in a Bugzilla search. 46 */ 47 private String filter; 48 49 /** 50 * Sets the keywords that you want to limit your report to include. 51 */ 52 private String keywords; 53 54 /** 55 * Sets the handling of the keywords. May have any value but Bugzilla supports 56 * currently <code>allwords</code>, <code>nowords</code>, 57 * <code>anywords</code>. 58 */ 59 private String keywordsType; 60 61 /** 62 * Sets the status(es) that you want to limit your report to include. Valid 63 * statuses are: UNCONFIRMED, NEW, ASSIGNED, REOPENED, RESOLVED, VERIFIED, and 64 * CLOSED. Multiple values can be separated by commas. 65 */ 66 private String status; 67 68 /** 69 * Sets the resolution(s) that you want to limit your report to include. Valid 70 * statuses are: FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE, 71 * WORKSFORME, and MOVED. Multiple values can be separated by commas. 72 */ 73 private String resolution; 74 75 /** 76 * Sets the component(s) that you want to limit your report to include. 77 * Multiple components can be separated by commas. If this is set to empty - 78 * that means all components. 79 */ 80 private String component; 81 82 /** 83 * Sets the product(s) that you want to limit your report to include. Multiple 84 * products can be separated by commas. If this is set to empty - that means 85 * all products. 86 */ 87 private String product; 88 89 /** 90 * The order of the bugs returned. 91 */ 92 private String order; 93 94 /** 95 * The name of the query to execute. If the query name is specified none of 96 * the other query properties is taken into account. 97 */ 98 private String queryName; 99 100 /** 101 * The type of the command executed. This property is currently only relevant 102 * is <code>queryName</code> is set. 103 */ 104 private String commandType; 105 106 /** 107 * The version range to query for. 108 */ 109 private ArtifactVersionRange versionRange; 110 111 // ****************************** Initializer ******************************* 112 113 // ****************************** Constructors ****************************** 114 115 /** 116 * Default constructor. 117 */ 118 public BugzillaQueryData() 119 { 120 } 121 122 // ****************************** Inner Classes ***************************** 123 124 // ********************************* Methods ******************************** 125 126 // --- init ----------------------------------------------------------------- 127 128 // --- get&set -------------------------------------------------------------- 129 130 /** 131 * Returns the value for filter. 132 * <p> 133 * Defines the filter parameters to restrict which issues are retrieved from 134 * Bugzilla. The filter parameter must use the same format of url parameters 135 * that is used in a Bugzilla search. 136 * 137 * @return the value for filter. 138 */ 139 public String getFilter() 140 { 141 return filter; 142 } 143 144 /** 145 * Sets the value for filter. 146 * <p> 147 * Defines the filter parameters to restrict which issues are retrieved from 148 * Bugzilla. The filter parameter must use the same format of url parameters 149 * that is used in a Bugzilla search. 150 * 151 * @param filter the value for filter. 152 */ 153 public void setFilter(final String filter) 154 { 155 this.filter = filter; 156 } 157 158 /** 159 * Returns the value for keywords. 160 * <p> 161 * Sets the keywords that you want to limit your report to include. 162 * 163 * @return the value for keywords. 164 */ 165 public String getKeywords() 166 { 167 return keywords; 168 } 169 170 /** 171 * Sets the value for keywords. 172 * <p> 173 * Sets the keywords that you want to limit your report to include. 174 * 175 * @param keywords the value for keywords. 176 */ 177 public void setKeywords(final String keywords) 178 { 179 this.keywords = keywords; 180 } 181 182 /** 183 * Returns the value for keywordsType. 184 * <p> 185 * Sets the handling of the keywords. May have any value but Bugzilla supports 186 * currently <code>allwords</code>, <code>nowords</code>, 187 * <code>anywords</code>. 188 * 189 * @return the value for keywordsType. 190 */ 191 public String getKeywordsType() 192 { 193 return keywordsType; 194 } 195 196 /** 197 * Sets the value for keywordsType. 198 * <p> 199 * Sets the handling of the keywords. May have any value but Bugzilla supports 200 * currently <code>allwords</code>, <code>nowords</code>, 201 * <code>anywords</code>. 202 * 203 * @param keywordsType the value for keywordsType. 204 */ 205 public void setKeywordsType(final String keywordsType) 206 { 207 this.keywordsType = keywordsType; 208 } 209 210 /** 211 * Returns the value for status. 212 * <p> 213 * Sets the status(es) that you want to limit your report to include. Valid 214 * statuses are: UNCONFIRMED, NEW, ASSIGNED, REOPENED, RESOLVED, VERIFIED, and 215 * CLOSED. Multiple values can be separated by commas. 216 * 217 * @return the value for status. 218 */ 219 public String getStatus() 220 { 221 return status; 222 } 223 224 /** 225 * Sets the value for status. 226 * <p> 227 * Sets the status(es) that you want to limit your report to include. Valid 228 * statuses are: UNCONFIRMED, NEW, ASSIGNED, REOPENED, RESOLVED, VERIFIED, and 229 * CLOSED. Multiple values can be separated by commas. 230 * 231 * @param status the value for status. 232 */ 233 public void setStatus(final String status) 234 { 235 this.status = status; 236 } 237 238 /** 239 * Returns the value for resolution. 240 * <p> 241 * Sets the resolution(s) that you want to limit your report to include. Valid 242 * statuses are: FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE, 243 * WORKSFORME, and MOVED. Multiple values can be separated by commas. 244 * 245 * @return the value for resolution. 246 */ 247 public String getResolution() 248 { 249 return resolution; 250 } 251 252 /** 253 * Sets the value for resolution. 254 * <p> 255 * Sets the resolution(s) that you want to limit your report to include. Valid 256 * statuses are: FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE, 257 * WORKSFORME, and MOVED. Multiple values can be separated by commas. 258 * 259 * @param resolution the value for resolution. 260 */ 261 public void setResolution(final String resolution) 262 { 263 this.resolution = resolution; 264 } 265 266 /** 267 * Returns the value for component. 268 * <p> 269 * Sets the component(s) that you want to limit your report to include. 270 * Multiple components can be separated by commas. If this is set to empty - 271 * that means all components. 272 * 273 * @return the value for component. 274 */ 275 public String getComponent() 276 { 277 return component; 278 } 279 280 /** 281 * Sets the value for component. 282 * <p> 283 * Sets the component(s) that you want to limit your report to include. 284 * Multiple components can be separated by commas. If this is set to empty - 285 * that means all components. 286 * 287 * @param component the value for component. 288 */ 289 public void setComponent(final String component) 290 { 291 this.component = component; 292 } 293 294 /** 295 * Returns the value for product. 296 * <p> 297 * Sets the product(s) that you want to limit your report to include. Multiple 298 * products can be separated by commas. If this is set to empty - that means 299 * all products. 300 * 301 * @return the value for product. 302 */ 303 public String getProduct() 304 { 305 return product; 306 } 307 308 /** 309 * Sets the value for product. 310 * <p> 311 * Sets the product(s) that you want to limit your report to include. Multiple 312 * products can be separated by commas. If this is set to empty - that means 313 * all products. 314 * 315 * @param product the value for product. 316 */ 317 public void setProduct(final String product) 318 { 319 this.product = product; 320 } 321 322 /** 323 * Returns the order of the bugs returned. 324 * 325 * @return the order of the bugs returned. 326 */ 327 public String getOrder() 328 { 329 return order; 330 } 331 332 /** 333 * Sets the order of the bugs returned. 334 * 335 * @param order the order of the bugs returned. 336 */ 337 public void setOrder(final String order) 338 { 339 this.order = order; 340 } 341 342 /** 343 * Returns the name of the query to execute. If the query name is specified 344 * none of the other query properties is taken into account. 345 * 346 * @return the name of the query to execute. 347 */ 348 public String getQueryName() 349 { 350 return queryName; 351 } 352 353 /** 354 * Sets the name of the query to execute. If the query name is specified none 355 * of the other query properties is taken into account. 356 * 357 * @param queryName the name of the query to execute. 358 */ 359 public void setQueryName(final String queryName) 360 { 361 this.queryName = queryName; 362 } 363 364 /** 365 * Returns the type of the command executed. This property is currently only 366 * relevant is <code>queryName</code> is set. 367 * 368 * @return the type of the command executed. 369 */ 370 public String getCommandType() 371 { 372 return commandType; 373 } 374 375 /** 376 * Sets the type of the command executed. This property is currently only 377 * relevant is <code>queryName</code> is set. 378 * 379 * @param commandType the type of the command executed. 380 */ 381 public void setCommandType(final String commandType) 382 { 383 this.commandType = commandType; 384 } 385 386 /** 387 * Returns the version range to query for. 388 * 389 * @return the version range to query for. 390 */ 391 public ArtifactVersionRange getVersionRange() 392 { 393 return versionRange; 394 } 395 396 /** 397 * Sets the version range to query for. 398 * 399 * @param versionRange the version range to query for. 400 */ 401 public void setVersionRange(final ArtifactVersionRange versionRange) 402 { 403 this.versionRange = versionRange; 404 } 405 406 // --- business ------------------------------------------------------------- 407 408 /** 409 * {@inheritDoc} 410 * 411 * @see de.smartics.maven.issues.QueryData#createUrl(String) 412 */ 413 public String createUrl(final String connectionUrl) 414 throws MavenReportException 415 { 416 final StringBuilder buffer = new StringBuilder(connectionUrl); 417 buffer.append("/buglist.cgi?"); 418 if (StringUtils.isNotBlank(queryName)) 419 { 420 appendNamedQuery(buffer); 421 } 422 else 423 { 424 createManualQuery(buffer); 425 } 426 427 String urlString = buffer.toString(); 428 try 429 { 430 if (urlString.endsWith("&")) 431 { 432 urlString = StringUtils.chop(urlString); 433 } 434 final String url = new URL(urlString).toString(); 435 return url; 436 } 437 catch (final MalformedURLException e) 438 { 439 throw new MavenReportException("There was a syntax error in your URL: " 440 + urlString, e); 441 } 442 } 443 444 /** 445 * Appends the parameters for a named query to the buffer. 446 * 447 * @param buffer the buffer to append to. 448 */ 449 private void appendNamedQuery(final StringBuilder buffer) 450 { 451 appendParameterIfPresent(buffer, "cmdtype", commandType); 452 appendParameterIfPresent(buffer, "namedcmd", queryName); 453 } 454 455 /** 456 * Appends the parameters for a query where the parameters have been set one 457 * by one or with a filter. 458 * 459 * @param buffer the buffer to append to. 460 */ 461 private void createManualQuery(final StringBuilder buffer) 462 { 463 appendIfPresent(buffer, "product", product); 464 appendIfPresent(buffer, "component", component); 465 appendIfPresent(buffer, "bug_status", status); 466 appendIfPresent(buffer, "resolution", resolution); 467 appendParameterIfPresent(buffer, "keywords", keywords); // Keywords are 468 // added as a list 469 // value 470 471 if (StringUtils.isNotBlank(keywords)) 472 { 473 appendParameterIfPresent(buffer, "keywords_type", keywordsType); 474 } 475 appendParameterIfPresent(buffer, "order", order); 476 477 if(versionRange != null) 478 { 479 versionRange.appendToUrl(buffer); 480 } 481 482 if (StringUtils.isNotBlank(filter)) 483 { 484 buffer.append(filter); 485 } 486 } 487 488 /** 489 * Appends the items of the value individually if present. 490 * 491 * @param buffer the buffer to append to. 492 * @param paramName the name of the parameter. 493 * @param paramValue the value of the parameter. 494 */ 495 private void appendIfPresent(final StringBuilder buffer, 496 final String paramName, final String paramValue) 497 { 498 if (StringUtils.isNotBlank(paramValue)) 499 { 500 for (String item : paramValue.split(",")) 501 { 502 appendParameterIfPresent(buffer, paramName, item); 503 } 504 } 505 } 506 507 /** 508 * Appends the parameter to the buffer. 509 * 510 * @param buffer the buffer to append to. 511 * @param paramName the name of the parameter. 512 * @param paramValue the value of the parameter. 513 */ 514 private void appendParameterIfPresent(final StringBuilder buffer, 515 final String paramName, final String paramValue) 516 { 517 if (StringUtils.isNotBlank(paramValue)) 518 { 519 buffer.append(paramName).append('=').append(paramValue).append('&'); 520 } 521 } 522 523 // --- object basics -------------------------------------------------------- 524 525 }