blob: f7330e2e7a31c3bc2195fbd379eb8e8d992000f4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.plugins.jira;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Locale;
import org.apache.maven.plugin.logging.Log;
/**
* Builder for a JIRA query using the JIRA query language. Only a limited set of JQL is supported.
*
* @author ton.swieb@finalist.com
* @version $Id$
* @since 2.8
*/
public class JqlQueryBuilder implements JiraQueryBuilder {
private String filter = "";
private boolean urlEncode = true;
/**
* Log for debug output.
*/
private Log log;
private StringBuilder orderBy = new StringBuilder();
private StringBuilder query = new StringBuilder();
public JqlQueryBuilder(Log log) {
this.log = log;
}
public String build() {
try {
String jqlQuery;
// If the user has defined a filter - use that
if ((this.filter != null) && (this.filter.length() > 0)) {
jqlQuery = filter;
} else {
jqlQuery = query.toString() + orderBy.toString();
}
if (urlEncode) {
getLog().debug("Encoding JQL query " + jqlQuery);
String encodedQuery = URLEncoder.encode(jqlQuery, "UTF-8");
getLog().debug("Encoded JQL query " + encodedQuery);
return encodedQuery;
} else {
return jqlQuery;
}
} catch (UnsupportedEncodingException e) {
getLog().error("Unable to encode JQL query with UTF-8", e);
throw new RuntimeException(e);
}
}
public JiraQueryBuilder components(String components) {
addCommaSeparatedValues("component", components);
return this;
}
public JiraQueryBuilder components(List<String> components) {
addValues("component", components);
return this;
}
public JiraQueryBuilder filter(String filter) {
this.filter = filter;
return this;
}
/**
* When both {@link #fixVersion(String)} and {@link #fixVersionIds(String)} are used then you will probably end up
* with a JQL query that is valid, but returns nothing. Unless they both only reference the same fixVersion
*
* @param fixVersion a single fix version
* @return the builder.
*/
public JiraQueryBuilder fixVersion(String fixVersion) {
addSingleValue("fixVersion", fixVersion);
return this;
}
/**
* When both {@link #fixVersion(String)} and {@link #fixVersionIds(String)} are used then you will probably end up
* with a JQL query that is valid, but returns nothing. Unless they both only reference the same fixVersion
*
* @param fixVersionIds a comma-separated list of version ids.
* @return the builder.
*/
public JiraQueryBuilder fixVersionIds(String fixVersionIds) {
addCommaSeparatedValues("fixVersion", fixVersionIds);
return this;
}
/**
* Add a sequence of version IDs already in a list.
*
* @param fixVersionIds the version ids.
* @return the builder.
*/
public JiraQueryBuilder fixVersionIds(List<String> fixVersionIds) {
addValues("fixVersion", fixVersionIds);
return this;
}
public Log getLog() {
return log;
}
public JiraQueryBuilder priorityIds(String priorityIds) {
addCommaSeparatedValues("priority", priorityIds);
return this;
}
public JiraQueryBuilder priorityIds(List<String> priorityIds) {
addValues("priority", priorityIds);
return this;
}
public JiraQueryBuilder project(String project) {
addSingleValue("project", project);
return this;
}
public JiraQueryBuilder resolutionIds(String resolutionIds) {
addCommaSeparatedValues("resolution", resolutionIds);
return this;
}
public JiraQueryBuilder resolutionIds(List<String> resolutionIds) {
addValues("resolution", resolutionIds);
return this;
}
public JiraQueryBuilder sortColumnNames(String sortColumnNames) {
if (sortColumnNames != null) {
orderBy.append(" ORDER BY ");
String[] sortColumnNamesArray = sortColumnNames.split(",");
for (int i = 0; i < sortColumnNamesArray.length - 1; i++) {
addSingleSortColumn(sortColumnNamesArray[i]);
orderBy.append(", ");
}
addSingleSortColumn(sortColumnNamesArray[sortColumnNamesArray.length - 1]);
}
return this;
}
public JiraQueryBuilder statusIds(String statusIds) {
addCommaSeparatedValues("status", statusIds);
return this;
}
public JiraQueryBuilder statusIds(List<String> statusIds) {
addValues("status", statusIds);
return this;
}
public JiraQueryBuilder typeIds(String typeIds) {
addCommaSeparatedValues("type", typeIds);
return this;
}
public JiraQueryBuilder typeIds(List<String> typeIds) {
addValues("type", typeIds);
return this;
}
public JiraQueryBuilder urlEncode(boolean doEncoding) {
urlEncode = doEncoding;
return this;
}
public boolean urlEncode() {
return urlEncode;
}
/* --------------------------------------------------------------------- */
/* Private methods */
/* --------------------------------------------------------------------- */
private void addCommaSeparatedValues(String key, String values) {
if (values != null) {
if (query.length() > 0) {
query.append(" AND ");
}
query.append(key).append(" in (");
String[] valuesArr = values.split(",");
for (int i = 0; i < (valuesArr.length - 1); i++) {
trimAndQuoteValue(valuesArr[i]);
query.append(", ");
}
trimAndQuoteValue(valuesArr[valuesArr.length - 1]);
query.append(")");
}
}
private void addValues(String key, List<String> values) {
if (values != null && values.size() > 0) {
if (query.length() > 0) {
query.append(" AND ");
}
query.append(key).append(" in (");
for (int i = 0; i < (values.size() - 1); i++) {
trimAndQuoteValue(values.get(i));
query.append(", ");
}
trimAndQuoteValue(values.get(values.size() - 1));
query.append(")");
}
}
private void addSingleSortColumn(String name) {
boolean descending = false;
name = name.trim().toLowerCase(Locale.ENGLISH);
if (name.endsWith("desc")) {
descending = true;
name = name.substring(0, name.length() - 4).trim();
} else if (name.endsWith("asc")) {
descending = false;
name = name.substring(0, name.length() - 3).trim();
}
// Strip any spaces from the column name, or it will trip up JIRA's JQL parser
name = name.replaceAll(" ", "");
orderBy.append(name);
orderBy.append(descending ? " DESC" : " ASC");
}
private void addSingleValue(String key, String value) {
if (value != null) {
if (query.length() > 0) {
query.append(" AND ");
}
query.append(key).append(" = ");
trimAndQuoteValue(value);
}
}
private void trimAndQuoteValue(String value) {
String trimmedValue = value.trim();
if (trimmedValue.contains(" ") || trimmedValue.contains(".")) {
query.append("\"").append(trimmedValue).append("\"");
} else {
query.append(trimmedValue);
}
}
}