diff options
author | Steffen Pingel | 2013-04-15 13:57:55 +0000 |
---|---|---|
committer | Steffen Pingel | 2013-04-16 00:06:09 +0000 |
commit | a0fad711183c44b82edcb5df816856beaddf5079 (patch) | |
tree | efab01ddbfb5a3e9a7a730ef6c73578b87c5f51e /org.eclipse.mylyn.trac.core | |
parent | dab45ebad385f4ee7320c58a7462995eafe6af35 (diff) | |
download | org.eclipse.mylyn.tasks-a0fad711183c44b82edcb5df816856beaddf5079.tar.gz org.eclipse.mylyn.tasks-a0fad711183c44b82edcb5df816856beaddf5079.tar.xz org.eclipse.mylyn.tasks-a0fad711183c44b82edcb5df816856beaddf5079.zip |
400396: fix additional Trac fixture test failures
* Handle empty value when parsing tickets on 1.0 in web mode.
* Ensure correct token is submitted for form based authentication.
* Exclude tests that don't apply in specialized fixtures.
Change-Id: Idc7ae6934a3a6a590fd867f995a69d537690bb28
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=400396
Diffstat (limited to 'org.eclipse.mylyn.trac.core')
3 files changed, 128 insertions, 58 deletions
diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/AbstractTracClient.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/AbstractTracClient.java index a33495b56..b44583f78 100644 --- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/AbstractTracClient.java +++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/AbstractTracClient.java @@ -98,9 +98,22 @@ public abstract class AbstractTracClient implements ITracClient { protected void authenticateAccountManager(HttpClient httpClient, HostConfiguration hostConfiguration, AuthenticationCredentials credentials, IProgressMonitor monitor) throws IOException, TracLoginException { + String formToken = getFormToken(httpClient); + authenticateAccountManagerInternal(httpClient, hostConfiguration, credentials, monitor, formToken); + + // form token is based on a cookie which may have changed due to the login post + // re-try with new token to ensure we are logging in with the right token, otherwise user won't be logged in + String newFormToken = getFormToken(httpClient); + if (formToken.length() == 0 && !formToken.equals(newFormToken)) { + authenticateAccountManagerInternal(httpClient, hostConfiguration, credentials, monitor, newFormToken); + } + } + + public void authenticateAccountManagerInternal(HttpClient httpClient, HostConfiguration hostConfiguration, + AuthenticationCredentials credentials, IProgressMonitor monitor, String formToken) throws IOException, + TracLoginException { PostMethod post = new PostMethod(WebUtil.getRequestPath(repositoryUrl + LOGIN_URL)); post.setFollowRedirects(false); - String formToken = getFormToken(httpClient); NameValuePair[] data = { new NameValuePair("referer", ""), //$NON-NLS-1$ //$NON-NLS-2$ new NameValuePair("user", credentials.getUserName()), //$NON-NLS-1$ new NameValuePair("password", credentials.getPassword()), new NameValuePair("__FORM_TOKEN", formToken) }; //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/TracWebClient.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/TracWebClient.java index 078a16f2a..9660753cf 100644 --- a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/TracWebClient.java +++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/TracWebClient.java @@ -37,10 +37,7 @@ import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.lang.StringEscapeUtils; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.commons.net.AbstractWebLocation; import org.eclipse.mylyn.commons.net.AuthenticationCredentials; import org.eclipse.mylyn.commons.net.AuthenticationType; @@ -51,7 +48,6 @@ import org.eclipse.mylyn.commons.net.Policy; import org.eclipse.mylyn.commons.net.SslCertificateException; import org.eclipse.mylyn.commons.net.UnsupportedRequestException; import org.eclipse.mylyn.commons.net.WebUtil; -import org.eclipse.mylyn.internal.trac.core.TracCorePlugin; import org.eclipse.mylyn.internal.trac.core.model.TracComment; import org.eclipse.mylyn.internal.trac.core.model.TracComponent; import org.eclipse.mylyn.internal.trac.core.model.TracMilestone; @@ -68,7 +64,6 @@ import org.eclipse.mylyn.internal.trac.core.model.TracTicketStatus; import org.eclipse.mylyn.internal.trac.core.model.TracTicketType; import org.eclipse.mylyn.internal.trac.core.model.TracVersion; import org.eclipse.mylyn.internal.trac.core.util.TracHttpClientTransportFactory.TracHttpException; -import org.eclipse.mylyn.internal.trac.core.util.TracUtil; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -480,58 +475,23 @@ public class TracWebClient extends AbstractTracClient { } } - public void search(TracSearch query, List<TracTicket> tickets, IProgressMonitor monitor) throws TracException { + public void search(TracSearch query, List<TracTicket> result, IProgressMonitor monitor) throws TracException { GetMethod method = connect(repositoryUrl + ITracClient.QUERY_URL + query.toUrl(), monitor); try { InputStream in = WebUtil.getResponseBodyAsStream(method, monitor); try { BufferedReader reader = new BufferedReader(new InputStreamReader(in, method.getResponseCharSet())); - String line; - Map<String, String> constantValues = getExactMatchValues(query); - - // first line contains names of returned ticket fields - line = reader.readLine(); - if (line == null) { - throw new InvalidTicketException(); - } - // the utf-8 output in Trac 1.0 starts with a byte-order mark which - // is passed to the tokenizer since it would otherwise end up in the first token - StringTokenizer t = new StringTokenizer(line, "\ufeff\t"); //$NON-NLS-1$ - Key[] fields = new Key[t.countTokens()]; - for (int i = 0; i < fields.length; i++) { - fields[i] = Key.fromKey(t.nextToken()); - } - - // create a ticket for each following line of output - while ((line = reader.readLine()) != null) { - t = new StringTokenizer(line, "\t"); //$NON-NLS-1$ - TracTicket ticket = new TracTicket(); - for (int i = 0; i < fields.length && t.hasMoreTokens(); i++) { - if (fields[i] != null) { - try { - if (fields[i] == Key.ID) { - ticket.setId(Integer.parseInt(t.nextToken())); - } else if (fields[i] == Key.TIME) { - ticket.setCreated(TracUtil.parseDate(Integer.parseInt(t.nextToken()))); - } else if (fields[i] == Key.CHANGE_TIME) { - ticket.setLastChanged(TracUtil.parseDate(Integer.parseInt(t.nextToken()))); - } else { - ticket.putBuiltinValue(fields[i], parseTicketValue(t.nextToken())); - } - } catch (NumberFormatException e) { - StatusHandler.log(new Status(IStatus.WARNING, TracCorePlugin.ID_PLUGIN, - "Error parsing response: '" + line + "'", e)); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } + WebSearchResultParser parser = new WebSearchResultParser(); + parser.parse(reader); + Map<String, String> constantValues = getExactMatchValues(query); + for (TracTicket ticket : parser.getTickets()) { if (ticket.isValid()) { for (String key : constantValues.keySet()) { - ticket.putValue(key, parseTicketValue(constantValues.get(key))); + ticket.putValue(key, WebSearchResultParser.parseTicketValue(constantValues.get(key))); } - - tickets.add(ticket); + result.add(ticket); } } } finally { @@ -545,16 +505,6 @@ public class TracWebClient extends AbstractTracClient { } /** - * Trac has sepcial encoding rules for the returned output: None is represented by "--". - */ - private String parseTicketValue(String value) { - if ("--".equals(value)) { //$NON-NLS-1$ - return ""; //$NON-NLS-1$ - } - return value; - } - - /** * Extracts constant values from <code>query</code>. The Trac query script does not return fields that matched * exactly againt a single value. */ diff --git a/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/WebSearchResultParser.java b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/WebSearchResultParser.java new file mode 100644 index 000000000..fdb2c8e4b --- /dev/null +++ b/org.eclipse.mylyn.trac.core/src/org/eclipse/mylyn/internal/trac/core/client/WebSearchResultParser.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2013 Steffen Pingel and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Steffen Pingel - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.trac.core.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.mylyn.internal.trac.core.model.TracTicket; +import org.eclipse.mylyn.internal.trac.core.model.TracTicket.Key; +import org.eclipse.mylyn.internal.trac.core.util.TracUtil; + +public class WebSearchResultParser { + + private final List<TracTicket> tickets = new ArrayList<TracTicket>(); + + public void parse(BufferedReader reader) throws IOException, TracException { + Key[] fields = parseHeader(reader); + parseTickets(reader, fields); + } + + public void parseTickets(BufferedReader reader, Key[] fields) throws IOException, InvalidTicketException { + // create a ticket for each following line of output + String line; + while ((line = reader.readLine()) != null) { + TracTicket ticket = new TracTicket(); + tickets.add(ticket); + + // include delimiters to detect empty values + StringTokenizer t = new StringTokenizer(line, "\t", true); //$NON-NLS-1$ + for (int i = 0; i < fields.length && t.hasMoreTokens(); i++) { + String nextToken = t.nextToken(); + if (nextToken.equals("\t")) { //$NON-NLS-1$ + // process empty value + nextToken = ""; //$NON-NLS-1$ + } else if (t.hasMoreTokens()) { + // skip delimiter + t.nextToken(); + } + Key key = fields[i]; + if (key != null) { + assignTicketValue(ticket, key, nextToken); + } + } + } + } + + public void assignTicketValue(TracTicket ticket, Key key, String value) throws InvalidTicketException { + try { + if (key == Key.ID) { + ticket.setId(Integer.parseInt(value)); + } else if (key == Key.TIME) { + ticket.setCreated(TracUtil.parseDate(Integer.parseInt(value))); + } else if (key == Key.CHANGE_TIME) { + ticket.setLastChanged(TracUtil.parseDate(Integer.parseInt(value))); + } else { + ticket.putBuiltinValue(key, parseTicketValue(value)); + } + } catch (NumberFormatException e) { + // ignore to avoid spamming log +// StatusHandler.log(new Status(IStatus.WARNING, TracCorePlugin.ID_PLUGIN, NLS.bind( +// "Error parsing response: ''{0}''", line), e)); //$NON-NLS-1$ + } + } + + private Key[] parseHeader(BufferedReader reader) throws IOException, InvalidTicketException { + // first line contains names of returned ticket fields + String line = reader.readLine(); + if (line == null) { + throw new InvalidTicketException(); + } + // the utf-8 output in Trac 1.0 starts with a byte-order mark which + // is passed to the tokenizer since it would otherwise end up in the first token + StringTokenizer t = new StringTokenizer(line, "\ufeff\t"); //$NON-NLS-1$ + Key[] fields = new Key[t.countTokens()]; + for (int i = 0; i < fields.length; i++) { + fields[i] = Key.fromKey(t.nextToken()); + } + return fields; + } + + public List<TracTicket> getTickets() { + return tickets; + } + + /** + * Trac has special encoding rules for the returned output: None is represented by "--". + */ + public static String parseTicketValue(String value) { + if ("--".equals(value)) { //$NON-NLS-1$ + return null; + } + return value; + } + +} |