/*******************************************************************************
* Copyright (c) 2009 Markus Knittig 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:
* Markus Knittig - initial API and implementation
*******************************************************************************/
package com.googlecode.mylyn.core.client;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
import org.eclipse.mylyn.commons.net.AuthenticationType;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import com.google.gdata.client.projecthosting.IssuesQuery;
import com.google.gdata.client.projecthosting.ProjectHostingService;
import com.google.gdata.data.IEntry;
import com.google.gdata.data.IFeed;
import com.google.gdata.data.Person;
import com.google.gdata.data.projecthosting.IssueCommentsEntry;
import com.google.gdata.data.projecthosting.IssueCommentsFeed;
import com.google.gdata.data.projecthosting.IssuesEntry;
import com.google.gdata.data.projecthosting.IssuesFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import com.googlecode.mylyn.core.GoogleCodeCorePlugin;
import com.googlecode.mylyn.core.util.GoogleCodeUtils;
/**
* Default implementation of {@IGoogleCodeClient} that wraps the GData API
* using {@link ProjectHostingService}.
*/
class GDataGoogleCodeClient implements IGoogleCodeClient {
private final ProjectHostingService projectHostingService;
private final TaskRepository repository;
private final String userName;
/**
* Initializes a new {@link GoogleCodeClient}. Attention this constructor
* may do IO.
*
* @category IO
* @param taskRepository the task repository
* @throws CoreException if the login fails
*/
GDataGoogleCodeClient(TaskRepository taskRepository) throws CoreException {
this.projectHostingService = new ProjectHostingService("googlecode-mylyn-connector");
AuthenticationCredentials credentials = taskRepository.getCredentials(AuthenticationType.REPOSITORY);
if (credentials != null) {
//not anonymous
try {
this.projectHostingService.setUserCredentials(credentials.getUserName(),
credentials.getPassword());
} catch (AuthenticationException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "invalid credentials", e);
throw new CoreException(status);
}
}
this.repository = taskRepository;
this.userName = taskRepository.getUserName();
}
public IssuesFeed getAllIssues(IProgressMonitor mointor) throws CoreException {
String feedUrl = getIssuesUrl();
return this.getFeed(feedUrl, IssuesFeed.class);
}
private String getIssuesUrl() {
return GoogleCodeUtils.getRepositoryFeedUrl(repository.getRepositoryUrl()) + "/issues/full";
}
public IssuesEntry getEntry(String issueId, IProgressMonitor monitor) throws CoreException {
try {
String repositoryUrl = repository.getRepositoryUrl();
URL feedUrl = new URL(GoogleCodeUtils.getRepositoryFeedUrl(repositoryUrl) + "/issues/full/" + issueId);
return this.projectHostingService.getEntry(feedUrl, IssuesEntry.class);
} catch (MalformedURLException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "invalid project URL", e);
throw new CoreException(status);
} catch (IOException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "error sending request or reading the feed", e);
throw new CoreException(status);
} catch (ServiceException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "system error retrieving feed", e);
throw new CoreException(status);
}
}
public IssueCommentsFeed getAllComments(String issueId, IProgressMonitor monitor)
throws CoreException {
String feedUrl = getCommentsUrl(issueId);
return getFeed(feedUrl, IssueCommentsFeed.class);
}
private String getCommentsUrl(String issueId) {
String repositoryUrl = repository.getRepositoryUrl();
return GoogleCodeUtils.getRepositoryFeedUrl(repositoryUrl) + "/issues/" + issueId + "/comments/full";
}
private <F extends IFeed> F getFeed(String feedUrl, Class<F> feedClass) throws CoreException {
try {
return this.projectHostingService.getFeed(new URL(feedUrl), feedClass);
} catch (MalformedURLException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "invalid project URL", e);
throw new CoreException(status);
} catch (IOException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "error sending request or reading the feed", e);
throw new CoreException(status);
} catch (ServiceException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "system error retrieving feed", e);
throw new CoreException(status);
}
}
private <F extends IFeed> F queryFeed(IssuesQuery query, Class<F> feedClass) throws CoreException {
try {
return this.projectHostingService.query(query, feedClass);
} catch (MalformedURLException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "invalid project URL", e);
throw new CoreException(status);
} catch (IOException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "error sending request or reading the feed", e);
throw new CoreException(status);
} catch (ServiceException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "system error retrieving feed", e);
throw new CoreException(status);
}
}
private <E extends IEntry> E insert(String feedUrl, E entry) throws CoreException {
try {
return this.projectHostingService.insert(new URL(feedUrl), entry);
} catch (MalformedURLException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "invalid project URL", e);
throw new CoreException(status);
} catch (IOException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "error sending request or reading the feed", e);
throw new CoreException(status);
} catch (ServiceException e) {
Status status = new Status(IStatus.ERROR, GoogleCodeCorePlugin.PLUGIN_ID, "system error retrieving feed", e);
throw new CoreException(status);
}
}
public IssuesEntry createIssue(IssuesEntry entry, IProgressMonitor monitor) throws CoreException {
return insert(getIssuesUrl(), entry);
}
public Person getCurrentUser() {
Person person = new Person();
person.setName(this.userName);
return person;
}
public IssueCommentsEntry updateIssue(String issueId, IssueCommentsEntry entry, IProgressMonitor monitor)
throws CoreException {
return insert(getCommentsUrl(issueId), entry);
}
public IssuesFeed getQueryIssues(IssuesQuery query, IProgressMonitor monitor)
throws CoreException {
return queryFeed(query, IssuesFeed.class);
}
public IssuesQuery createNewIssuesQuery() {
String issuesUrl = this.getIssuesUrl();
try {
return new IssuesQuery(new URL(issuesUrl));
} catch (MalformedURLException e) {
throw new RuntimeException("invalid url:" + issuesUrl, e);
}
}
public String createIssueId(String issueId) {
return getIssuesUrl() + '/' + issueId;
}
}