diff options
62 files changed, 3204 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.github-feature/.gitignore b/org.eclipse.mylyn.github-feature/.gitignore new file mode 100644 index 00000000..d567ba01 --- /dev/null +++ b/org.eclipse.mylyn.github-feature/.gitignore @@ -0,0 +1,2 @@ +bin +target diff --git a/org.eclipse.mylyn.github-feature/.project b/org.eclipse.mylyn.github-feature/.project new file mode 100644 index 00000000..54d8c9d5 --- /dev/null +++ b/org.eclipse.mylyn.github-feature/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.mylyn.github-feature</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.FeatureBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.FeatureNature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.mylyn.github-feature/build.properties b/org.eclipse.mylyn.github-feature/build.properties new file mode 100644 index 00000000..82ab19c6 --- /dev/null +++ b/org.eclipse.mylyn.github-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml
diff --git a/org.eclipse.mylyn.github-feature/feature.xml b/org.eclipse.mylyn.github-feature/feature.xml new file mode 100644 index 00000000..cac9ad47 --- /dev/null +++ b/org.eclipse.mylyn.github-feature/feature.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="org.eclipse.mylyn.github.feature" + label="Eclipse EGit Mylyn GitHub Feature" + version="0.1.0.qualifier" + provider-name="Eclipse EGit"> + + <description url="http://github.com/smilebase/org.eclipse.mylyn.github"> + Eclipse Mylyn to GitHub connector. + </description> + + <copyright url="http://smilebase.github.com/org.eclipse.mylyn.github/"> + Copyright 2009 + +Christian Trutz (christian.trutz@gmail.com) +Brian Gianforcaro (b.gianfo@gmail.com) + </copyright> + + <license url="http://www.apache.org/licenses/LICENSE-2.0.html"> + Apache License +Version 2.0, January 2004 + </license> + + <requires> + <import plugin="org.eclipse.core.runtime" version="3.5.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui" version="3.5.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui.forms" version="3.4.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.mylyn.tasks.core" version="3.2.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.mylyn.tasks.ui" version="3.2.0" match="greaterOrEqual"/> + </requires> + + <plugin + id="org.eclipse.mylyn.github.core" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.mylyn.github.ui" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + +</feature> diff --git a/org.eclipse.mylyn.github-feature/pom.xml b/org.eclipse.mylyn.github-feature/pom.xml new file mode 100644 index 00000000..f782928c --- /dev/null +++ b/org.eclipse.mylyn.github-feature/pom.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> + + 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 +--> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <parent> + <artifactId>github-parent</artifactId> + <groupId>org.eclipse.mylyn.github</groupId> + <version>0.1.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>feature</artifactId> + <packaging>eclipse-feature</packaging> + <name>Eclipse EGit Mylyn GitHub Feature (Incubation)</name> +</project> diff --git a/org.eclipse.mylyn.github-site/.gitignore b/org.eclipse.mylyn.github-site/.gitignore new file mode 100644 index 00000000..d567ba01 --- /dev/null +++ b/org.eclipse.mylyn.github-site/.gitignore @@ -0,0 +1,2 @@ +bin +target diff --git a/org.eclipse.mylyn.github-site/.project b/org.eclipse.mylyn.github-site/.project new file mode 100644 index 00000000..b96eff24 --- /dev/null +++ b/org.eclipse.mylyn.github-site/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.mylyn.github-site</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.UpdateSiteBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.UpdateSiteNature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.mylyn.github-site/assembly.xml b/org.eclipse.mylyn.github-site/assembly.xml new file mode 100644 index 00000000..907a49c0 --- /dev/null +++ b/org.eclipse.mylyn.github-site/assembly.xml @@ -0,0 +1,13 @@ +<assembly> + <id>site</id> + <formats> + <format>zip</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <fileSets> + <fileSet> + <directory>${project.build.directory}/site</directory> + <outputDirectory>/</outputDirectory> + </fileSet> + </fileSets> +</assembly> diff --git a/org.eclipse.mylyn.github-site/pom.xml b/org.eclipse.mylyn.github-site/pom.xml new file mode 100644 index 00000000..69ad2ae9 --- /dev/null +++ b/org.eclipse.mylyn.github-site/pom.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> + + 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 +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.mylyn.github</groupId> + <artifactId>github-parent</artifactId> + <version>0.1.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.mylyn.github-updatesite</artifactId> + <packaging>eclipse-update-site</packaging> + + <name>Eclipse EGit Mylyn GitHub Repository (Incubation)</name> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.2-beta-4</version> + <configuration> + <descriptors> + <descriptor>assembly.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-resources</id> + <phase>validate</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${basedir}/target/site</outputDirectory> + <resources> + <resource> + <directory>.</directory> + <includes> + <include>index.html</include> + <include>web/*</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/org.eclipse.mylyn.github-site/site.xml b/org.eclipse.mylyn.github-site/site.xml new file mode 100644 index 00000000..617b6a77 --- /dev/null +++ b/org.eclipse.mylyn.github-site/site.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<site> + <feature url="features/org.eclipse.mylyn.github.feature_0.0.0.qualifier.jar" id="org.eclipse.mylyn.github.feature" version="0.0.0"/> +</site> diff --git a/org.eclipse.mylyn.github.core/.classpath b/org.eclipse.mylyn.github.core/.classpath new file mode 100644 index 00000000..64c5e31b --- /dev/null +++ b/org.eclipse.mylyn.github.core/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/org.eclipse.mylyn.github.core/.gitignore b/org.eclipse.mylyn.github.core/.gitignore new file mode 100644 index 00000000..d567ba01 --- /dev/null +++ b/org.eclipse.mylyn.github.core/.gitignore @@ -0,0 +1,2 @@ +bin +target diff --git a/org.eclipse.mylyn.github.core/.project b/org.eclipse.mylyn.github.core/.project new file mode 100644 index 00000000..3ae827bb --- /dev/null +++ b/org.eclipse.mylyn.github.core/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.github.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.github.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.github.core/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..315bf27c --- /dev/null +++ b/org.eclipse.mylyn.github.core/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Tue Jun 09 20:22:30 CEST 2009
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.github.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.github.core/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 00000000..5b9dcff1 --- /dev/null +++ b/org.eclipse.mylyn.github.core/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,3 @@ +#Tue Jun 09 20:22:30 CEST 2009
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.github.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.github.core/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..1d6b3c18 --- /dev/null +++ b/org.eclipse.mylyn.github.core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Fri Jul 30 10:22:35 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/org.eclipse.mylyn.github.core/META-INF/MANIFEST.MF b/org.eclipse.mylyn.github.core/META-INF/MANIFEST.MF new file mode 100644 index 00000000..f05d1b0d --- /dev/null +++ b/org.eclipse.mylyn.github.core/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: EGit Mylyn GitHub Core Plug-in (Incubation) +Bundle-SymbolicName: org.eclipse.mylyn.github.core +Bundle-Version: 0.1.0.qualifier +Bundle-Vendor: Eclipse EGit +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.eclipse.mylyn.github.internal;x-friends:="org.eclipse.mylyn.github.ui" +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", + org.eclipse.mylyn.tasks.core;bundle-version="3.2.0", + org.eclipse.mylyn.commons.net;bundle-version="3.2.0" +Import-Package: com.google.gson;version="1.6.0", + org.apache.commons.logging diff --git a/org.eclipse.mylyn.github.core/build.properties b/org.eclipse.mylyn.github.core/build.properties new file mode 100644 index 00000000..e1e6580a --- /dev/null +++ b/org.eclipse.mylyn.github.core/build.properties @@ -0,0 +1,3 @@ +source.. = src/
+output.. = bin/
+bin.includes = META-INF/
\ No newline at end of file diff --git a/org.eclipse.mylyn.github.core/pom.xml b/org.eclipse.mylyn.github.core/pom.xml new file mode 100644 index 00000000..12b22700 --- /dev/null +++ b/org.eclipse.mylyn.github.core/pom.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> + + 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 +--> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <parent> + <groupId>org.eclipse.mylyn.github</groupId> + <artifactId>github-parent</artifactId> + <version>0.1.0-SNAPSHOT</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>core</artifactId> + <packaging>eclipse-plugin</packaging> + <name>Eclipse EGit Mylyn GitHub Core (Incubation)</name> +</project> diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHub.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHub.java new file mode 100644 index 00000000..708f39c5 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHub.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; + +public class GitHub { + public static final String BUNDLE_ID = "org.eclipse.mylyn.github.core"; + public static final String CONNECTOR_KIND = "github"; + + public static final String HTTP_WWW_GITHUB_ORG = "http://www.github.org"; + public static final String HTTP_GITHUB_COM = "http://github.com"; + + public static final Pattern URL_PATTERN = Pattern.compile("(?:"+Pattern.quote(HTTP_WWW_GITHUB_ORG)+"|"+Pattern.quote(HTTP_GITHUB_COM)+")/([^/]+)/([^/]+)"); + + public static IStatus createStatus(int severity, String message) { + return new Status(severity, BUNDLE_ID, message); + } + + public static IStatus createStatus(int severity, String message, Throwable e) { + return new Status(severity, BUNDLE_ID, message, e); + } + + public static IStatus createErrorStatus(String message) { + return createStatus(IStatus.ERROR, message); + } + + public static IStatus createErrorStatus(String message, Throwable t) { + return createStatus(IStatus.ERROR, message, t); + } + + public static IStatus createErrorStatus(Throwable e) { + return createStatus(IStatus.ERROR, "Unexpected error: " + + e.getMessage(), e); + } + + public static ILog getLog() { + return Platform.getLog(Platform.getBundle(BUNDLE_ID)); + } + + public static void logError(String message,Throwable t) { + getLog().log(createErrorStatus(message, t)); + } + + public static void logError(Throwable t) { + getLog().log(createErrorStatus(t.getMessage(), t)); + } + + public static String computeTaskRepositoryUser(String repositoryUrl) { + Matcher matcher = URL_PATTERN.matcher(repositoryUrl); + if (matcher.matches()) { + return matcher.group(1); + } + return null; + } + + public static String computeTaskRepositoryProject(String repositoryUrl) { + Matcher matcher = URL_PATTERN.matcher(repositoryUrl); + if (matcher.matches()) { + return matcher.group(2); + } + return null; + } + + /** + * uses github.com + * @see #createGitHubUrlAlternate(String, String) + */ + public static String createGitHubUrl(String user,String project) { + return HTTP_GITHUB_COM+'/'+user+'/'+project; + } + + /** + * Uses www.github.org + * @see #createGitHubUrl(String, String) + */ + public static String createGitHubUrlAlternate(String user,String project) { + return HTTP_WWW_GITHUB_ORG+'/'+user+'/'+project; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubCredentials.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubCredentials.java new file mode 100644 index 00000000..19cd580c --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubCredentials.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.net.AuthenticationType; +import org.eclipse.mylyn.tasks.core.TaskRepository; + +public class GitHubCredentials { + private final String username; + private final String apiToken; + + + public GitHubCredentials(String username, String apiToken) { + this.username = username; + this.apiToken = apiToken; + } + + public GitHubCredentials(AuthenticationCredentials credentials) { + this(credentials.getUserName(),credentials.getPassword()); + } + + public static GitHubCredentials create(TaskRepository repository) { + return new GitHubCredentials(repository.getCredentials(AuthenticationType.REPOSITORY)); + } + + public String getUsername() { + return username; + } + public String getApiToken() { + return apiToken; + } + +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubIssue.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubIssue.java new file mode 100644 index 00000000..9a989e00 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubIssue.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + + +/** + * GitHub Issue object to hold all the properties of an individual issue. + */ +public class GitHubIssue { + + private String number; + + private String user; + + private String title; + + private String body; + + /** + * open, closed + */ + private String state; + + private String created_at; + private String updated_at; + private String closed_at; + + /** + * Create a new GitHub Issue Object + * + * @param number + * - GitHub Issue number + * @param user + * - User who the posted issue belongs too. + * @param title + * - Issue title + * @param body + * - The text body of the issue; + */ + public GitHubIssue(final String number, final String user, + final String title, final String body) { + this.number = number; + this.user = user; + this.title = title; + this.body = body; + } + + /** + * Create a GitHub Issue with all parameters set to empty. + */ + public GitHubIssue() { + this.number = ""; + this.user = ""; + this.title = ""; + this.body = ""; + } + + /** + * Getter for the issue number + * + * @return The string representation of the issue number. + */ + public String getNumber() { + return number; + } + + /** + * Set the issues's number + * + * @param number + * - String representation of the number to set to. + */ + public void setNumber(final String number) { + this.number = number; + } + + /** + * Getter for the user name of the issue creator + * + * @return The user name of the person who created the issue + */ + public String getUser() { + return user; + } + + /** + * Set the issue user name to + * + * @param user + * - The user name to set the issue creator to. + */ + public void setUser(final String user) { + this.user = user; + } + + /** + * Getter for the issue Title + * + * @return The title text of this issue + */ + public String getTitle() { + return title; + } + + /** + * @param title + */ + public void setTitle(final String title) { + this.title = title; + } + + /** + * Getter of the body of an issue + * + * @return The text body of the issue + */ + public String getBody() { + return body; + } + + /** + * Setter for the body of an issue + * + * @param body + * - The text body to set for this issue + */ + public void setBody(final String body) { + this.body = body; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCreated_at() { + return created_at; + } + + public void setCreated_at(String created_at) { + this.created_at = created_at; + } + + public String getUpdated_at() { + return updated_at; + } + + public void setUpdated_at(String updated_at) { + this.updated_at = updated_at; + } + + public String getClosed_at() { + return closed_at; + } + + public void setClosed_at(String closed_at) { + this.closed_at = closed_at; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubIssues.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubIssues.java new file mode 100644 index 00000000..02100590 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubIssues.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +/** + * Container of multiple GitHub Issues, used when returning JSON objects + */ +public class GitHubIssues { + + private GitHubIssue[] issues; + + /** + * Getter for all issues inside this object + * + * @return The array of individual GitHub Issues + */ + public GitHubIssue[] getIssues() { + return issues; + } + +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubRepositoryConnector.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubRepositoryConnector.java new file mode 100644 index 00000000..c263cb9a --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubRepositoryConnector.java @@ -0,0 +1,217 @@ +/*******************************************************************************
+ * Copyright (c) 2011 Red Hat 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:
+ * David Green <david.green@tasktop.com> - initial contribution
+ * Christian Trutz <christian.trutz@gmail.com> - initial contribution
+ * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution
+ *******************************************************************************/
+package org.eclipse.mylyn.github.internal;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+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.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
+import org.eclipse.mylyn.tasks.core.data.TaskMapper;
+import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession;
+
+/**
+ * GitHub connector.
+ */
+public class GitHubRepositoryConnector extends AbstractRepositoryConnector {
+
+
+ /**
+ * GitHub kind.
+ */
+ protected static final String KIND = GitHub.CONNECTOR_KIND;
+
+ /**
+ * GitHub service which creates, lists, deletes, etc. GitHub tasks.
+ */
+ private final GitHubService service = new GitHubService();
+
+ /**
+ * GitHub specific {@link AbstractTaskDataHandler}.
+ */
+ private final GitHubTaskDataHandler taskDataHandler;
+
+ public GitHubRepositoryConnector() {
+ taskDataHandler = new GitHubTaskDataHandler(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return always {@code true}
+ */
+ @Override
+ public boolean canCreateNewTask(TaskRepository repository) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return always {@code true}
+ */
+ @Override
+ public boolean canCreateTaskFromKey(TaskRepository repository) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see #KIND
+ */
+ @Override
+ public String getConnectorKind() {
+ return KIND;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getLabel() {
+ return "GitHub";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AbstractTaskDataHandler getTaskDataHandler() {
+ return this.taskDataHandler;
+ }
+
+ @Override
+ public IStatus performQuery(TaskRepository repository,
+ IRepositoryQuery query, TaskDataCollector collector,
+ ISynchronizationSession session, IProgressMonitor monitor) {
+
+ IStatus result = Status.OK_STATUS;
+ String queryStatus = query.getAttribute("status");
+
+ String[] statuses;
+ if (queryStatus.equals("all")) {
+ statuses = new String[] {"open","closed"};
+ } else {
+ statuses = new String[] { queryStatus };
+ }
+
+ monitor.beginTask("Querying repository ...", statuses.length);
+ try {
+ String user = GitHub.computeTaskRepositoryUser(repository.getUrl());
+ String project = GitHub.computeTaskRepositoryProject(repository.getUrl());
+
+ // perform query
+
+ for (String status: statuses) {
+ GitHubIssues issues = service.searchIssues(user,project,
+ status, query
+ .getAttribute("queryText"));
+
+ // collect task data
+ for (GitHubIssue issue : issues.getIssues()) {
+ TaskData taskData = taskDataHandler.createPartialTaskData(
+ repository, monitor,user, project, issue);
+ collector.accept(taskData);
+ }
+ monitor.worked(1);
+ }
+
+ result = Status.OK_STATUS;
+ } catch (GitHubServiceException e) {
+ result = GitHub.createErrorStatus(e);
+ }
+
+ monitor.done();
+ return result;
+ }
+
+
+ @Override
+ public TaskData getTaskData(TaskRepository repository, String taskId,
+ IProgressMonitor monitor) throws CoreException {
+
+ String user = GitHub.computeTaskRepositoryUser(repository.getUrl());
+ String project = GitHub.computeTaskRepositoryProject(repository.getUrl());
+
+ try {
+ GitHubIssue issue = service.showIssue(user, project, taskId);
+ TaskData taskData = taskDataHandler.createTaskData(repository, monitor, user, project, issue);
+
+ return taskData;
+ } catch (GitHubServiceException e) {
+ throw new CoreException(GitHub.createErrorStatus(e));
+ }
+ }
+
+
+ @Override
+ public String getRepositoryUrlFromTaskUrl(String taskFullUrl) {
+ if (taskFullUrl != null) {
+ Matcher matcher = Pattern.compile("(http://.+?)/issues/issue/([^/]+)").matcher(taskFullUrl);
+ if (matcher.matches()) {
+ return matcher.group(1);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getTaskIdFromTaskUrl(String taskFullUrl) {
+ if (taskFullUrl != null) {
+ Matcher matcher = Pattern.compile(".+?/issues/issue/([^/]+)").matcher(taskFullUrl);
+ if (matcher.matches()) {
+ return matcher.group(1);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getTaskUrl(String repositoryUrl, String taskId) {
+ return repositoryUrl+"/issues/issue/"+taskId;
+ }
+
+ @Override
+ public void updateRepositoryConfiguration(TaskRepository taskRepository,
+ IProgressMonitor monitor) throws CoreException {
+ }
+
+ @Override
+ public boolean hasTaskChanged(TaskRepository repository, ITask task,
+ TaskData taskData) {
+ return new TaskMapper(taskData).hasChanges(task);
+ }
+
+ @Override
+ public void updateTaskFromTaskData(TaskRepository taskRepository,
+ ITask task, TaskData taskData) {
+ if (!taskData.isNew()) {
+ task.setUrl(getTaskUrl(taskRepository.getUrl(), taskData.getTaskId()));
+ }
+ new TaskMapper(taskData).applyTo(task);
+ }
+
+ public GitHubService getService() {
+ return service;
+ }
+}
diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubService.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubService.java new file mode 100644 index 00000000..07d884d8 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubService.java @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import java.io.IOException; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.google.gson.Gson; + +/** + * Facility to perform API operations on a GitHub issue tracker. + */ +public class GitHubService { + + private static final Log LOG = LogFactory.getLog(GitHubService.class); + + /** + * GitHub Issues API Documentation: http://develop.github.com/p/issues.html + */ + private final String gitURLBase = "https://github.com/api/v2/json/"; + + private final String gitIssueRoot = "issues/"; + private final String gitUserRoot = "user/"; + + private final HttpClient httpClient; + + private final Gson gson; + + /** + * Helper class, describing all of the possible GitHub API actions. + */ + private final static String OPEN = "open/"; // Implemented + private static final String REOPEN = "reopen/"; + private final static String CLOSE = "close/"; + private final static String EDIT = "edit/"; // Implemented + // private final static String VIEW = "view/"; + private final static String SHOW = "show/"; // :user/:repo/:number + private final static String LIST = "list/"; // Implemented + private final static String SEARCH = "search/"; // Implemented + // private final static String REOPEN = "reopen/"; + // private final static String COMMENT = "comment/"; + private final static String ADD_LABEL = "label/add/"; // Implemented + private final static String REMOVE_LABEL = "label/remove/"; // Implemented + + private static final String EMAILS = "emails"; + + + /** + * Constructor, create the client and JSON/Java interface object. + */ + public GitHubService() { + httpClient = new HttpClient(); + gson = new Gson(); + } + + /** + * Verify that the provided credentials are correct + * @param credentials + * + * @return true if and only if the credentials are correct + */ + public boolean verifyCredentials(GitHubCredentials credentials) throws GitHubServiceException { + PostMethod method = null; + + boolean success = false; + + try { + method = new PostMethod(gitURLBase + gitUserRoot + EMAILS); + + // Set the users login and API token + final NameValuePair login = new NameValuePair("login", credentials.getUsername()); + final NameValuePair token = new NameValuePair("token", credentials.getApiToken()); + method.setRequestBody(new NameValuePair[] { login, token }); + + executeMethod(method); + + // if we reach here we know that credentials were good + success = true; + } catch (PermissionDeniedException e) { + // if we provide bad credentials, GitHub will return 403 or 401 + return false; + } catch (GitHubServiceException e) { + throw e; + } catch (final RuntimeException runtimeException) { + throw runtimeException; + } catch (final Exception exception) { + throw new GitHubServiceException(exception); + } finally { + if (method != null) + method.releaseConnection(); + } + return success; + } + + /** + * Search the GitHub Issues API for a given search term + * + * @param user + * - The user the repository is owned by + * @param repo + * - The Git repository where the issue tracker is hosted + * @param state + * - The issue state you want to filter your search by + * @param searchTerm + * - The text search term to find in the issues. + * + * @return A GitHubIssues object containing all issues from the search + * results + * + * @throws GitHubServiceException + * + * @note API Doc: /issues/search/:user/:repo/:state/:search_term + */ + public GitHubIssues searchIssues(final String user, final String repo, + final String state, final String searchTerm) + throws GitHubServiceException { + GitHubIssues issues = null; + GetMethod method = null; + try { + // build HTTP GET method + if (searchTerm.trim().length() == 0) { // no search term: list all + method = new GetMethod(gitURLBase + gitIssueRoot + LIST + user + + "/" + repo + "/" + state); + } else { + method = new GetMethod(gitURLBase + gitIssueRoot + SEARCH + + user + "/" + repo + "/" + state + "/" + searchTerm); + } + // execute HTTP GET method + executeMethod(method); + // transform JSON to Java object + issues = gson.fromJson(new String(method.getResponseBody()), + GitHubIssues.class); + } catch (GitHubServiceException e) { + throw e; + } catch (final RuntimeException runtimeException) { + throw runtimeException; + } catch (final Exception exception) { + throw new GitHubServiceException(exception); + } finally { + if (method != null) + method.releaseConnection(); + } + return issues; + } + + /** + * Add a label to an existing GitHub issue. + * + * @param user + * - The user the repository is owned by + * @param repo + * - The git repository where the issue tracker is hosted + * @param label + * - The text label to add to the existing issue + * @param issueNumber + * - The issue number to add a label to + * @param api + * - The users GitHub + * + * @return A boolean representing the success of the function call + * + * @throws GitHubServiceException + * + * @note API Doc: issues/label/add/:user/:repo/:label/:number API POST + * Variables: login, api-token + */ + public boolean addLabel(final String user, final String repo, + final String label, final int issueNumber,final GitHubCredentials credentials) + throws GitHubServiceException { + PostMethod method = null; + + boolean success = false; + + try { + // build HTTP GET method + method = new PostMethod(gitURLBase + gitIssueRoot + ADD_LABEL + + user + "/" + repo + "/" + label + "/" + + Integer.toString(issueNumber)); + + // Set the users login and API token + final NameValuePair login = new NameValuePair("login", credentials.getUsername()); + final NameValuePair token = new NameValuePair("token", credentials.getApiToken()); + method.setRequestBody(new NameValuePair[] { login, token }); + + // execute HTTP GET method + executeMethod(method); + // Check the response, make sure the action was successful + final String response = method.getResponseBodyAsString(); + if (response.contains(label.subSequence(0, label.length()))) { + success = true; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Response: " + method.getResponseBodyAsString()); + LOG.debug("URL: " + method.getURI()); + } + } catch (GitHubServiceException e) { + throw e; + } catch (final RuntimeException runtimeException) { + throw runtimeException; + } catch (final Exception exception) { + throw new GitHubServiceException(exception); + } finally { + if (method != null) + method.releaseConnection(); + } + return success; + } + + /** + * Remove an existing label from an existing GitHub issue. + * + * @param user + * - The user the repository is owned by + * @param repo + * - The git repository where the issue tracker is hosted + * @param label + * @param issueNumber + * @param api + * + * @return A list of GitHub issues in the response text. + * + * @throws GitHubServiceException + * + * API Doc: issues/label/remove/:user/:repo/:label/:number API + * POST Variables: login, api-token + */ + public boolean removeLabel(final String user, final String repo, + final String label, final int issueNumber, final GitHubCredentials credentials) + throws GitHubServiceException { + PostMethod method = null; + boolean success = false; + try { + // build HTTP GET method + method = new PostMethod(gitURLBase + gitIssueRoot + REMOVE_LABEL + + user + "/" + repo + "/" + label + "/" + + Integer.toString(issueNumber)); + + // Set the users login and API token + final NameValuePair login = new NameValuePair("login", credentials.getUsername()); + final NameValuePair token = new NameValuePair("token", credentials.getUsername()); + method.setRequestBody(new NameValuePair[] { login, token }); + + // execute HTTP GET method + executeMethod(method); + // Check the response, make sure the action was successful + final String response = method.getResponseBodyAsString(); + if (!response.contains(label.subSequence(0, label.length()))) { + success = true; + } + if (LOG.isDebugEnabled()) { + LOG.debug("Response: " + method.getResponseBodyAsString()); + LOG.debug("URL: " + method.getURI()); + } + } catch (GitHubServiceException e) { + throw e; + } catch (final RuntimeException runtimeException) { + throw runtimeException; + } catch (final Exception exception) { + throw new GitHubServiceException(exception); + } finally { + if (method != null) + method.releaseConnection(); + } + return success; + } + + /** + * Open a new issue using the GitHub Issues API. + * + * @param user + * - The user the repository is owned by + * @param repo + * - The git repository where the issue tracker is hosted + * @param issue + * - The GitHub issue object to create on the issue tracker. + * + * @return the issue that was created + * + * @throws GitHubServiceException + * + * API Doc: issues/open/:user/:repo API POST Variables: login, + * api-token, title, body + */ + public GitHubIssue openIssue(final String user, final String repo, + final GitHubIssue issue, final GitHubCredentials credentials) + throws GitHubServiceException { + + GitHubShowIssue showIssue = null; + + PostMethod method = null; + try { + // Create the HTTP POST method + method = new PostMethod(gitURLBase + gitIssueRoot + OPEN + user + + "/" + repo); + // Set the users login and API token + final NameValuePair login = new NameValuePair("login", credentials.getUsername()); + final NameValuePair token = new NameValuePair("token", credentials.getApiToken()); + final NameValuePair body = new NameValuePair("body", issue + .getBody()); + final NameValuePair title = new NameValuePair("title", issue + .getTitle()); + + method.setRequestBody(new NameValuePair[] { login, token, body, + title }); + + executeMethod(method); + showIssue = gson.fromJson(new String(method.getResponseBody()), + GitHubShowIssue.class); + + + if (showIssue == null || showIssue.getIssue() == null) { + if (LOG.isErrorEnabled()) { + LOG.error("Unexpected server response: "+method.getResponseBodyAsString()); + } + throw new GitHubServiceException("Unexpected server response"); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Response: " + method.getResponseBodyAsString()); + LOG.debug("URL: " + method.getURI()); + } + return showIssue.getIssue(); + } catch (GitHubServiceException e) { + throw e; + } catch (final RuntimeException runTimeException) { + throw runTimeException; + } catch (final Exception e) { + throw new GitHubServiceException(e); + } finally { + if (method != null) { + method.releaseConnection(); + } + } + } + + /** + * Edit an existing issue using the GitHub Issues API. + * + * @param user + * - The user the repository is owned by + * @param repo + * - The git repository where the issue tracker is hosted + * @param issue + * - The GitHub issue object to create on the issue tracker. + * + * @return the issue with changes + * + * @throws GitHubServiceException + * + * API Doc: issues/edit/:user/:repo/:number API POST Variables: + * login, api-token, title, body + */ + public GitHubIssue editIssue(final String user, final String repo, + final GitHubIssue issue,final GitHubCredentials credentials) + throws GitHubServiceException { + PostMethod method = null; + try { + + // Create the HTTP POST method + method = new PostMethod(gitURLBase + gitIssueRoot + EDIT + user + + "/" + repo + "/" + issue.getNumber()); + // Set the users login and API token + final NameValuePair login = new NameValuePair("login", credentials.getUsername()); + final NameValuePair token = new NameValuePair("token", credentials.getApiToken()); + final NameValuePair body = new NameValuePair("body", issue + .getBody()); + final NameValuePair title = new NameValuePair("title", issue + .getTitle()); + + method.setRequestBody(new NameValuePair[] { login, token, body, + title }); + + executeMethod(method); + GitHubShowIssue showIssue = gson.fromJson(method.getResponseBodyAsString(), + GitHubShowIssue.class); + + // Make sure the changes were made properly + if (showIssue == null || showIssue.getIssue() == null) { + if (LOG.isErrorEnabled()) { + LOG.error("Unexpected server response: "+method.getResponseBodyAsString()); + } + throw new GitHubServiceException("Unexpected server response"); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Response: " + method.getResponseBodyAsString()); + LOG.debug("URL: " + method.getURI()); + } + return showIssue.getIssue(); + } catch (final RuntimeException runTimeException) { + throw runTimeException; + } catch (final Exception e) { + throw new GitHubServiceException(e); + } finally { + if (method != null) { + method.releaseConnection(); + } + } + } + + + public GitHubIssue showIssue(final String user, final String repo,final String issueNumber) throws GitHubServiceException { + GetMethod method = null; + try { + // build HTTP GET method + method = new GetMethod(gitURLBase + gitIssueRoot + SHOW + + user + "/" + repo + "/" + issueNumber); + + // execute HTTP GET method + executeMethod(method); + // transform JSON to Java object + GitHubShowIssue issue = gson.fromJson(new String(method.getResponseBody()), + GitHubShowIssue.class); + + return issue.getIssue(); + } catch (GitHubServiceException e) { + throw e; + } catch (final RuntimeException runtimeException) { + throw runtimeException; + } catch (final Exception exception) { + throw new GitHubServiceException(exception); + } finally { + if (method != null) { + method.releaseConnection(); + } + } + } + + private void executeMethod(HttpMethod method) throws GitHubServiceException { + int status; + try { + status = httpClient.executeMethod(method); + } catch (HttpException e) { + throw new GitHubServiceException(e); + } catch (IOException e) { + throw new GitHubServiceException(e); + } + if (status != HttpStatus.SC_OK) { + switch (status) { + case HttpStatus.SC_UNAUTHORIZED: + case HttpStatus.SC_FORBIDDEN: + throw new PermissionDeniedException(method.getStatusLine()); + default: + throw new GitHubServiceException(method.getStatusLine()); + } + } + } + + /** + * Edit an existing issue using the GitHub Issues API and change its status to open. + * + * @param user + * - The user the repository is owned by + * @param repo + * - The git repository where the issue tracker is hosted + * @param issue + * - The GitHub issue object to create on the issue tracker. + * + * @return the issue with changes + * + * @throws GitHubServiceException + * + * API Doc: issues/reopen/:user/:repo/:number API POST Variables: + * login, api-token, title, body + */ + public GitHubIssue reopenIssue(String user, String repo, GitHubIssue issue, + GitHubCredentials credentials) throws GitHubServiceException { + issue = editIssue(user, repo, issue, credentials); + return changeIssueStatus(user, repo, REOPEN, issue, credentials); + } + + /** + * Edit an existing issue using the GitHub Issues API and change its status to closed. + * + * @param user + * - The user the repository is owned by + * @param repo + * - The git repository where the issue tracker is hosted + * @param issue + * - The GitHub issue object to create on the issue tracker. + * + * @return the issue with changes + * + * @throws GitHubServiceException + * + * API Doc: issues/close/:user/:repo/:number API POST Variables: + * login, api-token, title, body + */ + public GitHubIssue closeIssue(String user, String repo, GitHubIssue issue, + GitHubCredentials credentials) throws GitHubServiceException { + issue = editIssue(user, repo, issue, credentials); + return changeIssueStatus(user, repo, CLOSE, issue, credentials); + + } + + private GitHubIssue changeIssueStatus(final String user, final String repo, + String githubOperation, final GitHubIssue issue, + final GitHubCredentials credentials) throws GitHubServiceException { + PostMethod method = null; + try { + + // Create the HTTP POST method + method = new PostMethod(gitURLBase + gitIssueRoot + githubOperation + user + + "/" + repo + "/" + issue.getNumber()); + // Set the users login and API token + final NameValuePair login = new NameValuePair("login", credentials.getUsername()); + final NameValuePair token = new NameValuePair("token", credentials.getApiToken()); + + method.setRequestBody(new NameValuePair[] { login, token }); + + executeMethod(method); + GitHubShowIssue showIssue = gson.fromJson(method.getResponseBodyAsString(), + GitHubShowIssue.class); + + // Make sure the changes were made properly + if (showIssue == null || showIssue.getIssue() == null) { + if (LOG.isErrorEnabled()) { + LOG.error("Unexpected server response: "+method.getResponseBodyAsString()); + } + throw new GitHubServiceException("Unexpected server response"); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Response: " + method.getResponseBodyAsString()); + LOG.debug("URL: " + method.getURI()); + } + return showIssue.getIssue(); + } catch (final RuntimeException runTimeException) { + throw runTimeException; + } catch (final Exception e) { + throw new GitHubServiceException(e); + } finally { + if (method != null) { + method.releaseConnection(); + } + } + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubServiceException.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubServiceException.java new file mode 100644 index 00000000..3e9a51c2 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubServiceException.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import org.apache.commons.httpclient.StatusLine; + +/** + * Exception generated by the GitHubService + */ +public class GitHubServiceException extends Exception { + + /** + * Auto generated serialVersionUID + */ + private static final long serialVersionUID = -6287902058352190022L; + + private int httpStatusCode = Integer.MIN_VALUE; + + /** + * Constructor for the GitHubServiceException + * + * @param exception + * - Exception to wrap around + */ + protected GitHubServiceException(final Exception exception) { + super(exception); + } + + protected GitHubServiceException(String message, Throwable cause) { + super(message, cause); + } + + protected GitHubServiceException(String message) { + super(message); + } + + protected GitHubServiceException(StatusLine statusLine) { + this(String.format("HTTP %s: %s",statusLine.getStatusCode(),statusLine.getReasonPhrase())); + httpStatusCode = statusLine.getStatusCode(); + } + + /** + * the HTTP status code, or -1 if unknown or not applicable. + */ + public int getHttpStatusCode() { + return httpStatusCode; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubShowIssue.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubShowIssue.java new file mode 100644 index 00000000..f249c53f --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubShowIssue.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +public class GitHubShowIssue { + private GitHubIssue issue; + + public GitHubIssue getIssue() { + return issue; + } + + public void setIssue(GitHubIssue issue) { + this.issue = issue; + } + +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskAttributeMapper.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskAttributeMapper.java new file mode 100644 index 00000000..2d42de8d --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskAttributeMapper.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; +import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; + +public class GitHubTaskAttributeMapper extends TaskAttributeMapper { + + private DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(); + + public GitHubTaskAttributeMapper(TaskRepository taskRepository) { + super(taskRepository); + } + + @Override + public String mapToRepositoryKey(TaskAttribute parent, String key) { + return key; + } + + @Override + public Date getDateValue(TaskAttribute attribute) { + String value = attribute.getValue(); + if (value != null) { + try { + return dateFormat.parse(value); + } catch (ParseException e) { + return super.getDateValue(attribute); + } + } + return null; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskAttributes.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskAttributes.java new file mode 100644 index 00000000..b43694d0 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskAttributes.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; + +public enum GitHubTaskAttributes { + + KEY("Key",TaskAttribute.TASK_KEY,TaskAttribute.TYPE_SHORT_TEXT,true,true,true), + TITLE("Summary",TaskAttribute.SUMMARY,TaskAttribute.TYPE_SHORT_TEXT,true,false,true), + BODY("Description",TaskAttribute.DESCRIPTION,TaskAttribute.TYPE_LONG_RICH_TEXT,true,false,true), + + CREATION_DATE("Created",TaskAttribute.DATE_CREATION,TaskAttribute.TYPE_DATETIME,true,true,false), + MODIFICATION_DATE("Modified",TaskAttribute.DATE_MODIFICATION,TaskAttribute.TYPE_DATETIME,true,true,false), + CLOSED_DATE("Closed",TaskAttribute.DATE_COMPLETION,TaskAttribute.TYPE_DATETIME,false,true,false), + + STATUS("Status",TaskAttribute.STATUS,TaskAttribute.TYPE_SHORT_TEXT,true,false,true) + ; + + + private final String id; + private final String label; + private final boolean readOnly; + private final boolean initTask; + private final boolean requiredForFullTaskData; + private final String type; + + private GitHubTaskAttributes(String label, String id,String type,boolean requiredForFullTaskData, boolean readOnly, boolean initTask) { + this.label = label; + this.requiredForFullTaskData = requiredForFullTaskData; + this.id = id==null?"github."+name():id; + this.type = type; + this.readOnly = readOnly; + this.initTask = initTask; + } + + public String getLabel() { + return label; + } + public String getId() { + return id; + } + public String getType() { + return type; + } + public boolean isReadOnly() { + return readOnly; + } + + public String getKind() { + return TaskAttribute.KIND_DEFAULT; + } + + public boolean isInitTask() { + return initTask; + } + + public boolean isRequiredForFullTaskData() { + return requiredForFullTaskData; + } +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskDataHandler.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskDataHandler.java new file mode 100644 index 00000000..62649e79 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskDataHandler.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.mylyn.tasks.core.ITaskMapping; +import org.eclipse.mylyn.tasks.core.RepositoryResponse; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.RepositoryResponse.ResponseKind; +import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; +import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; +import org.eclipse.mylyn.tasks.core.data.TaskAttributeMetaData; +import org.eclipse.mylyn.tasks.core.data.TaskData; +import org.eclipse.mylyn.tasks.core.data.TaskOperation; + +public class GitHubTaskDataHandler extends AbstractTaskDataHandler { + + private static final String DATA_VERSION = "1"; + /** + * + */ + private GitHubTaskAttributeMapper taskAttributeMapper = null; + private final GitHubRepositoryConnector connector; + private DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(); + + private DateFormat githubDateFormat = new SimpleDateFormat("yyyy/mm/dd HH:MM:ss Z"); + + public GitHubTaskDataHandler(GitHubRepositoryConnector connector) { + this.connector = connector; + } + + @Override + public TaskAttributeMapper getAttributeMapper(TaskRepository taskRepository) { + if (this.taskAttributeMapper == null) + this.taskAttributeMapper = new GitHubTaskAttributeMapper( + taskRepository); + return this.taskAttributeMapper; + } + + public TaskData createPartialTaskData(TaskRepository repository, + IProgressMonitor monitor,String user, String project, GitHubIssue issue) { + + TaskData data = new TaskData(getAttributeMapper(repository), + GitHubRepositoryConnector.KIND, repository.getRepositoryUrl(), + issue.getNumber()); + data.setVersion(DATA_VERSION); + + createOperations(data,issue); + + + createAttribute(data, GitHubTaskAttributes.KEY,issue.getNumber()); + createAttribute(data, GitHubTaskAttributes.TITLE, issue.getTitle()); + createAttribute(data, GitHubTaskAttributes.BODY, issue.getBody()); + createAttribute(data, GitHubTaskAttributes.STATUS, issue.getState()); + createAttribute(data, GitHubTaskAttributes.CREATION_DATE, toLocalDate(issue.getCreated_at())); + createAttribute(data, GitHubTaskAttributes.MODIFICATION_DATE, toLocalDate(issue.getCreated_at())); + createAttribute(data, GitHubTaskAttributes.CLOSED_DATE, toLocalDate(issue.getClosed_at())); + + if (isPartial(data)) { + data.setPartial(true); + } + + return data; + } + + + private boolean isPartial(TaskData data) { + for (GitHubTaskAttributes attribute: GitHubTaskAttributes.values()) { + if (attribute.isRequiredForFullTaskData()) { + TaskAttribute taskAttribute = data.getRoot().getAttribute(attribute.getId()); + if (taskAttribute == null) { + return true; + } + } + } + return false; + } + + private void createOperations(TaskData data, GitHubIssue issue) { + TaskAttribute operationAttribute = data.getRoot().createAttribute(TaskAttribute.OPERATION); + operationAttribute.getMetaData().setType(TaskAttribute.TYPE_OPERATION); + + if (!data.isNew()) { + if (issue.getState() != null) { + addOperation(data,issue,GitHubTaskOperation.LEAVE,true); + if (issue.getState().equals("open")) { + addOperation(data,issue,GitHubTaskOperation.CLOSE,false); + } else if (issue.getState().equals("closed")) { + addOperation(data,issue,GitHubTaskOperation.REOPEN,false); + } + } + } + } + + private void addOperation(TaskData data, GitHubIssue issue, GitHubTaskOperation operation,boolean asDefault) { + TaskAttribute attribute = data.getRoot().createAttribute(TaskAttribute.PREFIX_OPERATION + operation.getId()); + String label = createOperationLabel(issue, operation); + TaskOperation.applyTo(attribute, operation.getId(), label); + + if (asDefault) { + TaskAttribute operationAttribute = data.getRoot().getAttribute(TaskAttribute.OPERATION); + TaskOperation.applyTo(operationAttribute, operation.getId(), label); + } + } + + private String createOperationLabel(GitHubIssue issue, + GitHubTaskOperation operation) { + return operation==GitHubTaskOperation.LEAVE?operation.getLabel()+issue.getState():operation.getLabel(); + } + + private String toLocalDate(String date) { + if (date != null && date.trim().length() > 0) { + // expect "2010/02/02 22:58:39 -0800" + try { + Date d = githubDateFormat.parse(date); + date = dateFormat.format(d); + } catch (ParseException e) { + // ignore + } + } + return date; + } + + private String toGitHubDate(TaskData taskData, + GitHubTaskAttributes attr) { + TaskAttribute attribute = taskData.getRoot().getAttribute(attr.name()); + String value = attribute==null?null:attribute.getValue(); + if (value != null) { + try { + Date d = dateFormat.parse(value); + value = githubDateFormat.format(d); + } catch (ParseException e) { + // ignore + } + } + return value; + } + + public TaskData createTaskData(TaskRepository repository, + IProgressMonitor monitor, String user, String project, + GitHubIssue issue) { + TaskData taskData = createPartialTaskData(repository, monitor, user, project, issue); + taskData.setPartial(false); + + return taskData; + } + + private GitHubIssue createIssue(TaskData taskData) { + GitHubIssue issue = new GitHubIssue(); + if (!taskData.isNew()) { + issue.setNumber(taskData.getTaskId()); + } + issue.setBody(getAttributeValue(taskData,GitHubTaskAttributes.BODY)); + issue.setTitle(getAttributeValue(taskData,GitHubTaskAttributes.TITLE)); + issue.setState(getAttributeValue(taskData,GitHubTaskAttributes.STATUS)); + issue.setCreated_at(toGitHubDate(taskData,GitHubTaskAttributes.CREATION_DATE)); + issue.setCreated_at(toGitHubDate(taskData,GitHubTaskAttributes.MODIFICATION_DATE)); + issue.setCreated_at(toGitHubDate(taskData,GitHubTaskAttributes.CLOSED_DATE)); + return issue; + } + + private String getAttributeValue(TaskData taskData, + GitHubTaskAttributes attr) { + TaskAttribute attribute = taskData.getRoot().getAttribute(attr.getId()); + return attribute==null?null:attribute.getValue(); + } + + private void createAttribute(TaskData data, GitHubTaskAttributes attribute, String value) { + TaskAttribute attr = data.getRoot().createAttribute(attribute.getId()); + TaskAttributeMetaData metaData = attr.getMetaData(); + metaData.defaults() + .setType(attribute.getType()) + .setKind(attribute.getKind()) + .setLabel(attribute.getLabel()) + .setReadOnly(attribute.isReadOnly()); + + if (value != null) { + attr.addValue(value); + } + } + + @Override + public boolean initializeTaskData(TaskRepository repository, TaskData data, + ITaskMapping initializationData, IProgressMonitor monitor) + throws CoreException { + + data.setVersion(DATA_VERSION); + + for (GitHubTaskAttributes attr: GitHubTaskAttributes.values()) { + if (attr.isInitTask()) { + createAttribute(data, attr,null); + } + } + + return true; + } + + @Override + public RepositoryResponse postTaskData(TaskRepository repository, + TaskData taskData, Set<TaskAttribute> oldAttributes, + IProgressMonitor monitor) throws CoreException { + + GitHubIssue issue = createIssue(taskData); + String user = GitHub.computeTaskRepositoryUser(repository.getUrl()); + String repo = GitHub.computeTaskRepositoryProject(repository.getUrl()); + try { + + GitHubService service = connector.getService(); + GitHubCredentials credentials = GitHubCredentials.create(repository); + if (taskData.isNew()) { + issue = service.openIssue(user , repo, issue, credentials); + } else { + TaskAttribute operationAttribute = taskData.getRoot().getAttribute(TaskAttribute.OPERATION); + + GitHubTaskOperation operation = null; + + + if (operationAttribute != null) { + String opId = operationAttribute.getValue(); + operation = GitHubTaskOperation.fromId(opId); + + } + if (operation != null && operation != GitHubTaskOperation.LEAVE) { + service.editIssue(user , repo, issue, credentials); + switch (operation) { + case REOPEN: + service.reopenIssue(user,repo,issue,credentials); + break; + case CLOSE: + service.closeIssue(user,repo,issue,credentials); + break; + default: + throw new IllegalStateException("not implemented: "+operation); + } + } else { + service.editIssue(user , repo, issue, credentials); + } + } + return new RepositoryResponse(taskData.isNew()?ResponseKind.TASK_CREATED:ResponseKind.TASK_UPDATED,issue.getNumber()); + } catch (GitHubServiceException e) { + throw new CoreException(GitHub.createErrorStatus(e)); + } + + } + + +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskOperation.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskOperation.java new file mode 100644 index 00000000..7043d477 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/GitHubTaskOperation.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +public enum GitHubTaskOperation { + LEAVE("Leave as "), + REOPEN("Reopen"), + CLOSE("Close"); + + private final String label; + + private GitHubTaskOperation(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public String getId() { + return name(); + } + + /** + * get the operation by its id + * @param opId the id, or null + * @return the operation, or null if the id was null or did not match any operation + */ + public static GitHubTaskOperation fromId(String opId) { + for (GitHubTaskOperation op: values()) { + if (op.getId().equals(opId)) { + return op; + } + } + return null; + } + +} diff --git a/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/PermissionDeniedException.java b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/PermissionDeniedException.java new file mode 100644 index 00000000..f2401048 --- /dev/null +++ b/org.eclipse.mylyn.github.core/src/org/eclipse/mylyn/github/internal/PermissionDeniedException.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.internal; + +import org.apache.commons.httpclient.StatusLine; + +public class PermissionDeniedException extends GitHubServiceException { + + private static final long serialVersionUID = -4635370712942848361L; + + protected PermissionDeniedException(Exception exception) { + super(exception); + } + + protected PermissionDeniedException(StatusLine statusLine) { + super(statusLine); + } + + protected PermissionDeniedException(String message, Throwable cause) { + super(message, cause); + } + + protected PermissionDeniedException(String message) { + super(message); + } + +} diff --git a/org.eclipse.mylyn.github.tests/.classpath b/org.eclipse.mylyn.github.tests/.classpath new file mode 100644 index 00000000..64c5e31b --- /dev/null +++ b/org.eclipse.mylyn.github.tests/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/org.eclipse.mylyn.github.tests/.gitignore b/org.eclipse.mylyn.github.tests/.gitignore new file mode 100644 index 00000000..d567ba01 --- /dev/null +++ b/org.eclipse.mylyn.github.tests/.gitignore @@ -0,0 +1,2 @@ +bin +target diff --git a/org.eclipse.mylyn.github.tests/.project b/org.eclipse.mylyn.github.tests/.project new file mode 100644 index 00000000..c3fa2b20 --- /dev/null +++ b/org.eclipse.mylyn.github.tests/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.mylyn.github.tests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.mylyn.github.tests/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.github.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..593ea92a --- /dev/null +++ b/org.eclipse.mylyn.github.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Wed Feb 03 20:29:30 PST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/org.eclipse.mylyn.github.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.github.tests/META-INF/MANIFEST.MF new file mode 100644 index 00000000..2076b5bc --- /dev/null +++ b/org.eclipse.mylyn.github.tests/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Eclipse EGit Mylyn GitHub Tests (Incubation) +Bundle-SymbolicName: org.eclipse.mylyn.github.tests +Bundle-Version: 0.1.0.qualifier +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Require-Bundle: org.junit4;bundle-version="4.5.0", + org.eclipse.mylyn.github.core;bundle-version="0.1.0", + org.eclipse.mylyn.github.ui;bundle-version="0.1.0", + org.eclipse.jface.text;bundle-version="3.5.0", + org.eclipse.mylyn.tasks.ui;bundle-version="3.2.0", + org.eclipse.equinox.security;bundle-version="1.0.100", + org.eclipse.mylyn.tasks.core +Bundle-Vendor: Eclipse EGit +Import-Package: com.google.gson;version="1.6.0" diff --git a/org.eclipse.mylyn.github.tests/build.properties b/org.eclipse.mylyn.github.tests/build.properties new file mode 100644 index 00000000..34d2e4d2 --- /dev/null +++ b/org.eclipse.mylyn.github.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/AllHeadlessTests.java b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/AllHeadlessTests.java new file mode 100644 index 00000000..009f6db0 --- /dev/null +++ b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/AllHeadlessTests.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.tests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses( { // + GitHubServiceTest.class, + MarshalingTest.class + }) +public class AllHeadlessTests { + +} diff --git a/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/GitHubServiceTest.java b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/GitHubServiceTest.java new file mode 100644 index 00000000..d05be84a --- /dev/null +++ b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/GitHubServiceTest.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.eclipse.mylyn.github.internal.GitHubCredentials; +import org.eclipse.mylyn.github.internal.GitHubIssue; +import org.eclipse.mylyn.github.internal.GitHubIssues; +import org.eclipse.mylyn.github.internal.GitHubService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Run All the JUnit Tests for the GitHub API implementation + */ +@RunWith(JUnit4.class) +public class GitHubServiceTest { + + // GitHub API key for user "eclipse-github-plugin" + String API_KEY = "8b35af675fcdca9d254ae7a6ad4d0be8"; + + String TEST_USER = "eclipse-github-plugin"; + + String TEST_PASS = "plugin"; + + String TEST_PROJECT = "org.eclipse.mylyn.github.issues"; + + /** + * Test the GitHubService issue searching implementation + */ + @SuppressWarnings("restriction") + @Test + public void searchIssues() throws Exception { + final GitHubService service = new GitHubService(); + final GitHubIssues issues = service.searchIssues(TEST_USER, + TEST_PROJECT, "open", "test"); + assertEquals(0, issues.getIssues().length); + } + + /** + * Test the GitHubService implementation for opening a new issue. + */ + @Test + public void openIssue() throws Exception { + final GitHubService service = new GitHubService(); + final GitHubIssue issue = new GitHubIssue(); + issue.setUser(TEST_USER); + issue.setBody("This is a test body"); + issue.setTitle("Issue Title"); + GitHubIssue newIssue = service.openIssue(TEST_USER, TEST_PROJECT, issue, + new GitHubCredentials(TEST_USER,API_KEY)); + assertTrue(newIssue != null); + assertEquals(issue.getUser(),newIssue.getUser()); + assertEquals(issue.getBody(),newIssue.getBody()); + assertEquals(issue.getTitle(),newIssue.getTitle()); + assertTrue(newIssue.getNumber() != null && newIssue.getNumber().length() > 0); + } + /** + * Test the GitHubService implementation for opening a new issue. + */ + @Test + public void editIssue() throws Exception { + final GitHubService service = new GitHubService(); + final GitHubIssue issue = new GitHubIssue(); + issue.setUser(TEST_USER); + issue.setBody("This is a test body"); + issue.setTitle("Issue Title"); + GitHubIssue newIssue = service.openIssue(TEST_USER, TEST_PROJECT, issue, + new GitHubCredentials(TEST_USER,API_KEY)); + assertTrue(newIssue != null); + + newIssue.setTitle(newIssue.getTitle()+" - modified"); + newIssue.setBody(newIssue.getBody()+" - modified"); + + service.editIssue(TEST_USER, TEST_PROJECT, issue, new GitHubCredentials(TEST_USER,API_KEY)); + + GitHubIssue showIssue = service.showIssue(TEST_USER, TEST_PROJECT, issue.getNumber()); + + assertTrue(showIssue != null); + assertEquals(newIssue.getTitle(),showIssue.getTitle()); + } + + + + /** + * Test the GitHubService implementation for adding a label to an existing + * issue. + */ + @Test + public void addLabel() throws Exception { + final GitHubService service = new GitHubService(); + final boolean result = service.addLabel(TEST_USER, TEST_PROJECT, + "lame", 1, new GitHubCredentials(TEST_USER,API_KEY)); + assertTrue(result); + } + + /** + * Test the GitHubService implementation for removing an existing label from + * any GitHub issue. + */ + @Test + public void removeLable() throws Exception { + final GitHubService service = new GitHubService(); + final boolean result = service.removeLabel(TEST_USER, TEST_PROJECT, + "lame", 1, new GitHubCredentials(TEST_USER,API_KEY)); + assertTrue(result); + } +}
\ No newline at end of file diff --git a/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/MarshalingTest.java b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/MarshalingTest.java new file mode 100644 index 00000000..e6c80fe9 --- /dev/null +++ b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/MarshalingTest.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.tests; + +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; + +import org.eclipse.mylyn.github.internal.GitHubIssue; +import org.eclipse.mylyn.github.internal.GitHubIssues; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import com.google.gson.Gson; + +@SuppressWarnings("restriction") +@RunWith(JUnit4.class) +public class MarshalingTest { + + private Gson gson; + + @Before + public void beforeTest() { + gson = new Gson(); + } + + @Test + public void unmarshalIssues() { + GitHubIssues issues = gson.fromJson( + getResource("resources/issues.json"), GitHubIssues.class); + + assertTrue(issues != null); + assertTrue(issues.getIssues() != null); + + assertEquals(10,issues.getIssues().length); + + GitHubIssue issue = issues.getIssues()[9]; + //{"number":10,"votes":0,"created_at":"2010/02/04 21:03:54 -0800","body":"test description 2 ","title":"test issue for testing mylyn github connector2", + // "updated_at":"2010/02/04 21:09:37 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"}]} + assertEquals("10",issue.getNumber()); + assertEquals("2010/02/04 21:03:54 -0800",issue.getCreated_at()); + assertEquals("test description 2 ",issue.getBody()); + assertEquals("test issue for testing mylyn github connector2",issue.getTitle()); + assertEquals("2010/02/04 21:09:37 -0800",issue.getUpdated_at()); + assertNull(issue.getClosed_at()); + assertEquals("dgreen99",issue.getUser()); + assertEquals("open",issue.getState()); + } + + private String getResource(String resource) { + try { + InputStream stream = MarshalingTest.class + .getResourceAsStream(resource); + try { + StringWriter writer = new StringWriter(); + Reader reader = new InputStreamReader(stream); + int c; + while ((c = reader.read()) != -1) { + writer.write(c); + } + return writer.toString(); + } finally { + stream.close(); + } + } catch (Throwable t) { + throw new IllegalStateException(t); + } + } +} diff --git a/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/resources/issues.json b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/resources/issues.json new file mode 100644 index 00000000..d99eb9f3 --- /dev/null +++ b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/resources/issues.json @@ -0,0 +1 @@ +{"issues":[{"number":1,"votes":0,"created_at":"2010/02/02 22:58:39 -0800","body":"","title":"Test objective-c marshaling code","updated_at":"2010/02/02 22:58:39 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":2,"votes":0,"created_at":"2010/02/02 22:59:02 -0800","body":"","title":"Provide instructions for use","updated_at":"2010/02/02 22:59:02 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":3,"votes":0,"created_at":"2010/02/02 22:59:26 -0800","body":"","title":"add support for JSON marshalling","updated_at":"2010/02/04 17:56:02 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":4,"votes":0,"created_at":"2010/02/02 22:59:45 -0800","body":"","title":"provide working sample project","updated_at":"2010/02/02 22:59:45 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":5,"votes":0,"created_at":"2010/02/02 23:00:19 -0800","body":"","title":"support object inheritance","updated_at":"2010/02/02 23:00:19 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":6,"votes":0,"created_at":"2010/02/02 23:00:37 -0800","body":"","title":"provide support for nested types","updated_at":"2010/02/02 23:00:37 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":7,"votes":0,"created_at":"2010/02/02 23:00:49 -0800","body":"","title":"client enum support","updated_at":"2010/02/02 23:00:49 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":8,"votes":0,"created_at":"2010/02/02 23:01:09 -0800","body":"","title":"refactor templates to use field iterator","updated_at":"2010/02/02 23:01:09 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":9,"votes":0,"created_at":"2010/02/02 23:01:35 -0800","body":"","title":"wiki should explain target architecture","updated_at":"2010/02/02 23:01:35 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"},{"number":10,"votes":0,"created_at":"2010/02/04 21:03:54 -0800","body":"test description 2 ","title":"test issue for testing mylyn github connector2","updated_at":"2010/02/04 21:09:37 -0800","closed_at":null,"user":"dgreen99","labels":[],"state":"open"}]}
\ No newline at end of file diff --git a/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/ui/GitHubRepositoryConnectorUITest.java b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/ui/GitHubRepositoryConnectorUITest.java new file mode 100644 index 00000000..fe58f09e --- /dev/null +++ b/org.eclipse.mylyn.github.tests/src/org/eclipse/mylyn/github/tests/ui/GitHubRepositoryConnectorUITest.java @@ -0,0 +1,41 @@ +package org.eclipse.mylyn.github.tests.ui; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; +import junit.framework.Assert; + +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.mylyn.github.internal.GitHub; +import org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnectorUI; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.ui.TaskHyperlink; +import org.junit.Before; +import org.junit.Test; + +public class GitHubRepositoryConnectorUITest { + + private GitHubRepositoryConnectorUI connectorUI; + private TaskRepository repository; + + @Before + public void before() { + connectorUI = new GitHubRepositoryConnectorUI(); + repository = new TaskRepository(GitHub.CONNECTOR_KIND, GitHub.createGitHubUrl("foo", "bar")); + } + + @Test + public void testFindHyperlinksTaskRepositoryStringIntInt() { + IHyperlink[] hyperlinks = connectorUI.findHyperlinks(repository, "one #2 three", -1, 0); + assertNotNull(hyperlinks); + assertEquals(1,hyperlinks.length); + assertEquals(new Region(4,2),hyperlinks[0].getHyperlinkRegion()); + + hyperlinks = connectorUI.findHyperlinks(repository, "one #2 three", -1, 4); + assertNotNull(hyperlinks); + assertEquals(1,hyperlinks.length); + assertEquals(new Region(8,2),hyperlinks[0].getHyperlinkRegion()); + } + +} diff --git a/org.eclipse.mylyn.github.ui/.classpath b/org.eclipse.mylyn.github.ui/.classpath new file mode 100644 index 00000000..64c5e31b --- /dev/null +++ b/org.eclipse.mylyn.github.ui/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/org.eclipse.mylyn.github.ui/.gitignore b/org.eclipse.mylyn.github.ui/.gitignore new file mode 100644 index 00000000..d567ba01 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/.gitignore @@ -0,0 +1,2 @@ +bin +target diff --git a/org.eclipse.mylyn.github.ui/.project b/org.eclipse.mylyn.github.ui/.project new file mode 100644 index 00000000..6b7553c4 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.github.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.github.ui/.settings/org.eclipse.core.resources.prefs b/org.eclipse.mylyn.github.ui/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..84f3fcc6 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Tue Jun 09 20:22:15 CEST 2009
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.mylyn.github.ui/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.github.ui/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 00000000..f96d6778 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,3 @@ +#Tue Jun 09 20:22:15 CEST 2009
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.github.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.github.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..094b3472 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Sun Aug 23 18:34:16 EDT 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000..356db6d0 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Eclipse EGit Mylyn GitHub UI Plug-in (Incubation) +Bundle-SymbolicName: org.eclipse.mylyn.github.ui;singleton:=true +Bundle-Version: 0.1.0.qualifier +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-Vendor: Eclipse EGit +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", + org.eclipse.ui;bundle-version="3.5.0", + org.eclipse.ui.forms;bundle-version="3.4.0", + org.eclipse.mylyn.tasks.ui;bundle-version="3.2.0", + org.eclipse.mylyn.github.core;bundle-version="0.1.0", + org.eclipse.jface.text;bundle-version="3.5.0", + org.eclipse.mylyn.commons.net;bundle-version="3.2.0", + org.eclipse.mylyn.tasks.core +Export-Package: org.eclipse.mylyn.github.ui.internal;x-internal:=true diff --git a/org.eclipse.mylyn.github.ui/build.properties b/org.eclipse.mylyn.github.ui/build.properties new file mode 100644 index 00000000..3a0c53af --- /dev/null +++ b/org.eclipse.mylyn.github.ui/build.properties @@ -0,0 +1,7 @@ +source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties,\
+ images/
diff --git a/org.eclipse.mylyn.github.ui/images/git-logo.png b/org.eclipse.mylyn.github.ui/images/git-logo.png Binary files differnew file mode 100644 index 00000000..dd98d355 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/images/git-logo.png diff --git a/org.eclipse.mylyn.github.ui/plugin.properties b/org.eclipse.mylyn.github.ui/plugin.properties new file mode 100644 index 00000000..da940291 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/plugin.properties @@ -0,0 +1,2 @@ +org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnector=GitHub repository connector
+org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnectorUI=GitHub repository connector UI
\ No newline at end of file diff --git a/org.eclipse.mylyn.github.ui/plugin.xml b/org.eclipse.mylyn.github.ui/plugin.xml new file mode 100644 index 00000000..57da2a54 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/plugin.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.mylyn.tasks.ui.repositories">
+ <connectorCore
+ class="org.eclipse.mylyn.github.internal.GitHubRepositoryConnector"
+ id="org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnector"
+ name="%org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnector">
+ </connectorCore>
+ <connectorUi
+ brandingIcon="images/git-logo.png"
+ class="org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnectorUI"
+ id="org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnectorUI"
+ name="%org.eclipse.mylyn.github.ui.internal.GitHubRepositoryConnectorUI"
+ overlayIcon="images/git-logo.png">
+ </connectorUi>
+ </extension>
+ <extension
+ point="org.eclipse.mylyn.tasks.ui.editors">
+ <pageFactory
+ class="org.eclipse.mylyn.github.ui.internal.GitHubTaskEditorPageFactory"
+ id="org.eclipse.mylyn.github.ui.internal.GitHubTaskEditorPageFactory">
+ </pageFactory>
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.mylyn.github.ui/pom.xml b/org.eclipse.mylyn.github.ui/pom.xml new file mode 100644 index 00000000..1accffc8 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/pom.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> + + 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 +--> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <parent> + <artifactId>github-parent</artifactId> + <groupId>org.eclipse.mylyn.github</groupId> + <version>0.1.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>ui</artifactId> + <packaging>eclipse-plugin</packaging> + <name>Eclipse EGit Mylyn GitHub UI (Incubation)</name> +</project> diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java new file mode 100644 index 00000000..eda7565f --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryConnectorUI.java @@ -0,0 +1,147 @@ +/*******************************************************************************
+ * Copyright (c) 2011 Red Hat 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:
+ * David Green <david.green@tasktop.com> - initial contribution
+ * Christian Trutz <christian.trutz@gmail.com> - initial contribution
+ * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution
+ *******************************************************************************/
+package org.eclipse.mylyn.github.ui.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.jface.text.hyperlink.URLHyperlink;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.mylyn.github.internal.GitHub;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITaskMapping;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
+import org.eclipse.mylyn.tasks.ui.TaskHyperlink;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositorySettingsPage;
+import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage;
+import org.eclipse.mylyn.tasks.ui.wizards.NewTaskWizard;
+import org.eclipse.mylyn.tasks.ui.wizards.RepositoryQueryWizard;
+
+/**
+ * GitHub connector specific UI extensions.
+ */
+public class GitHubRepositoryConnectorUI extends AbstractRepositoryConnectorUi {
+
+ private final Pattern issuePattern = Pattern.compile("(?:([a-zA-Z0-9_\\.-]+)(?:/([a-zA-Z0-9_\\.-]+))?)?\\#(\\d+)");
+
+ /**
+ *
+ *
+ * @return the unique type of the repository: "github"
+ */
+ @Override
+ public String getConnectorKind() {
+ return GitHub.CONNECTOR_KIND;
+ }
+
+ /**
+ *
+ *
+ * @return {@link AbstractRepositorySettingsPage} with GitHub specific
+ * parameter like user name, password, ...
+ */
+ @Override
+ public ITaskRepositoryPage getSettingsPage(
+ final TaskRepository taskRepository) {
+ return new GitHubRepositorySettingsPage(taskRepository);
+ }
+
+ /**
+ *
+ *
+ * @return {@link NewTaskWizard} with GitHub specific tab
+ */
+ @Override
+ public IWizard getNewTaskWizard(final TaskRepository taskRepository,
+ final ITaskMapping taskSelection) {
+ return new NewTaskWizard(taskRepository, taskSelection);
+ }
+
+ /**
+ * This {@link AbstractRepositoryConnectorUi} has search page.
+ *
+ * @return {@code true}
+ */
+ @Override
+ public boolean hasSearchPage() {
+ return true;
+ }
+
+ /**
+ * Returns {@link IWizard} used in Mylyn for creating new queries. This
+ * {@link IWizard} has a wizard page for creating GitHub specific task
+ * queries.
+ *
+ * @return {@link RepositoryQueryWizard} with GitHub specific query page
+ */
+ @Override
+ public IWizard getQueryWizard(final TaskRepository taskRepository,
+ final IRepositoryQuery queryToEdit) {
+ RepositoryQueryWizard wizard = new RepositoryQueryWizard(taskRepository);
+ GitHubRepositoryQueryPage queryPage = new GitHubRepositoryQueryPage(
+ taskRepository, queryToEdit);
+ wizard.addPage(queryPage);
+ return wizard;
+ }
+
+
+ public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int index, int textOffset) {
+ List<IHyperlink> hyperlinks = new ArrayList<IHyperlink>();
+
+ Matcher matcher = issuePattern.matcher(text);
+ while (matcher.find()) {
+ if (index == -1 || (index >= matcher.start() && index <= matcher.end())) {
+ String user = matcher.group(1);
+ String project = matcher.group(2);
+ String taskId = matcher.group(3);
+
+ if (project == null && user != null) {
+ // same project name, different user
+ String url = repository.getUrl();
+ project = GitHub.computeTaskRepositoryProject(url);
+ }
+
+ TaskRepository taskRepository = null;
+ if (user == null && project == null) {
+ taskRepository = repository;
+ } else if (user != null && project != null) {
+ String repositoryUrl = GitHub.createGitHubUrl(user,project);
+ taskRepository = TasksUi.getRepositoryManager().getRepository(GitHub.CONNECTOR_KIND, repositoryUrl);
+ if (taskRepository == null) {
+ repositoryUrl = GitHub.createGitHubUrlAlternate(user,project);
+ taskRepository = TasksUi.getRepositoryManager().getRepository(GitHub.CONNECTOR_KIND, repositoryUrl);
+ }
+ }
+ if (taskRepository != null) {
+ Region region = createRegion(textOffset, matcher);
+ hyperlinks.add(new TaskHyperlink(region, repository, taskId));
+ } else if (user != null && project != null) {
+ Region region = createRegion(textOffset, matcher);
+ String url = GitHub.createGitHubUrl(user, project)+"/issues/issue/"+taskId;
+ hyperlinks.add(new URLHyperlink(region, url));
+ }
+ }
+ }
+ return hyperlinks.toArray(new IHyperlink[hyperlinks.size()]);
+ }
+
+ private Region createRegion(int textOffset, Matcher matcher) {
+ return new Region(matcher.start()+textOffset,matcher.end()-matcher.start());
+ }
+}
diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java new file mode 100644 index 00000000..b55e72a5 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositoryQueryPage.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.ui.internal; + +import org.eclipse.mylyn.tasks.core.IRepositoryQuery; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * GitHub connector specific extensions. + */ +public class GitHubRepositoryQueryPage extends AbstractRepositoryQueryPage { + + private static final String ATTR_QUERY_TEXT = "queryText"; + + private static final String ATTR_STATUS = "status"; + + private Text queryText = null; + + private Combo status = null; + + /** + * @param taskRepository + * @param query + */ + public GitHubRepositoryQueryPage(final TaskRepository taskRepository, + final IRepositoryQuery query) { + super("GitHub", taskRepository, query); + setTitle("GitHub search query parameters"); + setDescription("Valid search query parameters entered."); + setPageComplete(false); + } + + @Override + public String getQueryTitle() { + return "GitHub Query"; + } + + @Override + public void applyTo(IRepositoryQuery query) { + String statusString = status.getText(); + String queryString = queryText.getText(); + + String summary = statusString; + summary += " issues"; + if (queryString!=null && queryString.trim().length() > 0) { + summary += " matching "+queryString; + } + query.setSummary(summary); + query.setAttribute(ATTR_STATUS, statusString); + query.setAttribute(ATTR_QUERY_TEXT, queryString); + } + + /** + * + * + */ + public void createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginTop = 20; + gridLayout.marginLeft = 25; + gridLayout.verticalSpacing = 8; + gridLayout.horizontalSpacing = 8; + composite.setLayout(gridLayout); + + + // create the status option combo box + new Label(composite, SWT.NONE).setText("Status:"); + status = new Combo(composite, SWT.READ_ONLY); + String[] queryValues = new String[] { "all", "open", "closed" }; + status.setItems(queryValues); + status.select(0); + String queryModelStatus = getQuery()==null?null:getQuery().getAttribute(ATTR_STATUS); + if (queryModelStatus != null) { + for (int x = 0;x<queryValues.length;++x) { + if (queryValues[x].equals(queryModelStatus)) { + status.select(x); + break; + } + } + } + + // create the query entry box + new Label(composite, SWT.NONE).setText("Query text:"); + queryText = new Text(composite, SWT.BORDER); + GridData gridData = new GridData(); + gridData.widthHint = 250; + queryText.setLayoutData(gridData); + String queryModelText = getQuery()==null?null:getQuery().getAttribute(ATTR_QUERY_TEXT); + queryText.setText(queryModelText==null?"":queryModelText); + + setControl(composite); + } + + @Override + public boolean isPageComplete() { + setErrorMessage(null); + return true; + } + +} diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositorySettingsPage.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositorySettingsPage.java new file mode 100644 index 00000000..28cd3a55 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubRepositorySettingsPage.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.ui.internal; + +import java.util.regex.Matcher; + + +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.github.internal.GitHub; +import org.eclipse.mylyn.github.internal.GitHubCredentials; +import org.eclipse.mylyn.github.internal.GitHubService; +import org.eclipse.mylyn.github.internal.GitHubServiceException; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositorySettingsPage; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; + +/** + * GitHub connector specific extensions. + */ +public class GitHubRepositorySettingsPage extends + AbstractRepositorySettingsPage { + + static final String URL = "http://github.com"; + + private static final String PASS_LABEL_TEXT = "GitHub API Token:"; + + /** + * Populate taskRepository with repository settings. + * + * @param taskRepository + * - Object to populate + */ + public GitHubRepositorySettingsPage(final TaskRepository taskRepository) { + super("GitHub Repository Settings", "", taskRepository); + this.setHttpAuth(false); + this.setNeedsAdvanced(false); + this.setNeedsAnonymousLogin(false); + this.setNeedsTimeZone(false); + this.setNeedsHttpAuth(false); + } + + @Override + public String getConnectorKind() { + return GitHub.CONNECTOR_KIND; + } + + @Override + protected void createAdditionalControls(Composite parent) { + // Set the URL now, because serverURL is definitely instantiated . + if (serverUrlCombo != null && (serverUrlCombo.getText() == null || serverUrlCombo.getText().trim().length() == 0)) { + String fullUrlText = URL+"/user/project"; + serverUrlCombo.setText(fullUrlText); + // select the user/project part of the URL so that the user can just start + // typing to replace the text. + serverUrlCombo.setSelection(new Point(URL.length()+1,fullUrlText.length())); + } + + // Specify that you need the GitHub User Name + if (repositoryUserNameEditor != null) { + String text = repositoryUserNameEditor.getLabelText(); + repositoryUserNameEditor.setLabelText("GitHub " + text); + } + + // Use the password field for the API Token Key + if (repositoryPasswordEditor != null) { + repositoryPasswordEditor.setLabelText(PASS_LABEL_TEXT); + } + } + + @Override + protected Validator getValidator(final TaskRepository repository) { + Validator validator = new Validator() { + @Override + public void run(IProgressMonitor monitor) throws CoreException { + int totalWork = 1000; + monitor.beginTask("Validating settings", totalWork); + try { + + String urlText = repository.getUrl(); + Matcher urlMatcher = GitHub.URL_PATTERN.matcher(urlText==null?"":urlText); + if (!urlMatcher.matches()) { + setStatus(GitHubUi.createErrorStatus("Server URL must be in the form http://github.com/user/project or\nhttp://www.github.org/user/project")); + return; + } + monitor.worked(100); + + String user = urlMatcher.group(1); + String repo = urlMatcher.group(2); + AuthenticationCredentials auth = repository.getCredentials(AuthenticationType.REPOSITORY); + + GitHubService service = new GitHubService(); + + monitor.subTask("Contacting server..."); + try { + // verify the repo + service.searchIssues(user, repo, new String("open"),""); + monitor.worked(400); + + // verify the credentials + if (auth == null) { + setStatus(GitHubUi.createErrorStatus("Credentials are required. Please specify username and API Token.")); + return; + } + GitHubCredentials credentials = new GitHubCredentials(auth.getUserName(), auth.getPassword()); + if (!service.verifyCredentials(credentials)) { + setStatus(GitHubUi.createErrorStatus("Invalid credentials. Please check your GitHub User ID and API Token.\nYou can find your API Token on your GitHub account settings page.")); + return; + } + } catch (GitHubServiceException e) { + setStatus(GitHubUi.createErrorStatus("Repository Test failed:"+ e.getMessage())); + return; + } + + setStatus(new Status(IStatus.OK,GitHubUi.BUNDLE_ID, "Success!")); + } finally { + monitor.done(); + } + } + }; + return validator; + } + + @Override + protected boolean isValidUrl(final String url) { + if (url.contains("github")) { + return true; + } + return false; + } + +} diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubTaskEditorPage.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubTaskEditorPage.java new file mode 100644 index 00000000..a24d8cb1 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubTaskEditorPage.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.ui.internal; + +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.mylyn.github.internal.GitHub; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; +import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor; +import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage; +import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory; +import org.eclipse.mylyn.tasks.ui.editors.TaskEditor; +import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor; + +/** + * Editor page for GitHub. + */ +public class GitHubTaskEditorPage extends AbstractTaskEditorPage { + + /** + * Constructor for the GitHubTaskEditorPage + * + * @param editor + * The task editor to create for GitHub + */ + public GitHubTaskEditorPage(final TaskEditor editor) { + super(editor, GitHub.CONNECTOR_KIND); + setNeedsPrivateSection(true); + setNeedsSubmitButton(true); + } + + @Override + protected Set<TaskEditorPartDescriptor> createPartDescriptors() { + Set<TaskEditorPartDescriptor> partDescriptors = super.createPartDescriptors(); + Iterator<TaskEditorPartDescriptor> descriptorIt = partDescriptors.iterator(); + while (descriptorIt.hasNext()) { + TaskEditorPartDescriptor partDescriptor = descriptorIt.next(); + if (partDescriptor.getId().equals(ID_PART_ATTRIBUTES)) { + descriptorIt.remove(); + } else if (partDescriptor.getId().equals(ID_PART_COMMENTS)) { + // currently the API doesn't support reading existing comments, + // though it does allow for creating them. Silly really. + // see http://support.github.com/discussions/feature-requests/696-issues-api-improvement + descriptorIt.remove(); + } + } + return partDescriptors; + } + + + @Override + protected AttributeEditorFactory createAttributeEditorFactory() { + return new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) { + @Override + public AbstractAttributeEditor createEditor(String type, + TaskAttribute taskAttribute) { + // TODO Auto-generated method stub + return super.createEditor(type, taskAttribute); + } + }; + } +} diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubTaskEditorPageFactory.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubTaskEditorPageFactory.java new file mode 100644 index 00000000..b442b494 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubTaskEditorPageFactory.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.ui.internal; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.mylyn.github.internal.GitHub; +import org.eclipse.mylyn.tasks.ui.ITasksUiConstants; +import org.eclipse.mylyn.tasks.ui.TasksUiUtil; +import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPageFactory; +import org.eclipse.mylyn.tasks.ui.editors.TaskEditor; +import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.editor.IFormPage; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * Editor page factory for GitHub. + */ +public class GitHubTaskEditorPageFactory extends AbstractTaskEditorPageFactory { + + private Image gitLogoImage = null; + + @Override + public boolean canCreatePageFor(TaskEditorInput input) { + if (GitHub.CONNECTOR_KIND.equals( + input.getTask().getConnectorKind())) { + return true; + } + if (TasksUiUtil.isOutgoingNewTask(input.getTask(), + GitHub.CONNECTOR_KIND)) { + return true; + } + return false; + } + + @Override + public Image getPageImage() { + if (gitLogoImage != null) + return gitLogoImage; + ImageDescriptor imageDescriptor = AbstractUIPlugin + .imageDescriptorFromPlugin("org.eclipse.mylyn.github.ui", + "images/git-logo.png"); + if (imageDescriptor == null) { + return null; + } + + return gitLogoImage = new Image(Display.getCurrent(), imageDescriptor + .getImageData()); + } + + @Override + public String getPageText() { + return "GitHub"; + } + + @Override + public int getPriority() { + return PRIORITY_TASK; + } + + @Override + public IFormPage createPage(TaskEditor parentEditor) { + return new GitHubTaskEditorPage(parentEditor); + } + + @Override + public String[] getConflictingIds(TaskEditorInput input) { + return new String[] { ITasksUiConstants.ID_PAGE_PLANNING }; + } + +} diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubUi.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubUi.java new file mode 100644 index 00000000..6b2bdb60 --- /dev/null +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/GitHubUi.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat 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: + * David Green <david.green@tasktop.com> - initial contribution + * Christian Trutz <christian.trutz@gmail.com> - initial contribution + * Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution + *******************************************************************************/ +package org.eclipse.mylyn.github.ui.internal; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; + +class GitHubUi { + public static final String BUNDLE_ID = "org.eclipse.mylyn.github.ui"; + + public static IStatus createStatus(int severity,String message) { + return new Status(severity,BUNDLE_ID,message); + } + + public static IStatus createStatus(int severity,String message,Throwable e) { + return new Status(severity,BUNDLE_ID,message,e); + } + + public static IStatus createErrorStatus(String message) { + return createStatus(IStatus.ERROR, message); + } + + public static IStatus createErrorStatus(String message,Throwable t) { + return createStatus(IStatus.ERROR, message,t); + } + + public static IStatus createErrorStatus(Throwable e) { + return createStatus(IStatus.ERROR, "Unexpected error: "+e.getMessage(),e); + } + + public static ILog getLog() { + return Platform.getLog(Platform.getBundle(BUNDLE_ID)); + } + + public static void logError(String message,Throwable t) { + getLog().log(createErrorStatus(message, t)); + } + + public static void logError(Throwable t) { + getLog().log(createErrorStatus(t.getMessage(), t)); + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..d97f8771 --- /dev/null +++ b/pom.xml @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> + + 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 +--> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <version>0.1.0-SNAPSHOT</version> + <prerequisites> + <maven>3.0</maven> + </prerequisites> + + <groupId>org.eclipse.mylyn.github</groupId> + <artifactId>github-parent</artifactId> + <packaging>pom</packaging> + + <name>Eclipse EGit Mylyn GitHub Connector Parent</name> + + <licenses> + <license> + <name>Eclipse Public License v1.0</name> + <comments> + 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.htm + </comments> + </license> + </licenses> + + <properties> + <tycho-version>0.10.0</tycho-version> + <platform-version-name>helios</platform-version-name> + <eclipse-site>http://download.eclipse.org/releases/${platform-version-name}</eclipse-site> + <orbit-site>http://download.eclipse.org/tools/orbit/downloads/drops/S20110124210048/repository</orbit-site> + </properties> + + <modules> + <module>org.eclipse.mylyn.github.core</module> + <module>org.eclipse.mylyn.github.ui</module> + <module>org.eclipse.mylyn.github-feature</module> + <module>org.eclipse.mylyn.github-site</module> + </modules> + + <repositories> + <repository> + <id>helios</id> + <layout>p2</layout> + <url>${eclipse-site}</url> + </repository> + <repository> + <id>orbit</id> + <layout>p2</layout> + <url>${orbit-site}</url> + </repository> + </repositories> + + <build> + <plugins> + <plugin> + <groupId>org.sonatype.tycho</groupId> + <artifactId>tycho-maven-plugin</artifactId> + <version>${tycho-version}</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.sonatype.tycho</groupId> + <artifactId>target-platform-configuration</artifactId> + <version>${tycho-version}</version> + <configuration> + <resolver>p2</resolver> + </configuration> + </plugin> + </plugins> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.sonatype.tycho</groupId> + <artifactId>maven-osgi-compiler-plugin</artifactId> + <version>${tycho-version}</version> + <configuration> + <encoding>UTF-8</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>2.4.1</version> + <configuration> + <encoding>UTF-8</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.sonatype.tycho</groupId> + <artifactId>target-platform-configuration</artifactId> + <version>${tycho-version}</version> + <configuration> + <resolver>p2</resolver> + <pomDependencies>consider</pomDependencies> + </configuration> + </plugin> + </plugins> + </pluginManagement> + <sourceDirectory>src/</sourceDirectory> + </build> + +<profiles> + <profile> + <id>platform-helios</id> + <activation> + <property> + <name>platform-version-name</name> + <value>helios</value> + </property> + </activation> + <properties> + <eclipse-site>http://download.eclipse.org/releases/helios</eclipse-site> + <platform-version>[3.6,3.7)</platform-version> + </properties> + </profile> + <profile> + <id>platform-indigo</id> + <activation> + <property> + <name>platform-version-name</name> + <value>indigo</value> + </property> + </activation> + <properties> + <eclipse-site>http://download.eclipse.org/releases/indigo</eclipse-site> + <platform-version>[3.7,3.8)</platform-version> + </properties> + </profile> + </profiles> +</project> |