Inital commit

This commit is contained in:
Tilman
2011-10-26 09:44:02 +02:00
commit 5971f4b417
1813 changed files with 737837 additions and 0 deletions
@@ -0,0 +1,575 @@
/* Copyright (c) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.projecthosting;
import com.google.gdata.client.projecthosting.IssuesQuery;
import com.google.gdata.client.projecthosting.ProjectHostingService;
import com.google.gdata.data.HtmlTextConstruct;
import com.google.gdata.data.Person;
import com.google.gdata.data.TextContent;
import com.google.gdata.data.projecthosting.BlockedOn;
import com.google.gdata.data.projecthosting.BlockedOnUpdate;
import com.google.gdata.data.projecthosting.Blocking;
import com.google.gdata.data.projecthosting.Cc;
import com.google.gdata.data.projecthosting.CcUpdate;
import com.google.gdata.data.projecthosting.IssueCommentsEntry;
import com.google.gdata.data.projecthosting.IssueCommentsFeed;
import com.google.gdata.data.projecthosting.IssuesEntry;
import com.google.gdata.data.projecthosting.IssuesFeed;
import com.google.gdata.data.projecthosting.Label;
import com.google.gdata.data.projecthosting.Owner;
import com.google.gdata.data.projecthosting.Updates;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This is a simple client that provides high-level operations on the Google
* Code Project Hosting Issue Tracker Data API. It can also be used as a
* command-line application to test out some of the features of the API.
*
*
*/
public class ProjectHostingClient {
private ProjectHostingService service;
private static final String FEED_URI_BASE =
"https://code.google.com/feeds/issues";
private static final String PROJECTION = "/full";
// User-provided input
private String project;
private String username;
private String password;
/** Issues API base URL constructed from the given project name. */
private String issuesBaseUri;
/** Default issues feed URL constructed from the given project name. */
private URL issuesFeedUrl;
/** Group 1 of the regex will match the ID of the issue. */
private Pattern issueIdPattern;
/** Group 1 of the regex will match the ID of the comment. */
private Pattern commentIdPattern;
private static final String DIVIDER =
"-----------------------------------------------------------------------";
/**
* Constructs a new client.
*
* @throws AuthenticationException if authentication fails
* @throws MalformedURLException if there's a problem with URL
*/
public ProjectHostingClient(
ProjectHostingService service, String project, String username,
String password) throws AuthenticationException, MalformedURLException {
this.service = service;
this.project = project;
this.username = username;
this.password = password;
// Login via ClientLogin
if ((username != null) && (password != null)) {
service.setUserCredentials(username, password);
}
issuesBaseUri = FEED_URI_BASE + "/p/" + project + "/issues";
issuesFeedUrl = makeIssuesFeedUrl(project);
String issuesBaseUriHttp = issuesBaseUri.replaceFirst("https", "http");
issueIdPattern = Pattern.compile(
issuesBaseUriHttp + PROJECTION + "/(\\d+)$");
commentIdPattern = Pattern.compile(
issuesBaseUriHttp + "/\\d+/comments" + PROJECTION + "/(\\d+)$");
}
/**
* Getter method for {@code issuesFeedUrl}.
*/
protected URL getIssuesFeedUrl() {
return issuesFeedUrl;
}
/**
* Setter method for {@code issuesFeedUrl}.
*/
protected void setIssuesFeedUrl(URL url) {
issuesFeedUrl = url;
}
/**
* Constructs issues feed URL.
*
* @param proj name of the project for the issues feed
* @throws MalformedURLException if there's a problem with URL
*/
protected URL makeIssuesFeedUrl(String proj)
throws MalformedURLException {
return new URL(FEED_URI_BASE + "/p/" + proj + "/issues" + PROJECTION);
}
/**
* Constructs issue entry URL.
*
* @param issueId ID number of an issue to construct the issue entry URL
* @throws MalformedURLException if there's a problem with URL
*/
protected URL makeIssueEntryUrl(String issueId)
throws MalformedURLException {
return new URL(issuesBaseUri + PROJECTION + "/" + issueId);
}
/**
* Constructs comments feed URL.
*
* @param issueId ID number of an issue to construct the comments URL
* @throws MalformedURLException if there's a problem with URL
*/
protected URL makeCommentsFeedUrl(String issueId)
throws MalformedURLException {
return new URL(issuesBaseUri + "/" + issueId + "/comments" + PROJECTION);
}
/**
* Constructs comment entry URL.
*
* @param issueId ID number of an issue the comment belongs to
* @param commentId ID number of the comment
* @throws MalformedURLException if there's a problem with URL
*/
protected URL makeCommentEntryUrl(String issueId, String commentId)
throws MalformedURLException {
return new URL(issuesBaseUri + "/" + issueId + "/comments" + PROJECTION
+ "/" + commentId);
}
/**
* Retrieves issues feed.
*
* @param feedUrl feed URL of issues to retrieve
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssuesFeed getIssuesFeed(URL feedUrl)
throws IOException, ServiceException {
return service.getFeed(feedUrl, IssuesFeed.class);
}
/**
* Retrieves a particular issue entry.
*
* @param issueId ID number of an issue to retrieve
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssuesEntry getIssueEntry(String issueId)
throws IOException, ServiceException {
return getIssueEntry(makeIssueEntryUrl(issueId));
}
/**
* Retrieves a particular issue entry.
*
* @param entryUrl URL of an issue entry to retrieve
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssuesEntry getIssueEntry(URL entryUrl)
throws IOException, ServiceException {
return service.getEntry(entryUrl, IssuesEntry.class);
}
/**
* Retrieves comments feed.
*
* @param issueId ID number of an issue to retrieve comments from
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssueCommentsFeed getCommentsFeed(String issueId)
throws IOException, ServiceException {
return getCommentsFeed(makeCommentsFeedUrl(issueId));
}
/**
* Retrieves comments feed.
*
* @param feedUrl comments feed URL to retrieve
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssueCommentsFeed getCommentsFeed(URL feedUrl)
throws IOException, ServiceException {
return service.getFeed(feedUrl, IssueCommentsFeed.class);
}
/**
* Retrieves a particular comment entry.
*
* @param issueId ID number of an issue the comment belongs to
* @param commentId ID number of a comment to retrieve
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssueCommentsEntry getCommentEntry(
String issueId, String commentId)
throws IOException, ServiceException {
return getCommentEntry(makeCommentEntryUrl(issueId, commentId));
}
/**
* Retrieves a particular comment entry.
*
* @param entryUrl comment entry URL to retrieve
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssueCommentsEntry getCommentEntry(URL entryUrl)
throws IOException, ServiceException {
return service.getEntry(entryUrl, IssueCommentsEntry.class);
}
/**
* Inserts an issue entry to the issues feed.
*
* @param entry issue entry to insert
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssuesEntry insertIssue(IssuesEntry entry)
throws IOException, ServiceException {
return service.insert(issuesFeedUrl, entry);
}
/**
* Inserts a comment entry to the comments feed.
*
* @param issueId ID number of an issue to insert the comment entry to
* @param entry comment entry to insert
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssueCommentsEntry insertComment(
String issueId, IssueCommentsEntry entry)
throws IOException, ServiceException {
return insertComment(makeCommentsFeedUrl(issueId), entry);
}
/**
* Inserts a comment entry to the comments feed.
*
* @param commentsFeedUrl comments feed URL to insert the comment entry to
* @param entry comment entry to insert
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssueCommentsEntry insertComment(
URL commentsFeedUrl, IssueCommentsEntry entry)
throws IOException, ServiceException {
return service.insert(commentsFeedUrl, entry);
}
/**
* Queries issues using the given query parameters.
*
* @param query issues query object with query parameters set
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected IssuesFeed queryIssues(IssuesQuery query)
throws IOException, ServiceException {
return service.query(query, IssuesFeed.class);
}
/**
* Returns the numeric issue ID from the given {@code issueUrl}.
*
* @param issueUrl URI to find the issue ID from
*/
protected String getIssueId(String issueUrl) {
Matcher matcher = issueIdPattern.matcher(issueUrl);
return matcher.matches() ? matcher.group(1) : null;
}
/**
* Returns the numeric commentId from the given {@code commentUrl}.
*
* @param commentUrl URI to find the comment ID from
*/
protected String getCommentId(String commentUrl) {
Matcher matcher = commentIdPattern.matcher(commentUrl);
return matcher.matches() ? matcher.group(1) : null;
}
/**
* Prints issues in the given issues feed.
*
* @param issuesFeed issues feed to print
*/
protected void printIssues(IssuesFeed issuesFeed) {
for (IssuesEntry issueEntry : issuesFeed.getEntries()) {
printIssue(issueEntry);
}
}
/**
* Prints an issue entry in human-readable format.
*
* @param entry issue entry to print
*/
protected void printIssue(IssuesEntry entry) {
System.out.println(DIVIDER);
if (entry.getId() != null) {
String issueId = getIssueId(entry.getId());
System.out.printf("Issue #%s:\t%s\n", issueId, entry.getId());
} else {
System.out.println("Issue");
}
if (entry.getTitle() != null) {
System.out.println("\tSummary\n\t\t" + entry.getTitle().getPlainText());
}
Person author = entry.getAuthors().get(0);
printPerson("Reporter", author.getName(), author.getUri());
TextContent textContent = (TextContent) entry.getContent();
if ((textContent != null) && (textContent.getContent() != null)) {
HtmlTextConstruct textConstruct =
(HtmlTextConstruct) textContent.getContent();
System.out.println("\tDescription\n\t\t" + textConstruct.getHtml());
}
if (entry.hasStatus()) {
System.out.println("\tStatus\n\t\t" + entry.getStatus().getValue());
}
if (entry.hasOwner()) {
Owner owner = entry.getOwner();
printPerson(
"Owner", owner.getUsername().getValue(),
(owner.getUri() == null) ? null : owner.getUri().getValue());
}
if (entry.getLabels().size() > 0) {
System.out.println("\tLabel");
for (Label label : entry.getLabels()) {
System.out.println("\t\t" + label.getValue());
}
}
if (entry.getCcs().size() > 0) {
System.out.println("\tCC");
for (Cc cc : entry.getCcs()) {
printPerson(
null, cc.getUsername().getValue(),
(cc.getUri() == null) ? null : cc.getUri().getValue());
}
}
if (entry.getBlockedOns().size() > 0) {
System.out.println("\tBlockedOn");
for (BlockedOn blockedOn : entry.getBlockedOns()) {
System.out.print("\t\t");
if (blockedOn.hasProject()) {
System.out.print(blockedOn.getProject().getValue() + ":");
}
System.out.println(blockedOn.getId().getValue());
}
}
if (entry.getBlockings().size() > 0) {
System.out.println("\tBlocking");
for (Blocking blocking : entry.getBlockings()) {
System.out.print("\t\t");
if (blocking.hasProject()) {
System.out.print(blocking.getProject().getValue() + ":");
}
System.out.println(blocking.getId().getValue());
}
}
if (entry.hasMergedInto()) {
System.out.print("\tMergedInto\n\t\t");
if (entry.getMergedInto().hasProject()) {
System.out.print(entry.getMergedInto().getProject().getValue() + ":");
}
System.out.println(entry.getMergedInto().getId().getValue());
}
}
/**
* Prints Username and URI associated with the labeled person.
*
* @param label label to print
* @param name username of the person to print
* @param uri uri of the person to print, usually the profile url
*/
protected void printPerson(String label, String name, String uri) {
if (label != null) {
System.out.printf("\t%s\n", label);
}
System.out.print("\t\t" + name);
if (uri != null) {
System.out.println("\t" + uri);
} else {
System.out.println();
}
}
/**
* Prints issues and their comments.
*
* @param issuesFeed issues feed to print
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected void printIssuesAndComments(IssuesFeed issuesFeed)
throws IOException, ServiceException {
for (IssuesEntry issueEntry : issuesFeed.getEntries()) {
printIssueAndComments(issueEntry);
}
}
/**
* Prints an issue and its comments.
*
* @param issueId ID number of an issue to print
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected void printIssueAndComments(String issueId)
throws IOException, ServiceException {
printIssueAndComments(getIssueEntry(issueId));
}
/**
* Prints an issue and its comments.
*
* @param issueUrl URL of an issue to print
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected void printIssueAndComments(URL issueUrl)
throws IOException, ServiceException {
printIssueAndComments(getIssueEntry(issueUrl));
}
/**
* Prints an issue and its comments.
*
* @param issue issue entry to print
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
protected void printIssueAndComments(IssuesEntry entry)
throws IOException, ServiceException {
printIssue(entry);
String issueId = getIssueId(entry.getId());
IssueCommentsFeed commentsFeed = getCommentsFeed(issueId);
printComments(commentsFeed);
}
/**
* Prints comments in the given comments feed.
*
* @param commentsFeed comments feed to print
*/
protected void printComments(IssueCommentsFeed commentsFeed) {
for (IssueCommentsEntry commentEntry : commentsFeed.getEntries()) {
printComment(commentEntry);
}
}
/**
* Prints a comment entry in human-readable format.
*
* @param entry comment entry to print
*/
protected void printComment(IssueCommentsEntry entry) {
System.out.println(DIVIDER);
if (entry.getId() != null) {
String commentId = getCommentId(entry.getId());
System.out.printf("Comment #%s:\t%s\n", commentId, entry.getId());
} else {
System.out.println("Comment");
}
Person author = entry.getAuthors().get(0);
printPerson("Author", author.getName(), author.getUri());
TextContent textContent = (TextContent) entry.getContent();
if ((textContent != null) && (textContent.getContent() != null)) {
HtmlTextConstruct textConstruct =
(HtmlTextConstruct) textContent.getContent();
System.out.println("\tComment\n\t\t" + textConstruct.getHtml());
}
if (entry.hasUpdates()) {
Updates updates = entry.getUpdates();
if (updates.hasSummary()) {
System.out.println("\tSummary\n\t\t" + updates.getSummary().getValue());
}
if (updates.hasStatus()) {
System.out.println("\tStatus\n\t\t" + updates.getStatus().getValue());
}
if (updates.hasOwnerUpdate()) {
System.out.println(
"\tOwner\n\t\t" + updates.getOwnerUpdate().getValue());
}
if (updates.getLabels().size() > 0) {
System.out.println("\tLabel");
for (Label label : updates.getLabels()) {
System.out.println("\t\t" + label.getValue());
}
}
if (updates.getCcUpdates().size() > 0) {
System.out.println("\tCC");
for (CcUpdate cc : updates.getCcUpdates()) {
System.out.println("\t\t" + cc.getValue());
}
}
if (updates.getBlockedOnUpdates().size() > 0) {
System.out.println("\tBlockedOnUpdate");
for (BlockedOnUpdate blockedOnUpdate : updates.getBlockedOnUpdates()) {
System.out.println("\t\t" + blockedOnUpdate.getValue());
}
}
if (updates.hasMergedIntoUpdate()) {
System.out.println(
"\tMergedIntoUpdate\n\t\t" +
updates.getMergedIntoUpdate().getValue());
}
}
}
}
@@ -0,0 +1,281 @@
/* Copyright (c) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.projecthosting;
import com.google.gdata.client.projecthosting.IssuesQuery;
import com.google.gdata.client.projecthosting.ProjectHostingService;
import sample.util.SimpleCommandLineParser;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.projecthosting.IssuesFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
/**
* A Command-line application using the {@link ProjectHostingClient} to make
* calls to the Google Code Issue Tracker Data API.
* The following operations are handled:
*
* <ol>
* <li>Retrieving the list of issues in a project</li>
* <li>Querying issues with query parameters</li>
* <li>Retrieving the list of comments in a given issue</li>
* </ol>
*
*
*/
public class ProjectHostingReadDemo {
/** Disable default public constructor */
private ProjectHostingReadDemo() {
}
/** Client that provides high level operations of the API */
private ProjectHostingClient client;
private static final String DIVIDER =
"=====================================================================\n";
/**
* Constructs the command line application.
*
* @throws AuthenticationException if authentication fails
* @throws MalformedURLException if there's a problem with URL
*/
public ProjectHostingReadDemo(
ProjectHostingService service, String project, String username,
String password) throws AuthenticationException, MalformedURLException {
client = new ProjectHostingClient(service, project, username, password);
}
/**
* Main entry point. Parses arguments and creates and invokes the demo.
*/
public static void main(String[] arg) throws Exception {
SimpleCommandLineParser parser = new SimpleCommandLineParser(arg);
// Parse command-line flags
String project = parser.getValue("project");
String username = parser.getValue("username");
String password = parser.getValue("password");
boolean help = parser.containsKey("help");
if (help || (project == null)) {
usage();
System.exit(help ? 0 : 1);
}
if (username == null) {
System.out.println(
"***WARNING*** Unauthenticated user. To see any restricted issues, "
+ "you must authenticate yourself and have proper permission setting "
+ "for the project " + project + ".\n"
+ "You can authenticate yourself by specifying <username> and "
+ "<password> when you invoke this demo as follows:");
usage();
}
ProjectHostingService service =
new ProjectHostingService("projecthosting-read-demo");
try {
new ProjectHostingReadDemo(service, project, username, password).run();
} catch (AuthenticationException e) {
System.out.println("The username/password entered is invalid.");
System.exit(1);
}
}
/** Input stream for reading user input. */
private static final BufferedReader IN =
new BufferedReader(new InputStreamReader(System.in));
/**
* Prompts and returns user input as an integer.
* It will keep asking until the user provides a valid number.
*
* @throws IOException if there is a I/O related problem
*/
private static int readInteger(String name) throws IOException {
while (true) {
String input = readString(name);
try {
return Integer.parseInt(input);
} catch (NumberFormatException nfe) {
System.out.println("Invalid number " + input);
}
}
}
/**
* Prompts and returns user input as a string.
*
* @throws IOException if there is a I/O related problem
*/
private static String readString(String name) throws IOException {
System.out.print("Please enter " + name + ": ");
System.out.flush();
String result = IN.readLine();
return result.trim();
}
/**
* Runs the main loop for reading issues and comments.
* It offers a choice for users to read issues or a specific issue
* and its comments and continues to do so until "exit" is selected.
*
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
private void run() throws IOException, ServiceException {
while (true) {
System.out.println(
DIVIDER
+ "Main menu:\n"
+ "[0] Exit\n"
+ "[1] Read issues\n"
+ "[2] Read an issue and its comments");
int choice = readInteger("action");
switch (choice) {
case 0:
return;
case 1:
addAndRunQuery();
break;
case 2:
String issueId = readString("issue ID");
client.printIssueAndComments(issueId);
break;
default:
System.out.println("Invalid choice " + choice);
break;
}
}
}
/**
* Builds and runs a query. The user is prompted to add query parameters
* until "done" is selected at which point it runs the query and displays
* issues returned.
* Choice #1 runs the query and shows the issues returned.
* Choice #2-13 lets users add query parameters.
*
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
private void addAndRunQuery() throws IOException, ServiceException {
IssuesQuery query = new IssuesQuery(client.getIssuesFeedUrl());
while (true) {
System.out.println(
DIVIDER
+ "Set query parameters. Choose [1] when you're done.\n"
+ "[0] Return to the main menu\n"
+ "[1] Done. Query issues now.\n"
+ "[2] Set full-text query\n"
+ "[3] Set published-min\n"
+ "[4] Set published-max\n"
+ "[5] Set updated-min\n"
+ "[6] Set updated-max\n"
+ "[7] Set start-index\n"
+ "[8] Set max-results\n"
+ "[9] Set owner\n"
+ "[10] Set reporter\n"
+ "[11] Set status\n"
+ "[12] Set label\n"
+ "[13] Set canned-query");
int choice = readInteger("action");
switch (choice) {
case 0:
return;
case 1:
IssuesFeed resultFeed = client.queryIssues(query);
int numResult = resultFeed.getEntries().size();
System.out.println(
"Query returned " + numResult + " matching issues.");
client.printIssues(resultFeed);
return;
case 2:
String textQuery = readString("full-text query");
query.setFullTextQuery(textQuery);
break;
case 3:
String publishedMin = readString("published-min");
query.setPublishedMin(DateTime.parseDate(publishedMin));
break;
case 4:
String publishedMax = readString("published-max");
query.setPublishedMax(DateTime.parseDate(publishedMax));
break;
case 5:
String updatedMin = readString("updated-min");
query.setUpdatedMin(DateTime.parseDate(updatedMin));
break;
case 6:
String updatedMax = readString("updated-max");
query.setUpdatedMax(DateTime.parseDate(updatedMax));
break;
case 7:
int startIndex = readInteger("start-index");
query.setStartIndex(startIndex);
break;
case 8:
int maxResults = readInteger("max-results");
query.setMaxResults(maxResults);
break;
case 9:
String owner = readString("owner");
query.setOwner(owner);
break;
case 10:
String reporter = readString("reporter");
query.setAuthor(reporter);
break;
case 11:
String status = readString("status");
query.setStatus(status);
break;
case 12:
String label = readString("label");
query.setLabel(label);
break;
case 13:
String cannedQuery = readString("canned-query");
query.setCan(cannedQuery);
break;
default:
System.out.println("Invalid choice " + choice);
break;
}
}
}
/**
* Prints usage of this application.
*/
private static void usage() {
System.out.println(
"Syntax: ProjectHostingReadDemo --project <project> "
+ "[--username <username> --password <password>]\n"
+ "\t<project>\tProject on which the demo will run.\n"
+ "\t<username>\tGoogle Account username\n"
+ "\t<password>\tGoogle Account password\n");
}
}
@@ -0,0 +1,256 @@
/* Copyright (c) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.projecthosting;
import com.google.gdata.client.projecthosting.ProjectHostingService;
import sample.util.SimpleCommandLineParser;
import com.google.gdata.data.HtmlTextConstruct;
import com.google.gdata.data.Person;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.projecthosting.Cc;
import com.google.gdata.data.projecthosting.CcUpdate;
import com.google.gdata.data.projecthosting.IssueCommentsEntry;
import com.google.gdata.data.projecthosting.IssuesEntry;
import com.google.gdata.data.projecthosting.Label;
import com.google.gdata.data.projecthosting.Owner;
import com.google.gdata.data.projecthosting.OwnerUpdate;
import com.google.gdata.data.projecthosting.SendEmail;
import com.google.gdata.data.projecthosting.Status;
import com.google.gdata.data.projecthosting.Summary;
import com.google.gdata.data.projecthosting.Updates;
import com.google.gdata.data.projecthosting.Username;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import java.io.IOException;
import java.net.MalformedURLException;
/**
* Demonstrates how to use the Google Data API's Java client library to
* interface with the Google Code Issue Tracker Data API.
* There are examples for the following operations:
*
* <ol>
* <li>Creating a new issue</li>
* <li>Updating the issue by adding a comment with updates</li>
* <li>Closing the issue by adding a comment with status "Fixed"</li>
* </ol>
*
*
*/
public class ProjectHostingWriteDemo {
/** Disable default public constructor */
private ProjectHostingWriteDemo() {
}
/** Client that provides high level operations of the API */
private ProjectHostingClient client;
private String username;
/**
* Constructs the command line application.
*
* @throws AuthenticationException if authentication fails
* @throws MalformedURLException if there's a problem with URL
*/
public ProjectHostingWriteDemo(
ProjectHostingService service, String project, String username,
String password) throws AuthenticationException, MalformedURLException {
this.username = username;
client = new ProjectHostingClient(service, project, username, password);
}
/**
* Main entry point. Parses arguments and creates and invokes the demo.
*/
public static void main(String[] arg) throws Exception {
SimpleCommandLineParser parser = new SimpleCommandLineParser(arg);
// Parse command-line flags
String project = parser.getValue("project");
String username = parser.getValue("username");
String password = parser.getValue("password");
boolean help = parser.containsKey("help");
if (help || (project == null) || (username == null) || (password == null)) {
usage();
System.exit(help ? 0 : 1);
}
ProjectHostingService service =
new ProjectHostingService("projecthosting-write-demo");
try {
new ProjectHostingWriteDemo(service, project, username, password).run();
} catch (AuthenticationException e) {
System.out.println("The username/password entered is invalid.");
System.exit(1);
}
}
/**
* Creates a new issue and adds two comments to it, first to update the
* issue and second to close it.
*
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
private void run() throws IOException, ServiceException {
// Create an issue
IssuesEntry issueInserted = client.insertIssue(makeNewIssue());
String issueId = client.getIssueId(issueInserted.getId());
System.out.println("Issue #" + issueId + " created");
// Add comments and updates to the issue created
addComment(issueId, makeUpdatingComment());
addComment(issueId, makePlainComment());
addComment(issueId, makeClosingComment());
// Print the issue and comments added
System.out.println("-----------------------------------------------------");
System.out.println("Issue created and comments added:");
client.printIssueAndComments(issueInserted);
}
/**
* Adds the given comment to the given issue.
*
* @throws IOException if there is a problem communicating with the server
* @throws ServiceException if the service is unable to handle the request
*/
private void addComment(String issueId, IssueCommentsEntry issueComment)
throws IOException, ServiceException {
IssueCommentsEntry commentInserted = client.insertComment(
issueId, issueComment);
String commentId = client.getCommentId(commentInserted.getId());
System.out.println("Comment #" + commentId + " added in issue #" + issueId);
}
/**
* Creates a new issue that can be inserted to the issues feed.
*/
protected IssuesEntry makeNewIssue() {
Person author = new Person();
author.setName(username);
Owner owner = new Owner();
owner.setUsername(new Username(username));
Cc cc = new Cc();
cc.setUsername(new Username(username));
IssuesEntry entry = new IssuesEntry();
entry.getAuthors().add(author);
// Uncomment the following line to set the owner along with issue creation.
// It's intentionally commented out so we can demonstrate setting the owner
// field using setOwnerUpdate() as shown in makeUpdatingComment() below.
// entry.setOwner(owner);
entry.setContent(new HtmlTextConstruct("issue description"));
entry.setTitle(new PlainTextConstruct("issue summary"));
entry.setStatus(new Status("New"));
entry.addLabel(new Label("Priority-High"));
entry.addLabel(new Label("Milestone-2009"));
entry.addCc(cc);
entry.setSendEmail(new SendEmail("False"));
return entry;
}
/**
* Creates a comment that updates an existing issue.
*/
protected IssueCommentsEntry makeUpdatingComment() {
Person author = new Person();
author.setName(username);
// Create issue updates
Updates updates = new Updates();
updates.setSummary(new Summary("New issue summary"));
updates.setStatus(new Status("Accepted"));
updates.setOwnerUpdate(new OwnerUpdate(username));
updates.addLabel(new Label("-Priority-High"));
updates.addLabel(new Label("Priority-Low"));
updates.addLabel(new Label("-Milestone-2009"));
updates.addLabel(new Label("Milestone-2010"));
updates.addLabel(new Label("Type-Enhancement"));
updates.addCcUpdate(new CcUpdate("-" + username));
// Create issue comment entry
IssueCommentsEntry entry = new IssueCommentsEntry();
entry.getAuthors().add(author);
entry.setContent(new HtmlTextConstruct("some comment"));
entry.setUpdates(updates);
entry.setSendEmail(new SendEmail("False"));
return entry;
}
/**
* Creates a comment without any updates.
*/
protected IssueCommentsEntry makePlainComment() {
Person author = new Person();
author.setName(username);
// Create issue comment entry
IssueCommentsEntry entry = new IssueCommentsEntry();
entry.getAuthors().add(author);
entry.setContent(new HtmlTextConstruct("Some comment"));
entry.setSendEmail(new SendEmail("False"));
return entry;
}
/**
* Creates a comment that closes an issue by setting Status to "Fixed".
*/
protected IssueCommentsEntry makeClosingComment() {
Person author = new Person();
author.setName(username);
// Set the Status as Fixed
Updates updates = new Updates();
updates.setStatus(new Status("Fixed"));
// Create issue comment entry
IssueCommentsEntry entry = new IssueCommentsEntry();
entry.getAuthors().add(author);
entry.setContent(new HtmlTextConstruct("This was fixed last week."));
entry.setUpdates(updates);
entry.setSendEmail(new SendEmail("False"));
return entry;
}
/**
* Prints usage of this application.
*/
private static void usage() {
System.out.println(
"Syntax: ProjectHostingWriteDemo --project <project> "
+ "--username <username> --password <password>\n"
+ "\t<project>\tProject on which the demo will run. This demo will "
+ "create a new issue in the given project and add comments to it.\n"
+ "\t<username>\tGoogle Account username\n"
+ "\t<password>\tGoogle Account password\n");
}
}
@@ -0,0 +1,32 @@
Google Code Issues Data API Java Sample - README.txt
----------------------------------------------------
These Java samples are simple applications that show how to create, read issues
and comments from Google Code using the GData Java client library.
The applications can be built and run using the provided Ant build file found at
gdata/java/build-samples.xml. The samples can be run in the following manner:
1. Edit gdata/java/build-samples/build.properties to enter your
Google Account username and password.
2. Invoke the samples using the appropriate commandline:
ant -f gdata/java/build-samples.xml sample.projecthosting.read.run
ant -f gdata/java/build-samples.xml sample.projecthosting.write.run
Alternately, you can compile and run them from the command line:
java sample.projecthosting.ProjectHostingReadDemo
--project [project]
--username [user]
--password [pass]
java sample.projecthosting.ProjectHostingWriteDemo
--project [project]
--username [user]
--password [pass]
NOTE: The ProjectHostingWriteDemo will create issues and add comments to them,
so it is recommended that you use a test project.