Tasks. Generic Web Connector. GET and POST types of requests.

This commit is contained in:
Evgeny Zakrevsky
2012-10-23 17:02:54 +04:00
parent ef02e8d75e
commit de18d5bf86
4 changed files with 132 additions and 47 deletions
@@ -9,7 +9,9 @@ import com.intellij.tasks.impl.BaseRepositoryImpl;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.Tag;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -26,6 +28,8 @@ public class GenericWebRepository extends BaseRepositoryImpl {
private String myTasksListURL = "";
private String myTaskPattern = "";
private String myLoginURL = "";
private String myLoginMethodType = GenericWebRepositoryEditor.GET;
private String myGetTasksMethodType = GenericWebRepositoryEditor.GET;
final static String SERVER_URL_PLACEHOLDER = "{serverUrl}";
final static String USERNAME_PLACEHOLDER = "{username}";
@@ -33,7 +37,10 @@ public class GenericWebRepository extends BaseRepositoryImpl {
final static String ID_PLACEHOLDER = "{id}";
final static String SUMMARY_PLACEHOLDER = "{summary}";
final static String QUERY_PLACEHOLDER = "{query}";
final static String MAX_COUNT_PLACEHOLDER = "{count}";
//todo
final static String DESCRIPTION_PLACEHOLDER = "{description}";
//todo
final static String PAGE_PLACEHOLDER = "{page}";
@SuppressWarnings({"UnusedDeclaration"})
@@ -49,6 +56,8 @@ public class GenericWebRepository extends BaseRepositoryImpl {
myTasksListURL = other.getTasksListURL();
myTaskPattern = other.getTaskPattern();
myLoginURL = other.getLoginURL();
myLoginMethodType = other.getLoginMethodType();
myGetTasksMethodType = other.getGetTasksMethodType();
}
@Override
@@ -57,10 +66,16 @@ public class GenericWebRepository extends BaseRepositoryImpl {
if (!isLoginAnonymously()) login(httpClient);
final GetMethod getMethod = new GetMethod(getFullTasksUrl(query != null ? query : ""));
httpClient.executeMethod(getMethod);
if (getMethod.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + getMethod.getStatusCode());
final String response = getMethod.getResponseBodyAsString(Integer.MAX_VALUE);
final List<String> placeholders = getPlaceholders(myTaskPattern);
if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) {
throw new Exception("Incorrect Task Pattern");
}
//todo add possibility to select method type
final HttpMethod method = getTaskListsMethod(query != null ? query : "", max);
httpClient.executeMethod(method);
if (method.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + method.getStatusCode());
final String response = method.getResponseBodyAsString();
final String taskPatternWithoutPlaceholders = myTaskPattern.replaceAll("\\{.+?\\}", "");
Matcher matcher = Pattern
@@ -68,11 +83,6 @@ public class GenericWebRepository extends BaseRepositoryImpl {
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ)
.matcher(response);
final List<String> placeholders = getPlaceholders(myTaskPattern);
if (matcher.groupCount() != 2 || !placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) {
throw new Exception("Incorrect Task Pattern");
}
List<Task> tasks = new ArrayList<Task>();
while (matcher.find()) {
final String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1);
@@ -86,12 +96,42 @@ public class GenericWebRepository extends BaseRepositoryImpl {
return tasks.toArray(new Task[tasks.size()]);
}
private HttpMethod getTaskListsMethod(final String query, final int max) {
String requestUrl = getFullTasksUrl(query, max);
return GenericWebRepositoryEditor.GET.equals(myGetTasksMethodType) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl);
}
private void login(final HttpClient httpClient) throws Exception {
final GetMethod method = new GetMethod(getFullLoginUrl());
final HttpMethod method = getLoginMethod();
httpClient.executeMethod(method);
if (method.getStatusCode() != 200) throw new Exception("Cannot login: HTTP status code " + method.getStatusCode());
}
private HttpMethod getLoginMethod() {
String requestUrl = getFullLoginUrl();
return GenericWebRepositoryEditor.GET.equals(myLoginMethodType) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl);
}
private static HttpMethod getPostMethodFromURL(final String requestUrl) {
int n = requestUrl.indexOf('?');
if (n == -1) {
return new PostMethod(requestUrl);
}
PostMethod postMethod = new PostMethod(requestUrl.substring(0, n));
n = requestUrl.indexOf('?');
String[] requestParams = requestUrl.substring(n + 1).split("&");
for (String requestParam : requestParams) {
String[] nv = requestParam.split("=");
if (nv.length == 1) {
postMethod.addParameter(nv[0], "");
} else {
postMethod.addParameter(nv[0], nv[1]);
}
}
return postMethod;
}
private static List<String> getPlaceholders(String value) {
if (value == null) {
return ContainerUtil.emptyList();
@@ -105,21 +145,18 @@ public class GenericWebRepository extends BaseRepositoryImpl {
return vars;
}
private String getFullTasksUrl(final String query) {
private String getFullTasksUrl(final String query, final int max) {
return getTasksListURL()
.replaceAll(placeholder2regexp(SERVER_URL_PLACEHOLDER), getUrl())
.replaceAll(placeholder2regexp(QUERY_PLACEHOLDER), query);
.replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl())
.replaceAll(Pattern.quote(QUERY_PLACEHOLDER), encodeUrl(query))
.replaceAll(Pattern.quote(MAX_COUNT_PLACEHOLDER), String.valueOf(max));
}
private String getFullLoginUrl() {
return getLoginURL()
.replaceAll(placeholder2regexp(SERVER_URL_PLACEHOLDER), getUrl())
.replaceAll(placeholder2regexp(USERNAME_PLACEHOLDER), getUsername())
.replaceAll(placeholder2regexp(PASSWORD_PLACEHOLDER), getPassword());
}
private static String placeholder2regexp(String placeholder) {
return placeholder.replaceAll("\\{", "\\\\{");
.replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl())
.replaceAll(Pattern.quote(USERNAME_PLACEHOLDER), encodeUrl(getUsername()))
.replaceAll(Pattern.quote(PASSWORD_PLACEHOLDER), encodeUrl(getPassword()));
}
@Nullable
@@ -158,6 +195,8 @@ public class GenericWebRepository extends BaseRepositoryImpl {
if (!Comparing.equal(getTasksListURL(), that.getTasksListURL())) return false;
if (!Comparing.equal(getTaskPattern(), that.getTaskPattern())) return false;
if (!Comparing.equal(getLoginURL(), that.getLoginURL())) return false;
if (!Comparing.equal(getLoginMethodType(), that.getLoginMethodType())) return false;
if (!Comparing.equal(getGetTasksMethodType(), that.getGetTasksMethodType())) return false;
return true;
}
@@ -184,4 +223,20 @@ public class GenericWebRepository extends BaseRepositoryImpl {
public void setLoginURL(final String loginURL) {
myLoginURL = loginURL;
}
public void setLoginMethodType(final String loginMethodType) {
myLoginMethodType = loginMethodType;
}
public void setGetTasksMethodType(final String getTasksMethodType) {
myGetTasksMethodType = getTasksMethodType;
}
public String getLoginMethodType() {
return myLoginMethodType;
}
public String getGetTasksMethodType() {
return myGetTasksMethodType;
}
}
@@ -1,41 +1,52 @@
package com.intellij.tasks.generic;
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.tasks.config.BaseRepositoryEditor;
import com.intellij.ui.TextFieldWithAutoCompletion;
import com.intellij.ui.TextFieldWithAutoCompletionContributor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import static com.intellij.tasks.generic.GenericWebRepository.*;
import static com.intellij.ui.TextFieldWithAutoCompletion.StringsCompletionProvider;
/**
* User: Evgeny.Zakrevsky
* Date: 10/4/12
*/
public class GenericWebRepositoryEditor extends BaseRepositoryEditor<GenericWebRepository> {
public static final String POST = "POST";
public static final String GET = "GET";
private JBLabel myTasksListURLLabel;
private JBLabel myTaskPatternLabel;
private TextFieldWithAutoCompletion<String> myTasksListURLText;
private TextFieldWithAutoCompletion<String> myTaskPatternText;
private Editor myTaskPatternText;
private JBLabel myLoginURLLabel;
private TextFieldWithAutoCompletion<String> myLoginURLText;
private ComboBox myLoginMethodType;
private ComboBox myGetTasksMethodType;
public GenericWebRepositoryEditor(final Project project,
final GenericWebRepository repository,
final Consumer<GenericWebRepository> changeListener) {
super(project, repository, changeListener);
myUrlLabel.setText("{serverUrl}:");
myUsernameLabel.setText("{username}:");
myPasswordLabel.setText("{password}:");
myUrlLabel.setText("Server URL");
}
@Override
@@ -43,13 +54,16 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditor<GenericWebR
super.loginAnonymouslyChanged(enabled);
myLoginURLLabel.setEnabled(enabled);
myLoginURLText.setEnabled(enabled);
myLoginMethodType.setEnabled(enabled);
}
@Override
public void apply() {
myRepository.setTasksListURL(myTasksListURLText.getText());
myRepository.setTaskPattern(myTaskPatternText.getText());
myRepository.setTaskPattern(myTaskPatternText.getDocument().getText());
myRepository.setLoginURL(myLoginURLText.getText());
myRepository.setLoginMethodType((String)myLoginMethodType.getModel().getSelectedItem());
myRepository.setGetTasksMethodType((String)myGetTasksMethodType.getModel().getSelectedItem());
super.apply();
}
@@ -61,17 +75,36 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditor<GenericWebR
.create(myProject, ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER, USERNAME_PLACEHOLDER, PASSWORD_PLACEHOLDER), null, false,
myRepository.getLoginURL());
installListener(myLoginURLText.getDocument());
myLoginMethodType = new ComboBox(new String[]{GET, POST}, -1);
myLoginMethodType.setSelectedItem(myRepository.getLoginMethodType());
installListener(myLoginMethodType);
JPanel loginPanel = new JPanel(new BorderLayout(UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP));
loginPanel.add(myLoginURLText, BorderLayout.CENTER);
loginPanel.add(myLoginMethodType, BorderLayout.EAST);
myTasksListURLLabel = new JBLabel("Tasks List URL:", SwingConstants.RIGHT);
myTasksListURLText = TextFieldWithAutoCompletion.create(myProject, ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER), null, false,
myRepository.getTasksListURL());
final ArrayList<String> completionList1 = ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER, QUERY_PLACEHOLDER, MAX_COUNT_PLACEHOLDER);
myTasksListURLText = TextFieldWithAutoCompletion.create(myProject, completionList1, null, false, myRepository.getTasksListURL());
installListener(myTasksListURLText.getDocument());
myGetTasksMethodType = new ComboBox(new String[]{GET, POST}, -1);
myGetTasksMethodType.setSelectedItem(myRepository.getGetTasksMethodType());
installListener(myGetTasksMethodType);
JPanel tasksPanel = new JPanel(new BorderLayout(UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP));
tasksPanel.add(myTasksListURLText, BorderLayout.CENTER);
tasksPanel.add(myGetTasksMethodType, BorderLayout.EAST);
myTaskPatternLabel = new JBLabel("Task Pattern:", SwingConstants.RIGHT);
myTaskPatternText =
TextFieldWithAutoCompletion
.create(myProject, ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)"), null, false, myRepository.getTaskPattern());
installListener(myTaskPatternText.getDocument());
final Document document = EditorFactory.getInstance().createDocument(myRepository.getTaskPattern());
myTaskPatternText = EditorFactory.getInstance().createEditor(document, myProject, HtmlFileType.INSTANCE, false);
final ArrayList<String> completionList2 = ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)");
TextFieldWithAutoCompletionContributor
.installCompletion(document, myProject, new StringsCompletionProvider(completionList2, null), true);
installListener(document);
myTaskPatternText.getSettings().setLineMarkerAreaShown(false);
myTaskPatternText.getSettings().setFoldingOutlineShown(false);
//todo correct resizing
//todo completion
//todo completion without whitespace before cursor
String useCompletionText = ". Use " +
KeymapUtil
@@ -79,25 +112,20 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditor<GenericWebR
" for completion.";
return FormBuilder.createFormBuilder().setAlignLabelOnRight(true)
.addLabeledComponent(myLoginURLLabel, myLoginURLText)
.addLabeledComponent(myLoginURLLabel, loginPanel)
.addTooltip(
"Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + USERNAME_PLACEHOLDER + ", " + PASSWORD_PLACEHOLDER + useCompletionText)
.addLabeledComponent(myTasksListURLLabel, myTasksListURLText)
.addTooltip("Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + QUERY_PLACEHOLDER + " (use for faster tasks search)" + useCompletionText)
.addLabeledComponent(myTaskPatternLabel, myTaskPatternText)
.addTooltip("Task pattern should be a regexp with two matching group: ({id}.+?) and ({summary}.+?)" + useCompletionText)
"<html>Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + USERNAME_PLACEHOLDER + ", " + PASSWORD_PLACEHOLDER +
useCompletionText + "</html>")
.addLabeledComponent(myTasksListURLLabel, tasksPanel)
.addTooltip(
"<html>Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + MAX_COUNT_PLACEHOLDER + ", " + QUERY_PLACEHOLDER +
" (use for faster tasks search)" + useCompletionText + "</html>")
.addLabeledComponent(myTaskPatternLabel, myTaskPatternText.getComponent())
.addTooltip(
"<html>Task pattern should be a regexp with two matching groups: ({id}.+?) and ({summary}.+?)" + useCompletionText + "</html>")
.getPanel();
}
@Override
public void dispose() {
super.dispose();
if (myTasksListURLText != null && myTasksListURLText.getEditor() != null)
EditorFactory.getInstance().releaseEditor(myTasksListURLText.getEditor());
if (myLoginURLText.getEditor() != null) EditorFactory.getInstance().releaseEditor(myLoginURLText.getEditor());
if (myTaskPatternText.getEditor() != null) EditorFactory.getInstance().releaseEditor(myTaskPatternText.getEditor());
}
@Override
public void setAnchor(@Nullable final JComponent anchor) {
super.setAnchor(anchor);
@@ -18,7 +18,7 @@ public class GenericWebRepositoryType extends BaseRepositoryType<GenericWebRepos
@NotNull
@Override
public String getName() {
return "Generic Web Repository";
return "Generic";
}
@Override
+2
View File
@@ -38,6 +38,8 @@
</library>
</orderEntry>
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="RegExpSupport" />
<orderEntry type="module" module-name="xml" />
</component>
</module>