First cut at pulling in riolog plugin.

Plugin was retrieved from https://github.com/mstoeckl/riolog.git with minimal changes to
make it compile.

Change-Id: I340d77c69fe7598595deeaba8d4cd9414b971399
This commit is contained in:
Paul Malmsten
2014-11-08 12:56:45 -05:00
parent da0cc0c83f
commit 7338471194
11 changed files with 577 additions and 1 deletions

View File

@@ -0,0 +1,61 @@
package netconsole2;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "riolog"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}

View File

@@ -0,0 +1,414 @@
package netconsole2.views;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
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.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
public class RiologView extends ViewPart {
public static Action confAction(String name, String tooltip, String img,
Action e) {
e.setText(name);
e.setToolTipText(tooltip);
e.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(img));
return e;
}
public static byte[] getPacket(DatagramSocket socket, DatagramPacket buf) {
try {
socket.receive(buf);
} catch (IOException e) {
return null;
}
byte[] ret = new byte[buf.getLength()];
System.arraycopy(buf.getData(), 0, ret, 0, ret.length);
return ret;
}
public static DatagramSocket makeRecvSocket() {
DatagramSocket socket = null;
try {
socket = new DatagramSocket(null);
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(6666));
} catch (SocketException e) {
e.printStackTrace();
socket.close();
return null;
}
return socket;
}
public static Thread startDaemonThread(Runnable r, String name) {
Thread t = new Thread(r, name);
t.setDaemon(true);
t.start();
return t;
}
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "netconsole2.views.RiologView";
Text text;
Thread listener;
Thread transferer;
volatile DatagramSocket socket_hook = null;
volatile boolean discard = false;
volatile boolean paused = false;
volatile boolean cleanup = false;
private Action clearAction;
private Action pauseAction;
private Action discardAction;
private Action unpauseAction;
private Action undiscardAction;
private Button discardButton;
private Button pauseButton;
/**
* The constructor.
*/
public RiologView() {
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
GridLayout glayout = new GridLayout();
glayout.numColumns = 1;
parent.setLayout(glayout);
text = new Text(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
| SWT.READ_ONLY);
{
GridData gdata = new GridData();
gdata.grabExcessVerticalSpace = true;
gdata.grabExcessHorizontalSpace = true;
gdata.horizontalAlignment = SWT.FILL;
gdata.verticalAlignment = SWT.FILL;
text.setLayoutData(gdata);
}
Composite row = new Composite(parent, SWT.NONE);
row.setLayout(new FillLayout(SWT.HORIZONTAL));
{
GridData gdata = new GridData();
gdata.grabExcessVerticalSpace = false;
gdata.grabExcessHorizontalSpace = true;
gdata.horizontalAlignment = SWT.FILL;
gdata.verticalAlignment = SWT.CENTER;
row.setLayoutData(gdata);
}
// Create the help context id for the viewer's control
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(parent, "netconsole2.text");
makeActions();
makeButtons(row);
hookContextMenu();
contributeToActionBars();
startListening();
}
public void makeButtons(Composite parent) {
pauseButton = new Button(parent, SWT.TOGGLE);
pauseButton.setText(pauseAction.getText());
pauseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (pauseButton.getSelection()) {
pauseAction.run();
} else {
unpauseAction.run();
}
}
});
discardButton = new Button(parent, SWT.TOGGLE);
discardButton.setText(discardAction.getText());
discardButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (discardButton.getSelection()) {
discardAction.run();
} else {
undiscardAction.run();
}
}
});
Button clearButton = new Button(parent, SWT.PUSH);
clearButton.setText(clearAction.getText());
clearButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
clearAction.run();
}
});
}
@Override
public void dispose() {
stopListening();
super.dispose();
}
private void fillContextMenu(IMenuManager manager) {
manager.add(pauseAction);
manager.add(unpauseAction);
manager.add(new Separator());
manager.add(clearAction);
manager.add(new Separator());
manager.add(discardAction);
manager.add(undiscardAction);
manager.add(new Separator());
manager.add(confAction("Copy", "Copy selected text",
ISharedImages.IMG_TOOL_COPY, new Action() {
@Override
public void run() {
text.copy();
}
}));
manager.add(confAction("Select All", "Select all text", "",
new Action() {
@Override
public void run() {
text.selectAll();
}
}));
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(pauseAction);
manager.add(unpauseAction);
manager.add(new Separator());
manager.add(clearAction);
manager.add(new Separator());
manager.add(discardAction);
manager.add(undiscardAction);
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(pauseAction);
manager.add(unpauseAction);
manager.add(new Separator());
manager.add(clearAction);
manager.add(new Separator());
manager.add(discardAction);
manager.add(undiscardAction);
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
RiologView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(text);
text.setMenu(menu);
}
private void makeActions() {
clearAction = confAction("Clear Log", "Empty the textbox",
ISharedImages.IMG_ETOOL_CLEAR, new Action() {
public void run() {
text.setText("");
}
});
pauseAction = confAction("Pause Display",
"Stop adding packets to the textbox",
ISharedImages.IMG_ELCL_STOP, new Action() {
public void run() {
pauseAction.setEnabled(false);
unpauseAction.setEnabled(true);
pauseButton.setSelection(true);
pauseButton.setText("Show 0 Packets");
paused = true;
}
});
pauseAction.setEnabled(true);
unpauseAction = confAction("Continue Display",
"Continue adding packets to the textbox",
ISharedImages.IMG_TOOL_FORWARD, new Action() {
public void run() {
paused = false;
transferer.interrupt();
pauseAction.setEnabled(true);
unpauseAction.setEnabled(false);
pauseButton.setSelection(false);
pauseButton.setText(pauseAction.getText());
}
});
unpauseAction.setEnabled(false);
discardAction = confAction("Discard Incoming",
"Drop all incoming packets", ISharedImages.IMG_ETOOL_DELETE,
new Action() {
public void run() {
discard = true;
discardAction.setEnabled(false);
undiscardAction.setEnabled(true);
discardButton.setSelection(true);
discardButton.setText(undiscardAction.getText());
}
});
discardAction.setEnabled(true);
undiscardAction = confAction("Accept Incoming",
"Accept all incoming packets", ISharedImages.IMG_OBJ_ADD,
new Action() {
public void run() {
discard = false;
discardAction.setEnabled(true);
undiscardAction.setEnabled(false);
discardButton.setSelection(false);
discardButton.setText(discardAction.getText());
}
});
undiscardAction.setEnabled(false);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
text.setFocus();
}
public static String drainToString(ArrayList<byte[]> arr) {
int netlength = 0;
for (byte[] b : arr) {
netlength += b.length;
}
byte[] sum = new byte[netlength];
int mark = 0;
for (int i=0;i<arr.size();i++) {
byte[] b = arr.get(i);
System.arraycopy(b, 0, sum, mark, b.length);
arr.set(i, null);
mark += b.length;
}
arr.clear();
return new String(sum);
}
void startListening() {
final BlockingQueue<byte[]> queue = new LinkedBlockingQueue<>();
listener = startDaemonThread(new Runnable() {
@Override
public void run() {
DatagramSocket socket = makeRecvSocket();
if (socket == null)
return;
socket_hook = socket;
byte[] buf = new byte[4096];
DatagramPacket datagram = new DatagramPacket(buf, buf.length);
while (!Thread.interrupted()) {
byte[] s = getPacket(socket, datagram);
if (s != null && !discard) {
try {
queue.put(s);
} catch (InterruptedException e) {
socket.close();
return;
}
}
}
socket.close();
}
}, "Riolog-Listener");
transferer = startDaemonThread(new Runnable() {
@Override
public void run() {
final ArrayList<byte[]> temp = new ArrayList<>();
while (!cleanup) {
try {
temp.add(queue.take());
} catch (InterruptedException e) {
if (cleanup) {
return;
}
}
queue.drainTo(temp);
if (!paused) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
if (text.isDisposed())
return;
text.append(drainToString(temp));
}
});
} else {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
if (paused) {
if (temp.size() == 1) {
pauseButton.setText("Show 1 Packet\u2002");
} else {
pauseButton.setText("Show " + String.valueOf(temp.size()) + " Packets");
}
}
}
});
}
}
}
}, "Riolog-Transfer");
}
void stopListening() {
cleanup = true;
if (socket_hook != null) {
socket_hook.close();
}
listener.interrupt();
transferer.interrupt();
}
}