package org.vaadin.mideaas.app;
import java.io.IOException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.vaadin.addon.oauthpopup.OAuthListener;
import org.vaadin.addon.oauthpopup.buttons.GitHubButton;
import org.vaadin.mideaas.model.GitRepository;
import org.vaadin.mideaas.model.User;
import org.vaadin.mideaas.social.GitHubService;
import org.vaadin.mideaas.social.OAuthService.Service;
import org.vaadin.mideaas.social.UserProfile;
import org.vaadin.mideaas.social.UserToken;
import com.vaadin.server.ExternalResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.Notification;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
@SuppressWarnings("serial")
public class GitHubWindow extends Window {
private VerticalLayout layout = new VerticalLayout();
private final User user;
private final GitRepository repo;
private final String projectName;
protected GitHubService service;
public GitHubWindow(User user, GitRepository repo, String projectName) {
super("GitHub");
this.user = user;
this.repo = repo;
this.projectName = projectName;
layout.setMargin(true);
setContent(layout);
}
@Override
public void attach() {
super.attach();
redraw();
}
private void redraw() {
layout.removeAllComponents();
UserProfile profile = user.getProfile(Service.GITHUB);
if (profile==null) {
drawGitHubButton();
return;
}
else {
redrawConnected(profile);
}
}
private void redrawConnected(UserProfile profile) {
String remote = repo.getRemote(remoteName(profile));
if (remote==null) {
drawNewProject(profile);
}
else if (isGitHubOrigin(remote)) {
drawPush(profile);
}
else {
layout.addComponent(new Label("Git repository origin is not from GitHub."));
}
}
private void drawGitHubButton() {
final String key = GitPlugin.GITHUB_KEY;
final String secret = GitPlugin.GITHUB_SECRET;
GitHubButton ghb = new GitHubButton(key, secret);
ghb.setScope("repo");
ghb.setPopupWindowFeatures("resizable");
ghb.setCaption("Authorize with GitHub");
ghb.addOAuthListener(new OAuthListener() {
@Override
public void authSuccessful(String accessToken, String accessTokenSecret) {
service = new GitHubService(key, secret, new UserToken(accessToken, accessTokenSecret));
UserProfile profile = service.getUserProfile();
user.addProfile(profile);
redraw();
}
@Override
public void authDenied(String reason) {
Notification.show("Not authorized.");
}
});
layout.addComponent(ghb);
}
private static boolean isGitHubOrigin(String origin) {
return origin.contains("github.com"); // TODO better
}
private void drawNewProject(final UserProfile profile) {
Button bu = new Button("Create project in GitHub");
layout.addComponent(bu);
bu.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
newProject(profile);
}
});
}
private GitHubService getService() {
if (service==null) {
final String key = GitPlugin.GITHUB_KEY;
final String secret = GitPlugin.GITHUB_SECRET;
UserToken t = user.getProfile(Service.GITHUB).getToken();
service = new GitHubService(key, secret, new UserToken(t.getToken(), t.getSecret()));
}
return service;
}
protected void newProject(UserProfile profile) {
service = getService();
try {
String origin = service.createRepository(projectName);
repo.addRemote(remoteName(profile), origin);
Notification.show("Project created");
redraw();
} catch (IOException e) {
Notification.show(e.getMessage(), Notification.Type.ERROR_MESSAGE);
}
}
private static String remoteName(UserProfile profile) {
return "github-"+profile.getIdentifier();
}
private void drawPush(final UserProfile profile) {
final String remote = remoteName(profile);
String url = githubLinkFromOrigin(repo.getRemote(remote));
layout.addComponent(new Link(url, new ExternalResource(url)));
Button b = new Button("Push to GitHub");
b.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
gitPush(profile.getToken().getToken(), remote);
} catch (GitAPIException e) {
Notification.show(e.getMessage(), Notification.Type.ERROR_MESSAGE);
e.printStackTrace();
}
}
});
layout.addComponent(b);
}
private String githubLinkFromOrigin(String origin) {
return origin.replaceFirst(".git$", "");
}
/*
* Push to Gitrepository using OAuth token.
*
* Token can be acquired for example by writing:
* curl --insecure -u 'janne.lautamaki@tut.fi' -d '{"scopes":["repo"],"note":"Help example"}' https://api.github.com/authorizations
* Then password is asked:
* Enter host password for user 'janne.lautamaki@tut.fi':
* And finally we get response with the token that can be used
* {
* "id": 2670499,
* "url": "https://api.github.com/authorizations/2670499",
* "app": {
* "name": "Help example (API)",
* "url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api",
* "client_id": "9923f92ec0bd6f800a48"
* },
* "token": "f7b76c1d74b34079cbe1ea3f5156cc4b62060b88",
* "note": "Help example",
* "note_url": null,
* "created_at": "2013-05-29T10:23:56Z",
* "updated_at": "2013-05-29T10:23:56Z",
* "scopes": [
* "repo"
* ]
* }
*
* @param oauthToken the oauth token
* @throws GitAPIException the git api exception
*/
private void gitPush(String oauthToken, String remoteName) throws GitAPIException {
repo.pushAll(oauthToken, "", remoteName);
}
}