/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2014 Oracle and/or its affiliates. All rights reserved. * * Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. * * Contributor(s): * * Portions Copyrighted 2014 Sun Microsystems, Inc. */ package com.junichi11.netbeans.modules.github.issues.query; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams.Is; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams.No; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams.Order; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams.Sort; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams.State; import com.junichi11.netbeans.modules.github.issues.egit.SearchIssuesParams.Type; import com.junichi11.netbeans.modules.github.issues.issue.GitHubIssue; import com.junichi11.netbeans.modules.github.issues.repository.GitHubRepository; import com.junichi11.netbeans.modules.github.issues.utils.StringUtils; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.netbeans.modules.bugtracking.issuetable.ColumnDescriptor; import org.netbeans.modules.bugtracking.spi.QueryProvider; /** * * @author junichi11 */ public class GitHubQuery { public enum QParam { KEYWORD("keyword", "keyword"), // NOI18N MILESTONE("milestone", "milestone"), // NOI18N TYPE("type", "type"), // NOI18N IN("in", "in"), // NOI18N AUTHOR("author", "author"), // NOI18N ASSIGNEE("assignee", "assignee"), // NOI18N MENTIONS("mentions", "mentions"), // NOI18N COMMENTER("commenter", "commenter"), // NOI18N INVOLVES("involves", "involves"), // NOI18N STATE("state", "state"), // NOI18N LABELS("labels", "labels"), // NOI18N NO("no", "no"), // NOI18N LANGUAGE("language", "language"), // NOI18N IS("is", "is"), // NOI18N IS_OPEN("isOpen", "is"), // NOI18N IS_MERGED("isMerged", "is"), // NOI18N IS_ISSUE("isIssue", "is"), // NOI18N CREATED("created", "created"), // NOI18N UPDATED("updated", "updated"), // NOI18N MERGED("merged", "merged"), // NOI18N CLOSED("closed", "closed"), // NOI18N COMMENTS("comments", "comments"); // NOI18N private final String key; private final String value; private QParam(String key, String value) { this.key = key; this.value = value; } public String getKey() { return key; } public String getValue() { return value; } } public enum Param { SORT("sort"), // NOI18N ORDER("order"); // NOI18N private final String value; private Param(String value) { this.value = value; } public String getValue() { return value; } } private String name; private String queryParam; private GitHubRepository repository; private GitHubQueryController controller; private ColumnDescriptor[] columnDescriptors; private boolean isSaved; private QueryProvider.IssueContainer<GitHubIssue> issueContainer; private String keyword; private final Map<String, String> qParamsMap = new HashMap<>(); private final Map<String, String> paramsMap = new HashMap<>(); private State state; public GitHubQuery(GitHubRepository repository) { this(repository, null, null); } public GitHubQuery(GitHubRepository repository, String name, String queryParam) { this.name = name; this.repository = repository; this.queryParam = queryParam; if (queryParam != null) { isSaved = true; } parseParam(); } public GitHubRepository getRepository() { return this.repository; } public void setDisplayName(String name) { this.name = name; } public String getDisplayName() { return name; } public String getTooltip() { return getDisplayName(); } public String getQueryParam() { return queryParam; } public void setQueryParam(SearchIssuesParams params) { if (params == null) { queryParam = null; return; } this.queryParam = params.getParameters(false); parseParam(); } public Map<String, String> getParamsMap() { return new HashMap<>(paramsMap); } public Map<String, String> getQParamsMap() { return new HashMap<>(qParamsMap); } public void save() { repository.saveQuery(this); } public void setSaved(boolean isSaved) { this.isSaved = isSaved; } public boolean isSaved() { return isSaved; } public GitHubQueryController getController() { if (controller == null) { controller = createController(); } return controller; } private GitHubQueryController createController() { return new GitHubQueryController(this); } public boolean canRemove() { return true; } public void remove() { repository.removeQuery(this); } public boolean canRename() { return true; } public void rename(String string) { } public void setIssueContainer(QueryProvider.IssueContainer<GitHubIssue> issueContainer) { this.issueContainer = issueContainer; } /** * Refresh issues. */ public void refresh() { try { if (issueContainer != null) { issueContainer.refreshingStarted(); issueContainer.clear(); for (GitHubIssue issue : getIssues(true)) { issueContainer.add(issue); } } } finally { fireFinished(); } } void fireFinished() { if (issueContainer != null) { issueContainer.refreshingFinished(); } } public List<GitHubIssue> getIssues(boolean isRefresh) { Map<String, String> filter = getFilter(); if (filter.isEmpty()) { if (StringUtils.isEmpty(queryParam)) { return Collections.emptyList(); } return searchIssues(createSearchIssuesParams(), isRefresh); } return repository.getIssues(filter, isRefresh); } protected Map<String, String> getFilter() { return Collections.emptyMap(); } public List<GitHubIssue> searchIssues(SearchIssuesParams params, boolean isRefresh) { return repository.searchIssues(params, isRefresh); } public String getKeyword() { return keyword; } public State getState() { return state; } public String getParameter(QParam param) { if (param == null) { return null; } String value = qParamsMap.get(param.getKey()); return value == null ? "" : value; // NOI18N } public String getParameter(Param param) { if (param == null) { return null; } String value = paramsMap.get(param.getValue()); return value == null ? "" : value; // NOI18N } private SearchIssuesParams createSearchIssuesParams() { return new SearchIssuesParams() .keyword(getParameter(QParam.KEYWORD)) .milestone(getParameter(QParam.MILESTONE)) .assignee(getParameter(QParam.ASSIGNEE)) .author(getParameter(QParam.AUTHOR)) .commenter(getParameter(QParam.COMMENTER)) .mentions(getParameter(QParam.MENTIONS)) .created(getParameter(QParam.CREATED)) .updated(getParameter(QParam.UPDATED)) .merged(getParameter(QParam.MERGED)) .closed(getParameter(QParam.CLOSED)) .involves(getParameter(QParam.INVOLVES)) .language(getParameter(QParam.LANGUAGE)) .state(State.valueOfString(getParameter(QParam.STATE))) .type(Type.valueOfString(getParameter(QParam.TYPE))) .in(getParameter(QParam.IN)) .no(No.valueOfString(getParameter(QParam.NO))) .is(Is.valueOfString(getParameter(QParam.IS_OPEN))) .is(Is.valueOfString(getParameter(QParam.IS_MERGED))) .is(Is.valueOfString(getParameter(QParam.IS_ISSUE))) .comments(getParameter(QParam.COMMENTS)) .labels(getParameter(QParam.LABELS)) .sort(Sort.valueOfString(getParameter(Param.SORT))) .order(Order.valueOfString(getParameter(Param.ORDER))); } private void clearParams() { qParamsMap.clear(); paramsMap.clear(); } private void parseParam() { clearParams(); if (StringUtils.isEmpty(queryParam)) { return; } StringTokenizer tokenizer = new StringTokenizer(queryParam, "&"); // NOI18N while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); String[] split = token.split("="); // NOI18N if (split.length != 2) { continue; } String key = split[0]; String value = split[1]; paramsMap.put(key, value); switch (key) { case "q": // NOI18N parseQ(value); break; case "sort": // NOI18N break; case "order": // NOI18N break; default: break; } } } private void parseQ(String q) { if (StringUtils.isEmpty(q)) { return; } StringTokenizer tokenizer = new StringTokenizer(q, "+"); // NOI18N while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); String[] split = token.split(":"); // NOI18N if (split.length == 1) { qParamsMap.put(QParam.KEYWORD.getKey(), token); continue; } if (split.length != 2) { continue; } String key = split[0]; String value = split[1]; if (key.equals("is")) { // NOI18N switch (value) { case "merged": // NOI18N case "unmerged": // NOI18N qParamsMap.put(QParam.IS_MERGED.getKey(), value); break; case "issue": // NOI18N case "pr": // NOI18N qParamsMap.put(QParam.IS_ISSUE.getKey(), value); break; case "open": // NOI18N case "closed": // NOI18N qParamsMap.put(QParam.IS_OPEN.getKey(), value); break; default: break; } } else if (key.equals("label")) { // NOI18N String labels = qParamsMap.get(QParam.LABELS.getKey()); if (!StringUtils.isEmpty(labels)) { labels = String.format("%s,%s", labels, value); // NOI18N } else { labels = value; } qParamsMap.put(QParam.LABELS.getKey(), labels); } else { qParamsMap.put(key, value); } } } /** * Get ColumnDescriptors. * * @return ColumnDescriptors */ public ColumnDescriptor[] getColumnDescriptors() { if (columnDescriptors == null) { columnDescriptors = GitHubIssue.getColumnDescriptors(); } return columnDescriptors; } }