package com.cicadalane.androlate.statushandlers;
/*
* Copyright (C) 2011 cicada.software@gmail.com
*
* 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.
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider;
import org.eclipse.ui.statushandlers.StatusAdapter;
import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
import org.eclipse.ui.statushandlers.WorkbenchStatusDialogManager;
import com.cicadalane.androlate.Activator;
public class AndrolateStatusHandler extends WorkbenchErrorHandler {
@Override
public void handle(final StatusAdapter statusAdapter, int style) {
super.handle(statusAdapter, style);
}
@Override
protected void configureStatusDialog(
WorkbenchStatusDialogManager statusDialog) {
StackTraceSupportArea provider = new StackTraceSupportArea();
statusDialog.setSupportAreaProvider(provider);
super.configureStatusDialog(statusDialog);
}
public static class StackTraceSupportArea extends
AbstractStatusAreaProvider {
/*
* Displays statuses.
*/
private List list;
private Button submitBugReportButton;
private Clipboard clipboard;
/*
* (non-Javadoc)
*
* @seeorg.eclipse.ui.statushandlers.AbstractStatusAreaProvider#
* createSupportArea(org.eclipse.swt.widgets.Composite,
* org.eclipse.ui.statushandlers.StatusAdapter)
*/
public Control createSupportArea(final Composite parent,
StatusAdapter statusAdapter) {
Label label = new Label(parent, SWT.NONE);
label.setText("Title");
list = new List(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.grabExcessHorizontalSpace = true;
gd.grabExcessVerticalSpace = true;
gd.widthHint = 250;
list.setLayoutData(gd);
list.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (clipboard != null) {
clipboard.dispose();
}
}
});
list.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionAdapter#widgetSelected(org
* .eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
list.selectAll();
super.widgetSelected(e);
}
});
list.removeAll();
populateList(statusAdapter.getStatus());
createDNDSource();
createCopyAction(parent);
submitBugReportButton = new Button(parent, SWT.NONE);
submitBugReportButton.setText("Submit Bug Report");
submitBugReportButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
submitBugReport(parent);
}
});
return parent;
}
private void submitBugReport(Composite parent) {
URL url;
try {
url = new URL("http://cicadalane.com/feedback.php");
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
String message = Activator.PLUGIN_ID + " 0.1.0\n";
message.concat("\n");
message.concat("\n\n");
for (String itemString : getList().getItems()) {
String is = itemString;
message = message.concat(is);
message = message.concat("\n");
}
if (message.length() == 0)
message = "(empty)";
String content = "product="
+ URLEncoder.encode(Activator.PLUGIN_ID, "UTF-8")
+ "&message=" + URLEncoder.encode(message, "UTF-8");
final PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.write(content);
pw.flush();
InputStreamReader isr = null;
try {
isr = new InputStreamReader(conn.getInputStream(), "UTF8");
BufferedReader rd = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null)
sb.append(line);
} catch (UnsupportedEncodingException e) {
MessageDialog.openError(parent.getShell(),
"Unable to submit bug report",
"UnsupportedEncodingException " + e.getMessage());
} catch (IOException e) {
MessageDialog.openError(parent.getShell(),
"Unable to submit bug report", "IOException "
+ e.getMessage());
} finally {
conn.getInputStream().close();
if (conn.getErrorStream() != null) {
conn.getErrorStream().close();
}
pw.close();
if (isr != null)
isr.close();
}
} catch (MalformedURLException e) {
MessageDialog.openError(parent.getShell(),
"Unable to submit bug report", "MalformedURLException "
+ e.getMessage());
} catch (ProtocolException e) {
MessageDialog.openError(parent.getShell(),
"Unable to submit bug report", "ProtocolException "
+ e.getMessage());
} catch (IOException e) {
MessageDialog.openError(parent.getShell(),
"Unable to submit bug report", "IOException "
+ e.getMessage());
}
MessageDialog.openInformation(parent.getShell(),
"Bug report submitted",
"Your bug report was sent, thank you for reporting it");
}
/**
* Creates DND source for the list
*/
private void createDNDSource() {
DragSource ds = new DragSource(list, DND.DROP_COPY);
ds.setTransfer(new Transfer[] { TextTransfer.getInstance() });
ds.addDragListener(new DragSourceListener() {
public void dragFinished(DragSourceEvent event) {
}
public void dragSetData(DragSourceEvent event) {
if (TextTransfer.getInstance().isSupportedType(
event.dataType)) {
event.data = prepareCopyString();
}
}
public void dragStart(DragSourceEvent event) {
list.selectAll();
}
});
}
private void createCopyAction(final Composite parent) {
Menu menu = new Menu(parent.getShell(), SWT.POP_UP);
MenuItem copyAction = new MenuItem(menu, SWT.PUSH);
copyAction.setText("&Copy"); //$NON-NLS-1$
copyAction.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionAdapter#widgetSelected(org
* .eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
clipboard = new Clipboard(parent.getDisplay());
clipboard.setContents(new Object[] { prepareCopyString() },
new Transfer[] { TextTransfer.getInstance() });
super.widgetSelected(e);
}
});
list.setMenu(menu);
}
private String prepareCopyString() {
if (list == null || list.isDisposed()) {
return ""; //$NON-NLS-1$
}
StringBuffer sb = new StringBuffer();
String newLine = System.getProperty("line.separator"); //$NON-NLS-1$
for (int i = 0; i < list.getItemCount(); i++) {
sb.append(list.getItem(i));
sb.append(newLine);
}
return sb.toString();
}
private void populateList(IStatus status) {
if (status == null) {
list.add("No Stack Trace");
return;
}
list.add(status.getCode() + ": " + status.getMessage());
if (status.getException() != null) {
Throwable ex = status.getException();
StackTraceElement[] ste = ex.getStackTrace();
for (int i = 0; i < ste.length; i++) {
list.add(ste[i].toString());
}
if (ex.getCause() != null) {
list.add("Caused by:" + ex.getCause().getMessage());
}
}
}
/**
* @return Returns the list.
*/
public List getList() {
return list;
}
}
}