Finish support for initial features

This commit is contained in:
mchr3k 2011-05-08 22:45:18 +01:00
parent 41659d0011
commit f0ace2e0da
27 changed files with 568 additions and 192 deletions

View File

@ -10,7 +10,9 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.debug.ui, org.eclipse.debug.ui,
org.eclipse.jdt.debug.ui;bundle-version="3.5.2", org.eclipse.jdt.debug.ui;bundle-version="3.5.2",
org.eclipse.jdt.launching;bundle-version="3.5.200", org.eclipse.jdt.launching;bundle-version="3.5.200",
org.eclipse.ui.ide;bundle-version="3.6.2" org.eclipse.ui.ide;bundle-version="3.6.2",
org.eclipse.jdt.junit;bundle-version="3.6.1",
org.eclipse.jdt.core;bundle-version="3.6.2"
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ClassPath: lib/miglayout-3.7.3.1-swt.jar, Bundle-ClassPath: lib/miglayout-3.7.3.1-swt.jar,

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

View File

@ -13,18 +13,25 @@
point="org.eclipse.debug.core.launchDelegates"> point="org.eclipse.debug.core.launchDelegates">
<launchDelegate <launchDelegate
delegate="intrace.ecl.ui.launching.ConfigurationDelegate" delegate="intrace.ecl.ui.launching.ConfigurationDelegate"
id="intrace.ecl.intraceLaunchDelegate" id="intrace.ecl.intraceJavaAppLaunchDelegate"
modes="intrace" modes="intrace"
name="Java Application" name="Java Application"
type="org.eclipse.jdt.launching.localJavaApplication"> type="org.eclipse.jdt.launching.localJavaApplication">
</launchDelegate> </launchDelegate>
<launchDelegate
delegate="intrace.ecl.ui.launching.ConfigurationDelegate"
id="intrace.ecl.intraceJunitTestLaunchDelegate"
modes="intrace"
name="JUnit Test"
type="org.eclipse.jdt.junit.launchconfig">
</launchDelegate>
</extension> </extension>
<extension <extension
point="org.eclipse.debug.ui.launchGroups"> point="org.eclipse.debug.ui.launchGroups">
<launchGroup <launchGroup
bannerImage="icons/runcoverage.gif" bannerImage="icons/runintrace.gif"
id="intrace.ecl.inTraceLaunchGroup" id="intrace.ecl.inTraceLaunchGroup"
image="icons/runcoverage.gif" image="icons/runintrace.gif"
label="InTrace" label="InTrace"
mode="intrace"> mode="intrace">
</launchGroup> </launchGroup>
@ -37,9 +44,9 @@
visible="false"> visible="false">
<action <action
class="intrace.ecl.ui.launching.ToolbarAction" class="intrace.ecl.ui.launching.ToolbarAction"
disabledIcon="icons/runcoverage.gif" disabledIcon="icons/runintrace.gif"
hoverIcon="icons/runcoverage.gif" hoverIcon="icons/runintrace.gif"
icon="icons/runcoverage.gif" icon="icons/runintrace.gif"
id="intrace.eclipse.InTraceAction" id="intrace.eclipse.InTraceAction"
label="InTrace" label="InTrace"
style="pulldown" style="pulldown"
@ -59,8 +66,8 @@
<extension <extension
point="org.eclipse.debug.ui.launchShortcuts"> point="org.eclipse.debug.ui.launchShortcuts">
<shortcut <shortcut
class="intrace.ecl.ui.launching.Shortcut" class="intrace.ecl.ui.launching.JavaAppShortcut"
icon="icons/runcoverage.gif" icon="icons/java_launch.gif"
id="intrace.ecl.inTraceLocalJavaShortcut" id="intrace.ecl.inTraceLocalJavaShortcut"
label="Java Application" label="Java Application"
modes="intrace"> modes="intrace">
@ -81,6 +88,27 @@
</enablement> </enablement>
</contextualLaunch> </contextualLaunch>
</shortcut> </shortcut>
<shortcut
class="intrace.ecl.ui.launching.JunitTestShortcut"
icon="icons/junit_launch.gif"
id="intrace.ecl.inTraceJunitTestShortcut"
label="JUnit Test"
modes="intrace">
<contextualLaunch>
<enablement>
<with variable="selection">
<count value="1"/>
<iterate>
<adapt type="org.eclipse.jdt.core.IJavaElement">
<test property="org.eclipse.jdt.core.isInJavaProject"/>
<test property="org.eclipse.jdt.core.hasTypeOnClasspath" value="junit.framework.Test"/>
<test property="org.eclipse.jdt.junit.canLaunchAsJUnit" forcePluginActivation="true"/>
</adapt>
</iterate>
</with>
</enablement>
</contextualLaunch>
</shortcut>
</extension> </extension>
<extension <extension
point="org.eclipse.debug.ui.launchConfigurationTabGroups"> point="org.eclipse.debug.ui.launchConfigurationTabGroups">
@ -89,15 +117,20 @@
id="intrace.ecl.JavaAppTabGroup" id="intrace.ecl.JavaAppTabGroup"
type="org.eclipse.jdt.launching.localJavaApplication"> type="org.eclipse.jdt.launching.localJavaApplication">
</launchConfigurationTabGroup> </launchConfigurationTabGroup>
<launchConfigurationTabGroup
class="intrace.ecl.ui.launching.TabGroup"
id="intrace.ecl.JunitTestTabGroup"
type="org.eclipse.jdt.junit.launchconfig">
</launchConfigurationTabGroup>
</extension> </extension>
<extension <extension
point="org.eclipse.ui.editors"> point="org.eclipse.ui.editors">
<editor <editor
class="intrace.ecl.plugin.ui.output.InTraceEditor" class="intrace.ecl.plugin.ui.output.InTraceEditor"
default="false" default="false"
icon="icons/runcoverage.gif" icon="icons/runintrace.gif"
id="intrace.ecl.plugin.ui.output.inTraceEditor" id="intrace.ecl.plugin.ui.output.inTraceEditor"
name="InTrace Output"> name="InTrace">
</editor> </editor>
</extension> </extension>

View File

@ -13,6 +13,8 @@ import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.part.EditorPart;
import org.intrace.client.gui.helper.InTraceUI; import org.intrace.client.gui.helper.InTraceUI;
import org.intrace.client.gui.helper.Connection.ConnectState;
import org.intrace.client.gui.helper.InTraceUI.IConnectionStateCallback;
public class InTraceEditor extends EditorPart public class InTraceEditor extends EditorPart
{ {
@ -24,29 +26,38 @@ public class InTraceEditor extends EditorPart
} }
@Override @Override
public void createPartControl(Composite parent) public void createPartControl(final Composite parent)
{ {
IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbench workbench = PlatformUI.getWorkbench();
Display display = workbench.getDisplay(); final Display display = workbench.getDisplay();
Shell window = display.getActiveShell(); Shell window = display.getActiveShell();
inTraceUI = new InTraceUI(window, parent); inTraceUI = new InTraceUI(window, parent, false);
} inTraceUI.setConnCallback(new IConnectionStateCallback()
{
@Override @Override
public void init(IEditorSite site, public void setConnectionState(final ConnectState state)
IEditorInput input) {
throws PartInitException if (!parent.isDisposed())
{ {
setSite(site); display.syncExec(new Runnable()
setInput(input); {
final EditorInput intraceInput = (EditorInput)input; @Override
public void run()
{
setPartName("InTrace: " + state.str);
}
});
}
}
});
final EditorInput intraceInput = (EditorInput)getEditorInput();
new Thread(new Runnable() new Thread(new Runnable()
{ {
@Override @Override
public void run() public void run()
{ {
try try
{ {
Socket connection = intraceInput.callback.getClientConnection(); Socket connection = intraceInput.callback.getClientConnection();
inTraceUI.setFixedLocalConnection(connection); inTraceUI.setFixedLocalConnection(connection);
} }
@ -55,7 +66,16 @@ public class InTraceEditor extends EditorPart
e.printStackTrace(); e.printStackTrace();
} }
} }
}).start(); }).start();
}
@Override
public void init(IEditorSite site,
IEditorInput input)
throws PartInitException
{
setSite(site);
setInput(input);
} }
@Override @Override

View File

@ -78,6 +78,7 @@ public class ConfigurationDelegate extends AbstractJavaLaunchConfigurationDelega
vmArgs += Activator.getDefault().agentArg; vmArgs += Activator.getDefault().agentArg;
vmArgs += "=[callbackport-"; vmArgs += "=[callbackport-";
vmArgs += Integer.toString(callbackServer.getLocalPort()); vmArgs += Integer.toString(callbackServer.getLocalPort());
vmArgs += "[startwait";
} }
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs); wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs);

View File

@ -0,0 +1,9 @@
package intrace.ecl.ui.launching;
public class JavaAppShortcut extends Shortcut
{
public JavaAppShortcut()
{
super("org.eclipse.jdt.debug.ui.localJavaShortcut");
}
}

View File

@ -0,0 +1,9 @@
package intrace.ecl.ui.launching;
public class JunitTestShortcut extends Shortcut
{
public JunitTestShortcut()
{
super("org.eclipse.jdt.junit.junitShortcut");
}
}

View File

@ -12,9 +12,15 @@ import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorPart;
public class Shortcut implements ILaunchShortcut public abstract class Shortcut implements ILaunchShortcut
{ {
private final String delegateId = "org.eclipse.jdt.debug.ui.localJavaShortcut"; private final String delegateId;
public Shortcut(String xiDelegateId)
{
delegateId = xiDelegateId;
}
private ILaunchShortcut delegate; private ILaunchShortcut delegate;
private ILaunchShortcut getDelegate() private ILaunchShortcut getDelegate()

View File

@ -84,6 +84,7 @@ public class Agent
waitForServerPort(); waitForServerPort();
args.setActualServerPort(serverPort); args.setActualServerPort(serverPort);
// Return updated settings
try try
{ {
Map<String, String> settingsMap = new HashMap<String, String>(); Map<String, String> settingsMap = new HashMap<String, String>();
@ -95,6 +96,20 @@ public class Agent
{ {
e.printStackTrace(); e.printStackTrace();
} }
// Wait for startup
if (args.isWaitStart())
{
try
{
System.out.println("## Waiting to continue");
AgentServer.waitForStartSignal();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
} }
private static int serverPort = -1; private static int serverPort = -1;

View File

@ -13,14 +13,21 @@ import org.intrace.shared.AgentConfigConstants;
*/ */
public class AgentSettings public class AgentSettings
{ {
private Pattern classRegex = Pattern.compile(".*"); private Pattern classRegex = Pattern.compile("^$");
private Pattern excludeClassRegex = Pattern.compile("^$"); private Pattern excludeClassRegex = Pattern.compile("^$");
private boolean instruEnabled = false; private boolean instruEnabled = true;
private boolean saveTracedClassfiles = false; private boolean saveTracedClassfiles = false;
private boolean verboseMode = false; private boolean verboseMode = false;
private int serverPort = 9123; private int serverPort = 9123;
private int callbackPort = -1; private int callbackPort = -1;
private int actualServerPort = -1; private int actualServerPort = -1;
private boolean waitStart = false;
public boolean isWaitStart()
{
return waitStart;
}
public int getActualServerPort() public int getActualServerPort()
{ {
@ -54,6 +61,7 @@ public class AgentSettings
instruEnabled = oldInstance.isInstrumentationEnabled(); instruEnabled = oldInstance.isInstrumentationEnabled();
saveTracedClassfiles = oldInstance.saveTracedClassfiles(); saveTracedClassfiles = oldInstance.saveTracedClassfiles();
verboseMode = oldInstance.isVerboseMode(); verboseMode = oldInstance.isVerboseMode();
waitStart = oldInstance.isWaitStart();
} }
public void parseArgs(String args) public void parseArgs(String args)
@ -77,9 +85,9 @@ public class AgentSettings
{ {
verboseMode = false; verboseMode = false;
} }
else if (arg.toLowerCase().startsWith(AgentConfigConstants.SERVER_PORT)) else if (arg.toLowerCase().startsWith(AgentConfigConstants.OPT_SERVER_PORT))
{ {
String serverPortStr = arg.replace(AgentConfigConstants.SERVER_PORT, ""); String serverPortStr = arg.replace(AgentConfigConstants.OPT_SERVER_PORT, "");
serverPort = Integer.parseInt(serverPortStr); serverPort = Integer.parseInt(serverPortStr);
} }
else if (arg.toLowerCase().startsWith(AgentConfigConstants.CALLBACK_PORT)) else if (arg.toLowerCase().startsWith(AgentConfigConstants.CALLBACK_PORT))
@ -109,6 +117,15 @@ public class AgentSettings
{ {
saveTracedClassfiles = false; saveTracedClassfiles = false;
} }
else if (arg.toLowerCase()
.equals(AgentConfigConstants.START_WAIT))
{
waitStart = true;
}
else if (arg.toLowerCase().equals(AgentConfigConstants.START_ACTIVATE))
{
waitStart = false;
}
else if (arg.startsWith(AgentConfigConstants.CLASS_REGEX)) else if (arg.startsWith(AgentConfigConstants.CLASS_REGEX))
{ {
String classRegexStr = arg.replace(AgentConfigConstants.CLASS_REGEX, ""); String classRegexStr = arg.replace(AgentConfigConstants.CLASS_REGEX, "");
@ -172,7 +189,8 @@ public class AgentSettings
Boolean.toString(verboseMode)); Boolean.toString(verboseMode));
settingsMap.put(AgentConfigConstants.SAVE_TRACED_CLASSFILES, settingsMap.put(AgentConfigConstants.SAVE_TRACED_CLASSFILES,
Boolean.toString(saveTracedClassfiles)); Boolean.toString(saveTracedClassfiles));
settingsMap.put(AgentConfigConstants.ACTUAL_SERVER_PORT, Integer.toString(actualServerPort)); settingsMap.put(AgentConfigConstants.SERVER_PORT, Integer.toString(actualServerPort));
settingsMap.put(AgentConfigConstants.START_WAIT, Boolean.toString(waitStart));
return settingsMap; return settingsMap;
} }
} }

View File

@ -134,12 +134,15 @@ public class ClassTransformer implements ClassFileTransformer
ComparableClassName compklass = new ComparableClassName(className, ComparableClassName compklass = new ComparableClassName(className,
klassloader); klassloader);
// Record all class names which get this far
allClasses.add(compklass);
// Don't modify anything if tracing is disabled // Don't modify anything if tracing is disabled
if (!settings.isInstrumentationEnabled()) if (!settings.isInstrumentationEnabled())
{ {
return false; return false;
} }
// Don't sensitive classes // Don't sensitive classes
if (isSensitiveClass(className)) if (isSensitiveClass(className))
{ {
@ -159,10 +162,7 @@ public class ClassTransformer implements ClassFileTransformer
} }
return false; return false;
} }
// Record all class names which get this far
allClasses.add(compklass);
// Don't modify classes which match the exclude regex // Don't modify classes which match the exclude regex
if ((settings.getExcludeClassRegex() == null) if ((settings.getExcludeClassRegex() == null)
|| settings.getExcludeClassRegex().matcher(className).matches()) || settings.getExcludeClassRegex().matcher(className).matches())
@ -350,9 +350,9 @@ public class ClassTransformer implements ClassFileTransformer
public Map<String, String> getSettings() public Map<String, String> getSettings()
{ {
Map<String, String> settingsMap = settings.getSettingsMap(); Map<String, String> settingsMap = settings.getSettingsMap();
settingsMap.put(AgentConfigConstants.NUM_TOTAL_CLASSES, settingsMap.put(AgentConfigConstants.STCLS,
Integer.toString(allClasses.size())); Integer.toString(allClasses.size()));
settingsMap.put(AgentConfigConstants.NUM_INSTR_CLASSES, settingsMap.put(AgentConfigConstants.STINST,
Integer.toString(modifiedClasses.size())); Integer.toString(modifiedClasses.size()));
return settingsMap; return settingsMap;
} }
@ -559,11 +559,11 @@ public class ClassTransformer implements ClassFileTransformer
private void broadcastStatus(int count, int total) private void broadcastStatus(int count, int total)
{ {
Map<String, String> progressMap = new HashMap<String, String>(); Map<String, String> progressMap = new HashMap<String, String>();
progressMap.put(AgentConfigConstants.NUM_STATUS_ID, progressMap.put(AgentConfigConstants.STID,
AgentConfigConstants.NUM_STATUS_ID); AgentConfigConstants.STID);
progressMap.put(AgentConfigConstants.NUM_INSTR_CLASSES, progressMap.put(AgentConfigConstants.STINST,
Integer.toString(count)); Integer.toString(count));
progressMap.put(AgentConfigConstants.NUM_TOTAL_CLASSES, progressMap.put(AgentConfigConstants.STCLS,
Integer.toString(total)); Integer.toString(total));
try try
{ {

View File

@ -88,7 +88,6 @@ public class AgentClientConnection implements Runnable
{ {
while (true) while (true)
{ {
String message = receiveMessage(); String message = receiveMessage();
if (message.equals("getsettings")) if (message.equals("getsettings"))
{ {
@ -104,6 +103,11 @@ public class AgentClientConnection implements Runnable
commandSet.addAll(TraceConfigConstants.COMMANDS); commandSet.addAll(TraceConfigConstants.COMMANDS);
sendMessage(commandSet); sendMessage(commandSet);
} }
else if (message.equalsIgnoreCase(AgentConfigConstants.START_ACTIVATE))
{
transformer.getResponse(this, message);
AgentServer.setStartSignalled();
}
else else
{ {
List<String> responses = transformer.getResponse(this, message); List<String> responses = transformer.getResponse(this, message);
@ -151,7 +155,7 @@ public class AgentClientConnection implements Runnable
try try
{ {
String lRet = (String) objIn.readObject(); String lRet = (String) objIn.readObject();
System.out.println("Received Message: " + lRet); System.out.println("## Received Message: " + lRet);
return lRet; return lRet;
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
@ -168,10 +172,13 @@ public class AgentClientConnection implements Runnable
*/ */
public void sendMessage(Object xiObject) throws IOException public void sendMessage(Object xiObject) throws IOException
{ {
OutputStream out = connectedClient.getOutputStream(); synchronized (connectedClient)
ObjectOutputStream objOut = new ObjectOutputStream(out); {
objOut.writeObject(xiObject); OutputStream out = connectedClient.getOutputStream();
objOut.flush(); ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(xiObject);
objOut.flush();
}
} }
/** /**

View File

@ -23,7 +23,24 @@ public class AgentServer implements Runnable
// Target server port // Target server port
private final int serverPort; private final int serverPort;
// Start signalled
private static boolean startSignaled = false;
public static synchronized void setStartSignalled()
{
startSignaled = true;
AgentServer.class.notifyAll();
}
public static synchronized void waitForStartSignal() throws InterruptedException
{
if (!startSignaled)
{
AgentServer.class.wait();
}
}
/** /**
* cTor * cTor
* *

View File

@ -3,6 +3,8 @@ package org.intrace.client.gui;
import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.intrace.client.gui.helper.InTraceUI; import org.intrace.client.gui.helper.InTraceUI;
import org.intrace.client.gui.helper.Connection.ConnectState;
import org.intrace.client.gui.helper.InTraceUI.IConnectionStateCallback;
public class InTraceStandaloneUI public class InTraceStandaloneUI
{ {
@ -12,13 +14,35 @@ public class InTraceStandaloneUI
public static void main(String[] args) public static void main(String[] args)
{ {
// Prepare window // Prepare window
Shell window = new Shell(); final Shell window = new Shell();
window.setText("InTrace UI");
window.setSize(new Point(800, 800)); window.setSize(new Point(800, 800));
window.setMinimumSize(new Point(800, 480)); window.setMinimumSize(new Point(800, 480));
// Fill in UI // Fill in UI
new InTraceUI(window, window).open(); InTraceUI ui = new InTraceUI(window, window, true);
// Register title callback
ui.setConnCallback(new IConnectionStateCallback()
{
@Override
public void setConnectionState(final ConnectState state)
{
if (!window.isDisposed())
{
window.getDisplay().syncExec(new Runnable()
{
@Override
public void run()
{
window.setText("InTrace UI: " + state.str);
}
});
}
}
});
// Open UI
ui.open();
} }
} }

View File

@ -2,10 +2,6 @@ package org.intrace.client.gui.helper;
public class ClientStrings public class ClientStrings
{ {
public static final String ENABLE_INSTR = "Add Instrumentation";
public static final String ENABLING_INSTR = "Adding Instrumenting...";
public static final String DISABLING_INSTR = "Removing Instrumentation...";
public static final String DISABLE_INSTR = "Remove Instrumentation";
public static final String SET_CLASSREGEX = "Select Classes ..."; public static final String SET_CLASSREGEX = "Select Classes ...";
public static final String ENABLE_ALLOWJARS = "Instru JARs"; public static final String ENABLE_ALLOWJARS = "Instru JARs";
public static final String ENABLE_SAVECLASSES = "Save Instrumented Classes"; public static final String ENABLE_SAVECLASSES = "Save Instrumented Classes";

View File

@ -12,7 +12,15 @@ public class Connection
// State // State
public enum ConnectState public enum ConnectState
{ {
DISCONNECTED_ERR, DISCONNECTED, CONNECTING, CONNECTED DISCONNECTED_ERR("Disconnected"),
DISCONNECTED("Disconnected"),
CONNECTING("Connecting"),
CONNECTED("Connected");
public final String str;
private ConnectState(String xiStr)
{
str = xiStr;
}
} }
public static interface ISocketCallback public static interface ISocketCallback

View File

@ -76,7 +76,7 @@ public class ControlConnectionThread implements Runnable
{ {
listener.setProgress(map); listener.setProgress(map);
} }
else if (map.containsKey(AgentConfigConstants.NUM_STATUS_ID)) else if (map.containsKey(AgentConfigConstants.STID))
{ {
listener.setStatus(map); listener.setStatus(map);
} }
@ -97,7 +97,11 @@ public class ControlConnectionThread implements Runnable
} }
catch (Exception ex) catch (Exception ex)
{ {
ex.printStackTrace(); if (!ex.getMessage().contains("socket closed") &&
!ex.getMessage().contains("onnection reset"))
{
ex.printStackTrace();
}
listener.disconnect(); listener.disconnect();
} }
} }

View File

@ -14,6 +14,8 @@ import java.util.regex.Pattern;
import net.miginfocom.swt.MigLayout; import net.miginfocom.swt.MigLayout;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MenuDetectEvent; import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.events.MenuDetectListener;
@ -22,6 +24,7 @@ import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
@ -29,6 +32,7 @@ import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MenuItem;
@ -49,6 +53,11 @@ import org.intrace.shared.AgentConfigConstants;
public class InTraceUI implements ISocketCallback, IControlConnectionListener public class InTraceUI implements ISocketCallback, IControlConnectionListener
{ {
public static interface IConnectionStateCallback
{
public void setConnectionState(ConnectState state);
}
public static String NEWLINE = System.getProperty("line.separator"); public static String NEWLINE = System.getProperty("line.separator");
public void open() public void open()
@ -65,27 +74,69 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
display.dispose(); display.dispose();
} }
private Shell sWindow = null; private final Shell sWindow;
final TabFolder outputTabs;
private TabFolder buttonTabs;
private final Composite sRoot; private final Composite sRoot;
private final TabFolder outputTabs;
private final TabFolder buttonTabs;
private final CTabFolder buttonCTabs;
private final CTabFolder outputCTabs;
private final boolean standalone;
private IConnectionStateCallback connCallback = null;
private MigLayout rootLayout;
public InTraceUI(Shell xiWindow, Composite xiRoot) public void setConnCallback(IConnectionStateCallback connCallback)
{
this.connCallback = connCallback;
if (connCallback != null)
{
connCallback.setConnectionState(connectionState);
}
}
public InTraceUI(Shell xiWindow, Composite xiRoot, boolean xiStandalone)
{ {
sWindow = xiWindow; sWindow = xiWindow;
sRoot = xiRoot; sRoot = xiRoot;
standalone = xiStandalone;
MigLayout rootLayout = new MigLayout("fill", "", "[][grow]"); rootLayout = new MigLayout("fill", "[]", "[][][grow]");
xiRoot.setLayout(rootLayout); xiRoot.setLayout(rootLayout);
buttonTabs = new TabFolder(xiRoot, SWT.NONE); if (xiStandalone)
buttonTabs.setLayoutData("grow,wrap,wmin 0"); {
buttonCTabs = null;
outputTabs = new TabFolder(xiRoot, SWT.NONE); buttonTabs = new TabFolder(xiRoot, SWT.NONE);
outputTabs.setLayoutData("grow,wmin 0,hmin 0"); buttonTabs.setLayoutData("grow,wrap,wmin 0");
fillButtonTabs(buttonTabs);
fillButtonTabs(buttonTabs); }
fillOutputTabs(outputTabs); else
{
buttonTabs = null;
buttonCTabs = new CTabFolder(xiRoot, SWT.TOP | SWT.BORDER);
buttonCTabs.setSimple(false);
buttonCTabs.setLayoutData("grow,wrap,wmin 0");
fillButtonCTabs(buttonCTabs);
buttonCTabs.setSelection(0);
}
if (xiStandalone)
{
outputCTabs = null;
outputTabs = new TabFolder(xiRoot, SWT.NONE);
outputTabs.setLayoutData("grow,wmin 0,hmin 0,cell 0 2");
fillOutputTabs(outputTabs);
}
else
{
outputTabs = null;
outputCTabs = new CTabFolder(xiRoot, SWT.TOP | SWT.BORDER);
outputCTabs.setSimple(false);
outputCTabs.setLayoutData("grow,wmin 0,hmin 0,cell 0 2");
fillOutputCTabs(outputCTabs);
outputCTabs.setSelection(0);
}
updateUIStateSameThread(); updateUIStateSameThread();
@ -115,9 +166,20 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
@Override @Override
public void run() public void run()
{ {
if (standalone)
{
buttonTabs.getItem(0).dispose();
}
else
{
buttonCTabs.getItem(0).dispose();
}
connTab.addressInput.setText("localhost"); connTab.addressInput.setText("localhost");
connTab.portInput.setText("detecting..."); connTab.portInput.setText("detecting...");
buttonTabs.setSelection(instruTab.tabItem); textOutputTab.filterThread.addSystemTraceLine("Instructions");
textOutputTab.filterThread.addSystemTraceLine(" - Select Classes you want to Trace");
textOutputTab.filterThread.addSystemTraceLine("Full help available on the Help tab");
textOutputTab.filterThread.addSystemTraceLine("");
} }
}); });
} }
@ -128,24 +190,99 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
private InstruTab instruTab; private InstruTab instruTab;
private TraceTab traceTab; private TraceTab traceTab;
private ExtrasTab extraTab; private ExtrasTab extraTab;
private Composite startPanel;
private void fillButtonTabs(TabFolder tabFolder) private void fillButtonTabs(TabFolder tabFolder)
{ {
TabItem connTabItem = new TabItem(tabFolder, SWT.NONE); TabItem connTabItem = new TabItem(tabFolder, SWT.NONE);
connTabItem.setText("Connection"); connTabItem.setText("Connection");
connTab = new ConnectionTab(tabFolder, connTabItem); connTab = new ConnectionTab(tabFolder);
connTabItem.setControl(connTab.composite);
TabItem instrTabItem = new TabItem(tabFolder, SWT.NONE); TabItem instrTabItem = new TabItem(tabFolder, SWT.NONE);
instrTabItem.setText("Instrumentation"); instrTabItem.setText("Instrumentation");
instruTab = new InstruTab(tabFolder, instrTabItem); instruTab = new InstruTab(tabFolder);
instrTabItem.setControl(instruTab.composite);
TabItem traceTabItem = new TabItem(tabFolder, SWT.NONE); TabItem traceTabItem = new TabItem(tabFolder, SWT.NONE);
traceTabItem.setText("Trace"); traceTabItem.setText("Trace");
traceTab = new TraceTab(tabFolder, traceTabItem); traceTab = new TraceTab(tabFolder);
traceTabItem.setControl(traceTab.composite);
TabItem extraTabItem = new TabItem(tabFolder, SWT.NONE); TabItem extraTabItem = new TabItem(tabFolder, SWT.NONE);
extraTabItem.setText("Advanced"); extraTabItem.setText("Advanced");
extraTab = new ExtrasTab(tabFolder, extraTabItem); extraTab = new ExtrasTab(tabFolder);
extraTabItem.setControl(extraTab.composite);
}
private void fillButtonCTabs(CTabFolder tabFolder)
{
CTabItem connTabItem = new CTabItem(tabFolder, SWT.NONE);
connTabItem.setText("Connection");
connTab = new ConnectionTab(tabFolder);
connTabItem.setControl(connTab.composite);
CTabItem instrTabItem = new CTabItem(tabFolder, SWT.NONE);
instrTabItem.setText("Instrumentation");
instruTab = new InstruTab(tabFolder);
instrTabItem.setControl(instruTab.composite);
CTabItem traceTabItem = new CTabItem(tabFolder, SWT.NONE);
traceTabItem.setText("Trace");
traceTab = new TraceTab(tabFolder);
traceTabItem.setControl(traceTab.composite);
CTabItem extraTabItem = new CTabItem(tabFolder, SWT.NONE);
extraTabItem.setText("Advanced");
extraTab = new ExtrasTab(tabFolder);
extraTabItem.setControl(extraTab.composite);
}
private boolean waitStartUIShown = false;
private void addWaitStartUI()
{
if (!waitStartUIShown)
{
startPanel = new Composite(sRoot, SWT.NONE);
startPanel.setLayoutData("grow,wrap,cell 0 1");
MigLayout startLayout = new MigLayout("fillx", "[align center]", "[]");
startPanel.setLayout(startLayout);
Label startLabel = new Label(startPanel, SWT.NONE);
startLabel.setText("Program has been paused.");
startLabel.setLayoutData("split");
final Button startButton = new Button(startPanel, SWT.PUSH);
startButton.setText("Start Program");
startButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent arg0)
{
controlThread.sendMessage(AgentConfigConstants.START_ACTIVATE);
controlThread.sendMessage("getsettings");
startButton.setEnabled(false);
}
});
sRoot.layout();
waitStartUIShown = true;
}
}
private void removeWaitStartUI()
{
if (waitStartUIShown)
{
startPanel.dispose();
sRoot.layout();
waitStartUIShown = false;
}
} }
private class ConnectionTab private class ConnectionTab
@ -153,15 +290,15 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
final Button connectButton; final Button connectButton;
final Text addressInput; final Text addressInput;
final Text portInput; final Text portInput;
private Label statusLabel; final Label statusLabel;
final Composite composite;
private ConnectionTab(TabFolder tabFolder, TabItem connTab) private ConnectionTab(Composite parent)
{ {
MigLayout windowLayout = new MigLayout("fill", "[380][grow]"); MigLayout windowLayout = new MigLayout("fill", "[380][grow]");
Composite composite = new Composite(tabFolder, SWT.NONE); composite = new Composite(parent, SWT.NONE);
composite.setLayout(windowLayout); composite.setLayout(windowLayout);
connTab.setControl(composite);
Group connectionGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); Group connectionGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
MigLayout connGroupLayout = new MigLayout("fill", "[40][200][grow]"); MigLayout connGroupLayout = new MigLayout("fill", "[40][200][grow]");
@ -217,7 +354,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
if ((connectionState == ConnectState.DISCONNECTED) if ((connectionState == ConnectState.DISCONNECTED)
|| (connectionState == ConnectState.DISCONNECTED_ERR)) || (connectionState == ConnectState.DISCONNECTED_ERR))
{ {
connectionState = ConnectState.CONNECTING; setConnectionState(ConnectState.CONNECTING);
updateUIStateSameThread(); updateUIStateSameThread();
Connection.connectToAgent(thisWindow, sWindow, addressInput Connection.connectToAgent(thisWindow, sWindow, addressInput
.getText(), portInput.getText()); .getText(), portInput.getText());
@ -236,24 +373,21 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
private class InstruTab private class InstruTab
{ {
final Button togInstru;
final Button classRegex; final Button classRegex;
final Button listClasses; final Button listClasses;
final Label instrStatusLabel; final Label instrStatusLabel;
private final TabItem tabItem; final Composite composite;
private InstruTab(TabFolder tabFolder, TabItem instrTab) private InstruTab(Composite parent)
{ {
this.tabItem = instrTab;
MigLayout windowLayout = new MigLayout("fill", "[][300][grow]", "[]"); MigLayout windowLayout = new MigLayout("fill", "[][300][grow]", "[]");
Composite composite = new Composite(tabFolder, SWT.NONE); composite = new Composite(parent, SWT.NONE);
composite.setLayout(windowLayout); composite.setLayout(windowLayout);
instrTab.setControl(composite);
composite.setLayoutData("hmin 0"); composite.setLayoutData("hmin 0");
Group mainControlGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); Group mainControlGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
MigLayout mainControlGroupLayout = new MigLayout("filly", "[150][150]"); MigLayout mainControlGroupLayout = new MigLayout("filly", "[150]");
mainControlGroup.setLayout(mainControlGroupLayout); mainControlGroup.setLayout(mainControlGroupLayout);
mainControlGroup.setLayoutData("hmin 0, grow"); mainControlGroup.setLayoutData("hmin 0, grow");
mainControlGroup.setText("Instrumentation Settings"); mainControlGroup.setText("Instrumentation Settings");
@ -262,11 +396,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
classRegex.setText(ClientStrings.SET_CLASSREGEX); classRegex.setText(ClientStrings.SET_CLASSREGEX);
classRegex.setLayoutData("grow"); classRegex.setLayoutData("grow");
togInstru = new Button(mainControlGroup, SWT.PUSH);
togInstru.setText(ClientStrings.ENABLE_INSTR);
togInstru.setAlignment(SWT.CENTER);
togInstru.setLayoutData("grow");
Group statusGroup = new Group(composite, SWT.SHADOW_IN); Group statusGroup = new Group(composite, SWT.SHADOW_IN);
MigLayout statusGroupLayout = new MigLayout("fillx", "[][]"); MigLayout statusGroupLayout = new MigLayout("fillx", "[][]");
statusGroup.setLayout(statusGroupLayout); statusGroup.setLayout(statusGroupLayout);
@ -283,27 +412,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
listClasses.setAlignment(SWT.CENTER); listClasses.setAlignment(SWT.CENTER);
listClasses.setLayoutData("gapy 5px"); listClasses.setLayoutData("gapy 5px");
togInstru
.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent arg0)
{
if (!settingsData.instrEnabled)
{
togInstru.setText(ClientStrings.ENABLING_INSTR);
}
else
{
togInstru.setText(ClientStrings.DISABLE_INSTR);
}
togInstru.setEnabled(false);
toggleSetting(settingsData.instrEnabled, "[instru-true",
"[instru-false");
settingsData.instrEnabled = !settingsData.instrEnabled;
}
});
final String helpText = "Enter pattern in the form " final String helpText = "Enter pattern in the form "
+ "\"mypack.mysubpack.MyClass\" or using wildcards " + "\"mypack.mysubpack.MyClass\" or using wildcards "
+ "\"mypack.*.MyClass\" or \"*MyClass\" etc"; + "\"mypack.*.MyClass\" or \"*MyClass\" etc";
@ -366,17 +474,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
{ {
instrStatusLabel.setText("Progress: " + progressClasses + "/" instrStatusLabel.setText("Progress: " + progressClasses + "/"
+ totalClasses); + totalClasses);
if (done)
{
if (settingsData.instrEnabled)
{
togInstru.setText(ClientStrings.DISABLE_INSTR);
} else
{
togInstru.setText(ClientStrings.ENABLE_INSTR);
}
togInstru.setEnabled(true);
}
} }
} }
@ -388,14 +485,14 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
final Button stdOutOutput; final Button stdOutOutput;
final Button fileOutput; final Button fileOutput;
final Composite composite;
private TraceTab(TabFolder tabFolder, TabItem traceTab) private TraceTab(Composite parent)
{ {
MigLayout windowLayout = new MigLayout("fill", "[][][grow]"); MigLayout windowLayout = new MigLayout("fill", "[][][grow]");
Composite composite = new Composite(tabFolder, SWT.NONE); composite = new Composite(parent, SWT.NONE);
composite.setLayout(windowLayout); composite.setLayout(windowLayout);
traceTab.setControl(composite);
Group traceTypesGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); Group traceTypesGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);
MigLayout traceTypesGroupLayout = new MigLayout("fill", "[150]"); MigLayout traceTypesGroupLayout = new MigLayout("fill", "[150]");
@ -492,17 +589,17 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
private class ExtrasTab private class ExtrasTab
{ {
private Button togSaveClasses; final Button togSaveClasses;
private Button togVerbose; final Button togVerbose;
private Button printSettings; final Button printSettings;
final Composite composite;
private ExtrasTab(TabFolder tabFolder, TabItem traceTab) private ExtrasTab(Composite parent)
{ {
MigLayout windowLayout = new MigLayout("fill", "[200][grow]"); MigLayout windowLayout = new MigLayout("fill", "[200][grow]");
Composite composite = new Composite(tabFolder, SWT.NONE); composite = new Composite(parent, SWT.NONE);
composite.setLayout(windowLayout); composite.setLayout(windowLayout);
traceTab.setControl(composite);
togSaveClasses = new Button(composite, SWT.CHECK); togSaveClasses = new Button(composite, SWT.CHECK);
togSaveClasses.setText(ClientStrings.ENABLE_SAVECLASSES); togSaveClasses.setText(ClientStrings.ENABLE_SAVECLASSES);
@ -555,12 +652,32 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
} }
TextOutputTab textOutputTab; TextOutputTab textOutputTab;
HelpOutputTab helpOutputTab;
private void fillOutputTabs(TabFolder tabFolder) private void fillOutputTabs(TabFolder tabFolder)
{ {
TabItem textOutputTabItem = new TabItem(tabFolder, SWT.NONE); TabItem textOutputTabItem = new TabItem(tabFolder, SWT.NONE);
textOutputTabItem.setText("Output"); textOutputTabItem.setText("Output");
textOutputTab = new TextOutputTab(tabFolder, textOutputTabItem); textOutputTab = new TextOutputTab(tabFolder);
textOutputTabItem.setControl(textOutputTab.composite);
TabItem helpOutputTabItem = new TabItem(tabFolder, SWT.NONE);
helpOutputTabItem.setText("Help");
helpOutputTab = new HelpOutputTab(tabFolder);
helpOutputTabItem.setControl(helpOutputTab.composite);
}
private void fillOutputCTabs(CTabFolder tabFolder)
{
CTabItem textOutputTabItem = new CTabItem(tabFolder, SWT.NONE);
textOutputTabItem.setText("Output");
textOutputTab = new TextOutputTab(tabFolder);
textOutputTabItem.setControl(textOutputTab.composite);
CTabItem helpOutputTabItem = new CTabItem(tabFolder, SWT.NONE);
helpOutputTabItem.setText("Help");
helpOutputTab = new HelpOutputTab(tabFolder);
helpOutputTabItem.setControl(helpOutputTab.composite);
} }
private class TextOutputTab private class TextOutputTab
@ -576,15 +693,15 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
final Button downButton; final Button downButton;
final Button upButton; final Button upButton;
final Text findInput; final Text findInput;
final Composite composite;
private TextOutputTab(TabFolder tabFolder, TabItem textOutputTab) private TextOutputTab(Composite parent)
{ {
MigLayout windowLayout = new MigLayout("fill,wmin 0,hmin 0", MigLayout windowLayout = new MigLayout("fill,wmin 0,hmin 0",
"[100][100][100][150][100][grow]", "[20][20][grow][]"); "[100][100][100][150][100][grow]", "[20][20][grow][]");
final Composite composite = new Composite(tabFolder, SWT.NONE); composite = new Composite(parent, SWT.NONE);
composite.setLayout(windowLayout); composite.setLayout(windowLayout);
textOutputTab.setControl(composite);
Button saveText = new Button(composite, SWT.PUSH); Button saveText = new Button(composite, SWT.PUSH);
saveText.setText(ClientStrings.SAVE_TEXT); saveText.setText(ClientStrings.SAVE_TEXT);
@ -890,7 +1007,8 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
} }
}); });
filterThread = new TraceFilterThread(new TraceTextHandler() filterThread = new TraceFilterThread(standalone,
new TraceTextHandler()
{ {
// Re-usable class to avoid object allocations // Re-usable class to avoid object allocations
class SetTextRunnable implements Runnable class SetTextRunnable implements Runnable
@ -956,26 +1074,15 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
setOutputStatus(displayed, total); setOutputStatus(displayed, total);
} }
}); });
filterThread.addSystemTraceLine("Help is available online: https://github.com/mchr3k/org.intrace/wiki");
filterThread.addSystemTraceLine("Here is some example trace:"); if (standalone)
filterThread.addTraceLine("[10/05/27 14:14:30]:[1]:example.ExampleClass:multiplyMethod: {:100"); {
filterThread.addTraceLine("[10/05/27 14:14:30]:[1]:example.ExampleClass:multiplyMethod: Arg: 2"); filterThread.addSystemTraceLine("Instructions");
filterThread.addTraceLine("[10/05/27 14:14:30]:[1]:example.ExampleClass:multiplyMethod: Arg: 4"); filterThread.addSystemTraceLine("(1) Connect to Agent");
filterThread.addTraceLine("[10/05/27 14:14:30]:[1]:example.ExampleClass:multiplyMethod: /:101"); filterThread.addSystemTraceLine("(2) Select Classes you want to Trace");
filterThread.addTraceLine("[10/05/27 14:14:30]:[1]:example.ExampleClass:multiplyMethod: Return: 8"); filterThread.addSystemTraceLine("Full help available on the Help tab");
filterThread.addTraceLine("[10/05/27 14:14:30]:[1]:example.ExampleClass:multiplyMethod: }:105"); filterThread.addSystemTraceLine("");
filterThread.addSystemTraceLine(""); }
filterThread.addSystemTraceLine("This means the following:");
filterThread.addSystemTraceLine("[10/05/27 14:14:30] is a date/timestamp - the date is in the format yy/mm/dd");
filterThread.addSystemTraceLine("[1] - the thread ID");
filterThread.addSystemTraceLine("example.ExampleClass:multiplyMethod - the Class and Method being traced");
filterThread.addSystemTraceLine("{:100 - The method was entered on source line 100");
filterThread.addSystemTraceLine("Arg: 2 - The first argument had value 2");
filterThread.addSystemTraceLine("Arg: 2 - The second argument had value 4");
filterThread.addSystemTraceLine("/:101 - An optional block of code was executed starting at source line 101 (e.g. an if statement)");
filterThread.addSystemTraceLine("Return: 8 - The method returned value 8");
filterThread.addSystemTraceLine("}:105 - The method returned on source line 105");
filterThread.addSystemTraceLine("");
} }
private String getDisplayPatternFromText(String text) private String getDisplayPatternFromText(String text)
@ -1173,12 +1280,79 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
}); });
} }
} }
private class HelpOutputTab
{
final StyledText textOutput;
final Composite composite;
final Link helpLink;
private HelpOutputTab(Composite parent)
{
MigLayout windowLayout = new MigLayout("fill,wmin 0,hmin 0",
"[grow]", "[20][grow]");
composite = new Composite(parent, SWT.NONE);
composite.setLayout(windowLayout);
helpLink = new Link(composite, SWT.NONE);
helpLink.setLayoutData("growx,wrap");
helpLink.setText("<A HREF=\"https://github.com/mchr3k/org.intrace/wiki\">Online Help</A>");
textOutput = new StyledText(composite, SWT.MULTI | SWT.V_SCROLL
| SWT.H_SCROLL | SWT.BORDER);
textOutput.setEditable(false);
textOutput.setLayoutData("spanx,grow,wmin 0,hmin 0");
textOutput.setBackground(Display.getCurrent().getSystemColor(
SWT.COLOR_WHITE));
helpLink.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent event)
{
Program.launch(event.text);
}
});
StringBuilder helpStr = new StringBuilder();
helpStr.append("Here is some example trace:\n");
helpStr.append("[14:14:30]:[1]:example.ExampleClass:multiplyMethod: {:100\n");
helpStr.append("[14:14:30]:[1]:example.ExampleClass:multiplyMethod: Arg: 2\n");
helpStr.append("[14:14:30]:[1]:example.ExampleClass:multiplyMethod: Arg: 4\n");
helpStr.append("[14:14:30]:[1]:example.ExampleClass:multiplyMethod: /:101\n");
helpStr.append("[14:14:30]:[1]:example.ExampleClass:multiplyMethod: Return: 8\n");
helpStr.append("[14:14:30]:[1]:example.ExampleClass:multiplyMethod: }:105\n");
helpStr.append("\n");
helpStr.append("This means the following:\n");
helpStr.append("[14:14:30] is a timestamp");
helpStr.append("[1] - the thread ID\n");
helpStr.append("example.ExampleClass:multiplyMethod - the Class and Method being traced\n");
helpStr.append("{:100 - The method was entered on source line 100\n");
helpStr.append("Arg: 2 - The first argument had value 2\n");
helpStr.append("Arg: 2 - The second argument had value 4\n");
helpStr.append("/:101 - An optional block of code was executed starting at source line 101 (e.g. an if statement)\n");
helpStr.append("Return: 8 - The method returned value 8\n");
helpStr.append("}:105 - The method returned on source line 105\n");
textOutput.setText(helpStr.toString());
}
}
// Window ref // Window ref
private final InTraceUI thisWindow = this; private final InTraceUI thisWindow = this;
private ConnectState connectionState = ConnectState.DISCONNECTED; private ConnectState connectionState = ConnectState.DISCONNECTED;
public void setConnectionState(ConnectState connectionState)
{
this.connectionState = connectionState;
IConnectionStateCallback callback = connCallback;
if (callback != null)
{
callback.setConnectionState(connectionState);
}
}
// Network details // Network details
private InetAddress remoteAddress; private InetAddress remoteAddress;
@ -1189,12 +1363,15 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
// Settings // Settings
private ParsedSettingsData settingsData = new ParsedSettingsData( private ParsedSettingsData settingsData = new ParsedSettingsData(
new HashMap<String, String>()); new HashMap<String, String>());
private Pattern lastEnteredIncludeFilterPattern = TraceFilterThread.MATCH_ALL;
private Pattern lastEnteredIncludeFilterPattern = TraceFilterThread.MATCH_NONE;
private Pattern activeIncludeFilterPattern = TraceFilterThread.MATCH_NONE;
private Pattern oldIncludeFilterPattern = TraceFilterThread.MATCH_NONE;
private Pattern lastEnteredExcludeFilterPattern = TraceFilterThread.MATCH_NONE; private Pattern lastEnteredExcludeFilterPattern = TraceFilterThread.MATCH_NONE;
private Pattern activeIncludeFilterPattern = TraceFilterThread.MATCH_ALL;
private Pattern oldIncludeFilterPattern = TraceFilterThread.MATCH_ALL;
private Pattern activeExcludeFilterPattern = TraceFilterThread.MATCH_NONE; private Pattern activeExcludeFilterPattern = TraceFilterThread.MATCH_NONE;
private Pattern oldExcludeFilterPattern = TraceFilterThread.MATCH_NONE; private Pattern oldExcludeFilterPattern = TraceFilterThread.MATCH_NONE;
private boolean autoScroll = true; private boolean autoScroll = true;
private boolean fixedConnection = false; private boolean fixedConnection = false;
@ -1207,7 +1384,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
controlThread = new ControlConnectionThread(socket, this); controlThread = new ControlConnectionThread(socket, this);
controlThread.start(); controlThread.start();
controlThread.sendMessage("getsettings"); controlThread.sendMessage("getsettings");
connectionState = ConnectState.CONNECTED; setConnectionState(ConnectState.CONNECTED);
controlThread.sendMessage("[out-network"); controlThread.sendMessage("[out-network");
String networkTracePortStr = controlThread.getMessage(); String networkTracePortStr = controlThread.getMessage();
@ -1233,7 +1410,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
} }
} else } else
{ {
connectionState = ConnectState.DISCONNECTED_ERR; setConnectionState(ConnectState.DISCONNECTED_ERR);
} }
updateUIState(); updateUIState();
} }
@ -1248,7 +1425,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
{ {
networkTraceThread.disconnect(); networkTraceThread.disconnect();
} }
connectionState = ConnectState.DISCONNECTED; setConnectionState(ConnectState.DISCONNECTED);
updateUIState(); updateUIState();
} }
@ -1361,6 +1538,15 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
connTab.portInput.setText(Integer.toString(settingsData.actualServerPort)); connTab.portInput.setText(Integer.toString(settingsData.actualServerPort));
} }
if (settingsData.waitStart)
{
addWaitStartUI();
}
else
{
removeWaitStartUI();
}
if (connectionState == ConnectState.CONNECTING) if (connectionState == ConnectState.CONNECTING)
{ {
connTab.connectButton.setText(ClientStrings.CONNECTING); connTab.connectButton.setText(ClientStrings.CONNECTING);
@ -1372,9 +1558,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
chooseText(connTab.connectButton, chooseText(connTab.connectButton,
(connectionState == ConnectState.CONNECTED), ClientStrings.CONNECT, (connectionState == ConnectState.CONNECTED), ClientStrings.CONNECT,
ClientStrings.DISCONNECT); ClientStrings.DISCONNECT);
chooseText(instruTab.togInstru,
settingsData.instrEnabled, ClientStrings.ENABLE_INSTR,
ClientStrings.DISABLE_INSTR);
if (connectionState == ConnectState.CONNECTED) if (connectionState == ConnectState.CONNECTED)
{ {
@ -1385,7 +1568,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
// Enable all buttons // Enable all buttons
instruTab.classRegex.setEnabled(true); instruTab.classRegex.setEnabled(true);
instruTab.listClasses.setEnabled(true); instruTab.listClasses.setEnabled(true);
instruTab.togInstru.setEnabled(true);
traceTab.argsTrace.setEnabled(true); traceTab.argsTrace.setEnabled(true);
traceTab.branchTrace.setEnabled(true); traceTab.branchTrace.setEnabled(true);
@ -1400,7 +1582,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
textOutputTab.networkOutput.setEnabled(true); textOutputTab.networkOutput.setEnabled(true);
// Update the button pressed/unpressed state // Update the button pressed/unpressed state
instruTab.togInstru.setSelection(settingsData.instrEnabled);
traceTab.argsTrace.setSelection(settingsData.argsEnabled); traceTab.argsTrace.setSelection(settingsData.argsEnabled);
traceTab.branchTrace.setSelection(settingsData.branchEnabled); traceTab.branchTrace.setSelection(settingsData.branchEnabled);
traceTab.entryExitTrace.setSelection(settingsData.entryExitEnabled); traceTab.entryExitTrace.setSelection(settingsData.entryExitEnabled);
@ -1435,7 +1616,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
instruTab.classRegex.setEnabled(false); instruTab.classRegex.setEnabled(false);
instruTab.listClasses.setEnabled(false); instruTab.listClasses.setEnabled(false);
instruTab.togInstru.setEnabled(false);
traceTab.argsTrace.setEnabled(false); traceTab.argsTrace.setEnabled(false);
traceTab.branchTrace.setEnabled(false); traceTab.branchTrace.setEnabled(false);
@ -1498,9 +1678,9 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
public void run() public void run()
{ {
int numInstr = Integer.parseInt(statusMap int numInstr = Integer.parseInt(statusMap
.get(AgentConfigConstants.NUM_INSTR_CLASSES)); .get(AgentConfigConstants.STINST));
int numTotal = Integer.parseInt(statusMap int numTotal = Integer.parseInt(statusMap
.get(AgentConfigConstants.NUM_TOTAL_CLASSES)); .get(AgentConfigConstants.STCLS));
instruTab.setStatus(numInstr, numTotal); instruTab.setStatus(numInstr, numTotal);
} }
}); });
@ -1519,7 +1699,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
textOutputTab.filterThread textOutputTab.filterThread
.addSystemTraceLine("Latest Settings Received"); .addSystemTraceLine("Latest Settings Received");
settingsData = new ParsedSettingsData(settingsMap); settingsData = new ParsedSettingsData(settingsMap);
connectionState = ConnectState.CONNECTED; setConnectionState(ConnectState.CONNECTED);
updateUIStateSameThread(); updateUIStateSameThread();
} }
}); });

View File

@ -25,6 +25,8 @@ public class ParsedSettingsData
public final int totalClasses; public final int totalClasses;
public final int actualServerPort; public final int actualServerPort;
public final boolean waitStart;
private final Map<String, String> settingsMap; private final Map<String, String> settingsMap;
@ -120,7 +122,7 @@ public class ParsedSettingsData
} }
String numInstrStr = settingsMap String numInstrStr = settingsMap
.get(AgentConfigConstants.NUM_INSTR_CLASSES); .get(AgentConfigConstants.STINST);
if (numInstrStr != null) if (numInstrStr != null)
{ {
instruClasses = Integer.parseInt(numInstrStr); instruClasses = Integer.parseInt(numInstrStr);
@ -131,7 +133,7 @@ public class ParsedSettingsData
} }
String numTotalStr = settingsMap String numTotalStr = settingsMap
.get(AgentConfigConstants.NUM_TOTAL_CLASSES); .get(AgentConfigConstants.STCLS);
if (numTotalStr != null) if (numTotalStr != null)
{ {
totalClasses = Integer.parseInt(numTotalStr); totalClasses = Integer.parseInt(numTotalStr);
@ -141,7 +143,7 @@ public class ParsedSettingsData
totalClasses = 0; totalClasses = 0;
} }
String actualServerPortStr = settingsMap.get(AgentConfigConstants.ACTUAL_SERVER_PORT); String actualServerPortStr = settingsMap.get(AgentConfigConstants.SERVER_PORT);
if (actualServerPortStr != null) if (actualServerPortStr != null)
{ {
actualServerPort = Integer.parseInt(actualServerPortStr); actualServerPort = Integer.parseInt(actualServerPortStr);
@ -150,6 +152,15 @@ public class ParsedSettingsData
{ {
actualServerPort = 9123; actualServerPort = 9123;
} }
if ("true".equals(settingsMap.get(AgentConfigConstants.START_WAIT)))
{
waitStart = true;
}
else
{
waitStart = false;
}
} }
@Override @Override

View File

@ -107,14 +107,18 @@ public class TraceFilterThread implements Runnable
*/ */
private boolean clearTrace = false; private boolean clearTrace = false;
private final boolean standalone;
/** /**
* cTor * cTor
* @param standalone
* *
* @param callback * @param callback
* @param progressCallback * @param progressCallback
*/ */
public TraceFilterThread(TraceTextHandler callback) public TraceFilterThread(boolean standalone, TraceTextHandler callback)
{ {
this.standalone = standalone;
this.callback = callback; this.callback = callback;
thisThread = new Thread(this); thisThread = new Thread(this);
@ -219,11 +223,19 @@ public class TraceFilterThread implements Runnable
{ {
lowMemorySignalled = false; lowMemorySignalled = false;
// I expected a factor of 2 due to trace strings being held by this if (standalone)
// thread along with another copy held by the UI. However, profiling {
// shows a factor of 18 is necessary. This is because we need to be able // I expected a factor of 2 due to trace strings being held by this
// to handle entire copies of the active data when adding new strings. // thread along with another copy held by the UI. However, profiling
numChars += (18 * newTraceLine.length()); // shows a factor of 18 is necessary. This is because we need to be able
// to handle entire copies of the active data when adding new strings.
numChars += (18 * newTraceLine.length());
}
else
{
// Running within eclipse so better be really conservative
numChars += (40 * newTraceLine.length());
}
traceLines.add(newTraceLine); traceLines.add(newTraceLine);
totalLines.incrementAndGet(); totalLines.incrementAndGet();

View File

@ -372,7 +372,7 @@ public class TraceHandler implements IInstrumentationHandler
*/ */
public void writeTraceOutput(String xiOutput) public void writeTraceOutput(String xiOutput)
{ {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd HH:mm:ss.SSS"); SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
long threadID = Thread.currentThread().getId(); long threadID = Thread.currentThread().getId();
String traceString = "[" + dateFormat.format(new Date()) + "]:[" + threadID String traceString = "[" + dateFormat.format(new Date()) + "]:[" + threadID
+ "]:" + xiOutput; + "]:" + xiOutput;

View File

@ -5,24 +5,28 @@ import java.util.Set;
public class AgentConfigConstants public class AgentConfigConstants
{ {
public static final String NUM_STATUS_ID = "NUM_STATUS_ID"; public static final String STID = "STID";
public static final String NUM_TOTAL_CLASSES = "NUM_TOTAL_CLASSES"; public static final String STCLS = "STCLS";
public static final String NUM_INSTR_CLASSES = "NUM_INSTR_CLASSES"; public static final String STINST = "STINST";
public static final String NUM_PROGRESS_ID = "NUM_PROGRESS_ID"; public static final String NUM_PROGRESS_ID = "NUM_PROGRESS_ID";
public static final String NUM_PROGRESS_COUNT = "NUM_PROGRESS_COUNT"; public static final String NUM_PROGRESS_COUNT = "NUM_PROGRESS_COUNT";
public static final String NUM_PROGRESS_TOTAL = "NUM_PROGRESS_TOTAL"; public static final String NUM_PROGRESS_TOTAL = "NUM_PROGRESS_TOTAL";
public static final String NUM_PROGRESS_DONE = "NUM_PROGRESS_DONE"; public static final String NUM_PROGRESS_DONE = "NUM_PROGRESS_DONE";
public static final String ACTUAL_SERVER_PORT = "ACTUAL_SERVER_PORT"; public static final String SERVER_PORT = "SERVER_PORT";
public static final String CLASS_REGEX = "[regex-"; public static final String CLASS_REGEX = "[regex-";
public static final String EXCLUDE_CLASS_REGEX = "[exclude-regex-"; public static final String EXCLUDE_CLASS_REGEX = "[exclude-regex-";
public static final String INSTRU_ENABLED = "[instru-"; public static final String INSTRU_ENABLED = "[instru-";
public static final String SAVE_TRACED_CLASSFILES = "[saveinstru-"; public static final String SAVE_TRACED_CLASSFILES = "[saveinstru-";
public static final String VERBOSE_MODE = "[verbose-"; public static final String VERBOSE_MODE = "[verbose-";
public static final String SERVER_PORT = "[serverport-"; public static final String OPT_SERVER_PORT = "[serverport-";
public static final String CALLBACK_PORT = "[callbackport-"; public static final String CALLBACK_PORT = "[callbackport-";
public static final String START_WAIT = "[startwait";
public static final String START_ACTIVATE = "[startactivate";
public static final Set<String> COMMANDS = new HashSet<String>(); public static final Set<String> COMMANDS = new HashSet<String>();
static static
{ {
@ -31,7 +35,7 @@ public class AgentConfigConstants
COMMANDS.add(INSTRU_ENABLED + "<true/false>"); COMMANDS.add(INSTRU_ENABLED + "<true/false>");
COMMANDS.add(SAVE_TRACED_CLASSFILES + "<true/false>"); COMMANDS.add(SAVE_TRACED_CLASSFILES + "<true/false>");
COMMANDS.add(VERBOSE_MODE + "<true/false>"); COMMANDS.add(VERBOSE_MODE + "<true/false>");
COMMANDS.add(SERVER_PORT + "<int>"); COMMANDS.add(OPT_SERVER_PORT + "<int>");
COMMANDS.add(CALLBACK_PORT + "<int>"); COMMANDS.add(CALLBACK_PORT + "<int>");
} }
} }