blob: f3be666bf6aeb42325e1e7930e035f1db374dae5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 Steffen Pingel and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* 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;
}
}