/*******************************************************************************
* 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:
* Chris Aniszczyk <caniszczyk@gmail.com> - initial contribution
*******************************************************************************/
package org.eclipse.mylyn.internal.github.ui.gist;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Locale;
import java.util.Set;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.egit.github.core.client.GitHubClient;
import org.eclipse.egit.github.core.service.GistService;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.mylyn.internal.github.core.gist.GistConnector;
import org.eclipse.mylyn.internal.github.ui.GitHubUi;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPart2;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* Create Gist handler class.
*/
public class CreateGistHandler extends AbstractHandler {
/**
* PUBLIC_GIST
*/
public static final String PUBLIC_GIST = "publicGist"; //$NON-NLS-1$
/**
* DEFAULT_FILENAME
*/
private static final String DEFAULT_FILENAME = "file.txt"; //$NON-NLS-1$
/**
* @see org.eclipse.core.commands.AbstractHandler#isEnabled()
*/
public boolean isEnabled() {
return !GistConnectorUi.getRepositories().isEmpty();
}
/**
* TODO replace this with HandlerUtil.getActiveEditorInput(ExecutionEvent)
* as soon as we don't support Eclipse 3.6 anymore copied from HandlerUtil
* in 3.7 to be able to run this on 3.6
*
* Return the input of the active editor.
*
* @param event
* The execution event that contains the application context
* @return the input of the active editor, or <code>null</code>.
*/
private static IEditorInput getActiveEditorInput(ExecutionEvent event) {
Object var = HandlerUtil.getVariable(event,
ISources.ACTIVE_EDITOR_INPUT_NAME);
return var instanceof IEditorInput ? (IEditorInput) var : null;
}
/**
* Get active part
*
* @param event
* @return part
*/
private IWorkbenchPart getActivePart(ExecutionEvent event) {
Object var = HandlerUtil.getVariable(event, ISources.ACTIVE_PART_NAME);
return var instanceof IWorkbenchPart ? (IWorkbenchPart) var : null;
}
public Object execute(ExecutionEvent event) throws ExecutionException {
// TODO replace this with
// HandlerUtil.getActiveEditorInput(ExecutionEvent) as soon
// as we don't support Eclipse 3.6 anymore
IEditorInput input = getActiveEditorInput(event);
IWorkbenchPart part = getActivePart(event);
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection == null || selection.isEmpty())
selection = HandlerUtil.getActiveMenuSelection(event);
if (selection == null || selection.isEmpty())
return null;
boolean isPublic = Boolean
.parseBoolean(event.getParameter(PUBLIC_GIST));
if (selection instanceof ITextSelection) {
ITextSelection text = (ITextSelection) selection;
String name = null;
if (part == null || part instanceof IEditorPart) {
if (input instanceof IFileEditorInput) {
IFile file = ((IFileEditorInput) input).getFile();
if (file != null)
name = file.getName();
}
if (name == null && input instanceof IPathEditorInput) {
IPath path = ((IPathEditorInput) input).getPath();
if (path != null)
name = path.lastSegment();
}
if (name == null && input instanceof IURIEditorInput) {
URI uri = ((IURIEditorInput) input).getURI();
if (uri != null) {
String rawPath = uri.getRawPath();
if (rawPath != null) {
int lastSlash = rawPath.lastIndexOf('/') + 1;
if (lastSlash > 0 && lastSlash < rawPath.length())
name = rawPath.substring(lastSlash);
}
}
}
} else if (part instanceof IWorkbenchPart2)
name = ((IWorkbenchPart2) part).getPartName().replace(" ", "")
.toLowerCase(Locale.US)
+ ".txt";
if (name == null)
name = DEFAULT_FILENAME;
createGistJob(event, name, text.getText(), isPublic);
} else if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
Object obj = structuredSelection.getFirstElement();
IResource file = null;
if (obj instanceof IResource)
file = (IResource) obj;
else if (obj instanceof IAdaptable) {
file = (IResource) ((IAdaptable) obj)
.getAdapter(IResource.class);
if (file == null)
file = (IFile) ((IAdaptable) obj).getAdapter(IFile.class);
}
if (file instanceof IFile)
createGistJob(event, (IFile) file, isPublic);
}
return null;
}
private void createGistJob(ExecutionEvent event, String name,
String contents, boolean isPublic) {
Set<TaskRepository> repositories = GistConnectorUi.getRepositories();
if (repositories.isEmpty())
return;
TaskRepository repository = null;
// Prompt for repository selection if more than one
if (repositories.size() > 1) {
GistConnectorSelectionDialog dialog = new GistConnectorSelectionDialog(
HandlerUtil.getActiveShell(event), repositories);
if (Window.OK == dialog.open())
repository = (TaskRepository) dialog.getResult()[0];
} else
repository = repositories.iterator().next();
if (repository == null)
return;
GitHubClient client = GistConnector.createClient(repository);
GistService service = new GistService(client);
CreateGistJob job = new CreateGistJob(
Messages.CreateGistHandler_CreateGistJobName, name, contents,
service, isPublic, repository);
job.schedule();
}
private void createGistJob(ExecutionEvent event, IFile file,
boolean isPublic) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(file.getContents()));
String line;
StringBuilder result = new StringBuilder();
while ((line = br.readLine()) != null)
result.append(line).append('\n');
String contents = result.toString();
createGistJob(event, file.getName(), contents, isPublic);
} catch (CoreException e) {
GitHubUi.logError(e);
} catch (IOException e) {
GitHubUi.logError(e);
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
GitHubUi.logError(e);
}
}
}
}