blob: 8589ab6d6dc3a2ba7c26fbab12511228162afde0 [file] [log] [blame]
/*
* Copyright (c) 2016 Manumitting Technologies Inc. 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:
* Manumitting Technologies Inc - initial API and implementation
*/
package org.eclipse.userstorage.sdk.browser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.StatusLineContributionItem;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.userstorage.IBlob;
import org.eclipse.userstorage.IStorage;
import org.eclipse.userstorage.StorageFactory;
import org.eclipse.userstorage.internal.util.StringUtil;
import org.eclipse.userstorage.oauth.EclipseOAuthCredentialsProvider;
public class USSBrowsingView extends ViewPart {
private static final String APP_TOKEN_OOMPH = "cNhDr0INs8T109P8h6E1r_GvU3I";
private static final String APP_TOKEN_MPC = "MZ04RMOpksKN5GpxKXafq2MSjSP";
private TableViewer viewer;
private Action showMPCBucketAction;
private Action showOomphBucketAction;
private Action setOAuthParametersAction;
private Action restoreDefaultOAuthParametersAction;;
private StatusLineContributionItem statusText;
private Text appTokenText;
private Button useOAuth;
private String oauthClientId;
private String oauthClientSecret;
private String[] oauthScopes;
private URI oauthExpectedCallback;
private URI oauthAuthorizationService;
public USSBrowsingView() {
resetDefaults();
}
private void resetDefaults() {
try {
oauthAuthorizationService = new URI("https://accounts.eclipse.org/");
oauthClientId = Constants.getOAuthClientId();
oauthClientSecret = Constants.getOAuthClientSecret();
// "profile": the user personal identification information
oauthScopes = new String[] { "profile", "uss_all_retrieve", };
oauthExpectedCallback = new URI("http://localhost/");
refresh();
} catch (URISyntaxException e) {
// this is never expected to happen
ErrorDialog.openError(getViewSite().getShell(), "Error Configuring OAuth", "Exception occurred",
new Status(IStatus.ERROR, getClass().getName(), "Exception", e));
}
}
public void createPartControl(Composite c) {
Composite parent = new Composite(c, SWT.NONE);
{
Composite header = new Composite(parent, SWT.NONE);
header.setLayout(new RowLayout());
Label label = new Label(header, SWT.NONE);
label.setText("Application Token:");
appTokenText = new Text(header, SWT.SINGLE | SWT.BORDER);
appTokenText.setMessage("Application token");
GC gc = new GC(appTokenText);
int fontWidth = gc.getFontMetrics().getAverageCharWidth();
gc.dispose();
appTokenText.setLayoutData(new RowData(30 * fontWidth, SWT.DEFAULT));
useOAuth = new Button(header, SWT.CHECK);
useOAuth.setText("Use OAuth?");
useOAuth.setSelection(true);
appTokenText.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
refresh();
}
});
useOAuth.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
refresh();
}
});
}
Composite tableContainer = new Composite(parent, SWT.NONE);
TableColumnLayout tableLayout = new TableColumnLayout();
tableContainer.setLayout(tableLayout);
viewer = new TableViewer(tableContainer, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.getTable().setHeaderVisible(true);
viewer.setContentProvider(ArrayContentProvider.getInstance());
GridDataFactory.defaultsFor(viewer.getControl()).grab(true, true).applyTo(viewer.getControl());
TableViewerColumn tvcBlobId = new TableViewerColumn(viewer, SWT.LEFT);
tableLayout.setColumnData(tvcBlobId.getColumn(), new ColumnWeightData(20));
tvcBlobId.getColumn().setText("Blob ID");
tvcBlobId.setLabelProvider(new CellLabelProvider() {
@Override
public void update(ViewerCell cell) {
IBlob blob = (IBlob) cell.getElement();
cell.setText(blob.getKey());
}
});
TableViewerColumn tvcBlobContent = new TableViewerColumn(viewer, SWT.LEFT);
tableLayout.setColumnData(tvcBlobContent.getColumn(), new ColumnWeightData(80));
tvcBlobContent.getColumn().setText("Content");
tvcBlobContent.setLabelProvider(new CellLabelProvider() {
@Override
public void update(ViewerCell cell) {
IBlob blob = (IBlob) cell.getElement();
cell.setText(toText(blob));
}
});
GridDataFactory.fillDefaults().grab(true, true).applyTo(tableContainer);
GridLayoutFactory.fillDefaults().generateLayout(parent);
getSite().setSelectionProvider(viewer);
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
}
protected String toText(IBlob blob) {
InputStream stream = null;
try {
stream = blob.getContents();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StringUtil.UTF8));
StringBuilder sb = new StringBuilder();
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) > 0) {
sb.append(buffer, 0, len);
}
return sb.toString();
} catch (IOException e) {
return e.toString();
} finally {
if(stream != null) {
try {
stream.close();
} catch (IOException e) {
/* ignored */}
}
}
}
private void refresh() {
if (appTokenText == null) {
// not yet rendered
return;
}
applicationTokenChanged(appTokenText.getText(), useOAuth.getSelection());
}
protected void applicationTokenChanged(String appToken, boolean useOAuth) {
getViewSite().getActionBars().getStatusLineManager().setErrorMessage(null);
try {
final IStorage storage = StorageFactory.DEFAULT.create(appToken);
if (useOAuth) {
EclipseOAuthCredentialsProvider credentialsProvider = new EclipseOAuthCredentialsProvider(
oauthAuthorizationService, oauthClientId, oauthClientSecret, oauthScopes,
oauthExpectedCallback);
credentialsProvider.setShell(getViewSite());
storage.setCredentialsProvider(credentialsProvider);
}
Job loadBlobs = new Job("Load blobs") {
@Override
protected IStatus run(IProgressMonitor monitor) {
SubMonitor progress = SubMonitor.convert(monitor);
final List<IBlob> blobs = new ArrayList<IBlob>();
try {
for (IBlob b : storage.getBlobs()) {
blobs.add(b);
progress.worked(1);
}
} catch (IOException e) {
return new Status(IStatus.ERROR, getClass().getName(), 0, "Unable to load blobs", e);
}
asyncExec(new Runnable() {
public void run() {
update(storage, blobs);
done(Status.OK_STATUS);
}
});
return ASYNC_FINISH;
}
};
loadBlobs.schedule();
} catch (Exception e) {
getViewSite().getActionBars().getStatusLineManager().setErrorMessage(e.getMessage());
}
}
protected void update(IStorage storage, List<IBlob> blobs) {
viewer.setInput(blobs);
statusText.setText("Service: " + storage.getService().toString());
statusText.getParent().update(true);
}
protected void asyncExec(Runnable runnable) {
Display d = getSite().getShell().getDisplay();
if (!d.isDisposed()) {
d.asyncExec(runnable);
}
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
statusText = new StatusLineContributionItem(getViewSite().getId());
bars.getStatusLineManager().add(statusText);
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(showMPCBucketAction);
manager.add(showOomphBucketAction);
manager.add(new Separator());
manager.add(setOAuthParametersAction);
manager.add(restoreDefaultOAuthParametersAction);
}
private void fillContextMenu(IMenuManager manager) {
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
}
private void makeActions() {
showMPCBucketAction = new Action() {
public void run() {
appTokenText.setText(APP_TOKEN_MPC);
useOAuth.setSelection(true);
applicationTokenChanged(APP_TOKEN_MPC, true);
}
};
showMPCBucketAction.setText("Browse Marketplace Data");
showMPCBucketAction.setToolTipText("Use Eclipse Marketplace USS application token");
showOomphBucketAction = new Action() {
public void run() {
appTokenText.setText(APP_TOKEN_OOMPH);
useOAuth.setSelection(true);
applicationTokenChanged(APP_TOKEN_OOMPH, true);
}
};
showOomphBucketAction.setText("Browse Oomph Data");
showOomphBucketAction.setToolTipText("Use Oomph USS application token");
restoreDefaultOAuthParametersAction = new Action() {
public void run() {
resetDefaults();
}
};
restoreDefaultOAuthParametersAction.setText("Restore Default OAuth Client Parameters");
setOAuthParametersAction = new Action() {
public void run() {
OAuthClientDetailsDialog dialog = new OAuthClientDetailsDialog(getSite().getShell(),
oauthAuthorizationService, oauthClientId, oauthClientSecret, oauthScopes,
oauthExpectedCallback);
if (dialog.open() == OAuthClientDetailsDialog.OK) {
oauthAuthorizationService = dialog.getAuthorizationURI();
oauthClientId = dialog.getClientId();
oauthClientSecret = dialog.getClientSecret();
oauthScopes = dialog.getScopes();
oauthExpectedCallback = dialog.getExpectedCallbackURIText();
refresh();
}
}
};
setOAuthParametersAction.setText("Set OAuth Client Parameters");
// doubleClickAction = new Action() {
// public void run() {
// ISelection selection = viewer.getSelection();
// Object obj = ((IStructuredSelection) selection).getFirstElement();
// showMessage("Double-click detected on " + obj.toString());
// }
// };
}
private void hookDoubleClickAction() {
// viewer.addDoubleClickListener(new IDoubleClickListener() {
// public void doubleClick(DoubleClickEvent event) {
// doubleClickAction.run();
// }
// });
}
public void setFocus() {
viewer.getControl().setFocus();
}
}