diff --git a/org.ntlab.traceCollector/.classpath b/org.ntlab.traceCollector/.classpath
new file mode 100644
index 0000000..b1ca03a
--- /dev/null
+++ b/org.ntlab.traceCollector/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/org.ntlab.traceCollector/.project b/org.ntlab.traceCollector/.project
new file mode 100644
index 0000000..ae83358
--- /dev/null
+++ b/org.ntlab.traceCollector/.project
@@ -0,0 +1,28 @@
+
+
+ org.ntlab.traceCollector
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/org.ntlab.traceCollector/.settings/org.eclipse.jdt.core.prefs b/org.ntlab.traceCollector/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..11f6e46
--- /dev/null
+++ b/org.ntlab.traceCollector/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.ntlab.traceCollector/META-INF/MANIFEST.MF b/org.ntlab.traceCollector/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8cc08ca
--- /dev/null
+++ b/org.ntlab.traceCollector/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Tracer
+Bundle-SymbolicName: org.ntlab.traceCollector;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.ntlab.traceCollector.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jdt.launching,
+ org.eclipse.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.jdt.debug.ui,
+ org.eclipse.jdt.core,
+ com.ibm.icu
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
diff --git a/org.ntlab.traceCollector/build.properties b/org.ntlab.traceCollector/build.properties
new file mode 100644
index 0000000..41eb6ad
--- /dev/null
+++ b/org.ntlab.traceCollector/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/org.ntlab.traceCollector/javassist.jar b/org.ntlab.traceCollector/javassist.jar
new file mode 100644
index 0000000..e9840d5
--- /dev/null
+++ b/org.ntlab.traceCollector/javassist.jar
Binary files differ
diff --git a/org.ntlab.traceCollector/plugin.xml b/org.ntlab.traceCollector/plugin.xml
new file mode 100644
index 0000000..382f05e
--- /dev/null
+++ b/org.ntlab.traceCollector/plugin.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/Activator.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/Activator.java
new file mode 100644
index 0000000..075cce7
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/Activator.java
@@ -0,0 +1,50 @@
+package org.ntlab.traceCollector;
+
+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 = "org.ntlab.traceCollector"; //$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;
+ }
+
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/TracerLaunchConfigurationDelegate.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/TracerLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..32f782b
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/TracerLaunchConfigurationDelegate.java
@@ -0,0 +1,120 @@
+package org.ntlab.traceCollector;
+
+import java.io.File;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jdt.internal.launching.LaunchingMessages;
+import org.eclipse.jdt.launching.ExecutionArguments;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMRunner;
+import org.eclipse.jdt.launching.VMRunnerConfiguration;
+import org.ntlab.traceCollector.tracer.Tracer;
+
+import com.ibm.icu.text.MessageFormat;
+
+public class TracerLaunchConfigurationDelegate extends org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate {
+ @Override
+ public void launch(ILaunchConfiguration configuration, String mode,
+ ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+
+ monitor.beginTask(MessageFormat.format("{0}...", new String[]{configuration.getName()}), 3); //$NON-NLS-1$
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+ try {
+ monitor.subTask(LaunchingMessages.JavaLocalApplicationLaunchConfigurationDelegate_Verifying_launch_attributes____1);
+
+ String mainTypeName = verifyMainTypeName(configuration);
+ IVMRunner runner = getVMRunner(configuration, mode);
+
+ File workingDir = verifyWorkingDirectory(configuration);
+ String workingDirName = null;
+ if (workingDir != null) {
+ workingDirName = workingDir.getAbsolutePath();
+ }
+
+ // Environment variables
+ String[] envp = getEnvironment(configuration);
+
+ // Program & VM arguments
+ String pgmArgs = getProgramArguments(configuration);
+ String vmArgs = getVMArguments(configuration);
+ ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs);
+
+ // VM-specific attributes
+ Map vmAttributesMap = getVMSpecificAttributesMap(configuration);
+
+ // Classpath
+ String[] configClasspath = getClasspath(configuration);
+ String[] classpath;
+ String bundlePath = Activator.getDefault().getBundle().getLocation();
+ if (bundlePath.startsWith("reference:file:/")) {
+ classpath = new String[configClasspath.length + 2];
+ System.arraycopy(configClasspath, 0, classpath, 0, configClasspath.length);
+ classpath[configClasspath.length] = bundlePath.substring(16) + "bin/";
+ classpath[configClasspath.length + 1] = bundlePath.substring(16) + "javassist.jar";
+ } else {
+ classpath = configClasspath;
+ }
+
+ // VM argments
+ String[] configVmArgs = execArgs.getVMArgumentsArray();
+ String[] vmArgs2 = new String[configVmArgs.length + 1];
+ System.arraycopy(configVmArgs, 0, vmArgs2, 0, configVmArgs.length);
+ vmArgs2[configVmArgs.length] = "-Djava.system.class.loader=" + Tracer.TRACER + "TracerClassLoader";
+
+ // Create VM config
+ VMRunnerConfiguration runConfig = new VMRunnerConfiguration(mainTypeName, classpath);
+ runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
+ runConfig.setEnvironment(envp);
+ runConfig.setVMArguments(vmArgs2);
+ runConfig.setWorkingDirectory(workingDirName);
+ runConfig.setVMSpecificAttributesMap(vmAttributesMap);
+
+ // Bootpath
+ runConfig.setBootClassPath(getBootpath(configuration));
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ // stop in main
+ prepareStopInMain(configuration);
+
+ // done the verification phase
+ monitor.worked(1);
+
+ monitor.subTask(LaunchingMessages.JavaLocalApplicationLaunchConfigurationDelegate_Creating_source_locator____2);
+ // set the default source locator if required
+ setDefaultSourceLocator(launch, configuration);
+ monitor.worked(1);
+
+ // Launch the configuration - 1 unit of work
+ runner.run(runConfig, launch, monitor);
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ @Override
+ public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException {
+ IVMInstall vm = verifyVMInstall(configuration);
+ IVMRunner runner = vm.getVMRunner(mode);
+ return runner;
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/ITraceGenerator.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/ITraceGenerator.java
new file mode 100644
index 0000000..a39f372
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/ITraceGenerator.java
@@ -0,0 +1,51 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.util.List;
+
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtMethod;
+
+/**
+ * �g���[�X�o�͂��s�����s��������̃t�H�[�}�b�g�ˑ�����
+ * @author Nitta
+ *
+ */
+public interface ITraceGenerator {
+
+ public abstract String generateReplaceStatementsForFieldSet(
+ String fieldName, String containerClass, String containerObject,
+ String valueClass, String valueObject,
+ String threadId, String lineNum, String timeStamp);
+
+ public abstract String generateReplaceStatementsForFieldGet(
+ String fieldName, String thisClass, String thisObject,
+ String containerClass, String containerObject,
+ String valueClass, String valueObject,
+ String threadId, String lineNum, String timeStamp);
+
+ public abstract String generateInsertBeforeStatements(
+ CtBehavior m, String methodSignature,
+ String thisClass, String thisObject,
+ List argClasses, List argObjects,
+ String threadId, String timeStamp);
+
+ public abstract String generateInsertAfterStatements(
+ CtClass cls, CtBehavior m,
+ String thisClass, String thisObject,
+ String returnedClass, String returnedObject,
+ String threadId, String timeStamp,
+ boolean isCallerSideInstrumentation);
+
+ public abstract String generateInsertStatementsForCall(
+ CtBehavior m, String lineNum, String threadId);
+
+ public abstract String generateReplaceStatementsForNewArray(
+ String arrayClass, String arrayObject, String dimension,
+ String threadId, String lineNum, String timeStamp);
+
+ public abstract String generateInsertStatementsForBlockEntry(
+ CtMethod m, String blockId, String incomings,
+ String threadId, String lineNum, String timeStamp);
+
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/JSONArrayAdvisor.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/JSONArrayAdvisor.java
new file mode 100644
index 0000000..7c4373c
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/JSONArrayAdvisor.java
@@ -0,0 +1,130 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.util.ArrayList;
+
+/**
+ * �z��ւ̃A�N�Z�X�����o�͂��邽�߂̃N���X
+ * @author �V�c����
+ *
+ */
+public class JSONArrayAdvisor {
+ public static void arrayWriteInt(Object array, int index, int value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "int", Integer.toString(value), threadId, timeStamp);
+ ((int [])array)[index] = value;
+ }
+
+ public static int arrayReadInt(Object array, int index) {
+ int value = ((int [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "int", Integer.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteLong(Object array, int index, long value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "long", Long.toString(value), threadId, timeStamp);
+ ((long [])array)[index] = value;
+ }
+
+ public static long arrayReadLong(Object array, int index) {
+ long value = ((long [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "long", Long.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteFloat(Object array, int index, float value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "float", Float.toString(value), threadId, timeStamp);
+ ((float [])array)[index] = value;
+ }
+
+ public static float arrayReadFloat(Object array, int index) {
+ float value = ((float [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "float", Float.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteDouble(Object array, int index, double value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "double", Double.toString(value), threadId, timeStamp);
+ ((double [])array)[index] = value;
+ }
+
+ public static double arrayReadDouble(Object array, int index) {
+ double value = ((double [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "double", Double.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteShort(Object array, int index, short value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "short", Short.toString(value), threadId, timeStamp);
+ ((short [])array)[index] = value;
+ }
+
+ public static short arrayReadShort(Object array, int index) {
+ short value = ((short [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "short", Short.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteChar(Object array, int index, char value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "char", Character.toString(value), threadId, timeStamp);
+ ((char [])array)[index] = value;
+ }
+
+ public static char arrayReadChar(Object array, int index) {
+ char value = ((char [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "char", Character.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteByteOrBoolean(Object array, int index, byte value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "byte", Byte.toString(value), threadId, timeStamp);
+ ((byte [])array)[index] = value;
+ }
+
+ public static byte arrayReadByteOrBoolean(Object array, int index) {
+ byte value = ((byte [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, "byte", Byte.toString(value), threadId, timeStamp);
+ return value;
+ }
+
+ public static void arrayWriteObject(Object array, int index, Object value) {
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arraySetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, value.getClass().getName(), Integer.toString(System.identityHashCode(value)), threadId, timeStamp);
+ ((Object [])array)[index] = value;
+ }
+
+ public static Object arrayReadObject(Object array, int index) {
+ Object value = ((Object [])array)[index];
+ long threadId = Thread.currentThread().getId();
+ long timeStamp = System.nanoTime();
+ JSONTraceGenerator.arrayGetOutput(array.getClass().getName(), Integer.toString(System.identityHashCode(array)), index, value.getClass().getName(), Integer.toString(System.identityHashCode(value)), threadId, timeStamp);
+ return value;
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/JSONTraceGenerator.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/JSONTraceGenerator.java
new file mode 100644
index 0000000..0d67a0c
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/JSONTraceGenerator.java
@@ -0,0 +1,226 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+
+/**
+ * JSON�g���[�X�o�͗p�̎��s��������
+ * @author Nitta
+ *
+ */
+public class JSONTraceGenerator implements ITraceGenerator {
+ private static final String DQ_GEN = "\"\\\"\"";
+
+ @Override
+ public String generateReplaceStatementsForFieldSet(
+ String fieldName, String containerClass, String containerObject,
+ String valueClass, String valueObject,
+ String threadId, String lineNum, String timeStamp) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ keys.add("type"); values.add(DQ_GEN + " + \"fieldSet\" + " + DQ_GEN);
+ keys.add("fieldName"); values.add(DQ_GEN + " + " + fieldName + " + " + DQ_GEN);
+ keys.add("container"); values.add(generateJSONObjectGenerator(containerClass, containerObject));
+ keys.add("value"); values.add(generateJSONObjectGenerator(valueClass, valueObject));
+ keys.add("threadId"); values.add(threadId);
+ keys.add("lineNum"); values.add(lineNum);
+ keys.add("time"); values.add(timeStamp);
+ return "$proceed($$); " +
+ Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+ @Override
+ public String generateReplaceStatementsForFieldGet(
+ String fieldName, String thisClass, String thisObject,
+ String containerClass, String containerObject,
+ String valueClass, String valueObject,
+ String threadId, String lineNum, String timeStamp) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ keys.add("type"); values.add(DQ_GEN + " + \"fieldGet\" + " + DQ_GEN);
+ keys.add("fieldName"); values.add(DQ_GEN + " + " + fieldName + " + " + DQ_GEN);
+ keys.add("this"); values.add(generateJSONObjectGenerator(thisClass, thisObject));
+ keys.add("container"); values.add(generateJSONObjectGenerator(containerClass, containerObject));
+ keys.add("value"); values.add(generateJSONObjectGenerator(valueClass, valueObject));
+ keys.add("threadId"); values.add(threadId);
+ keys.add("lineNum"); values.add(lineNum);
+ keys.add("time"); values.add(timeStamp);
+ return "$_ = $proceed(); " +
+ Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+
+ @Override
+ public String generateReplaceStatementsForNewArray(
+ String arrayClass, String arrayObject, String dimension,
+ String threadId, String lineNum, String timeStamp) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ keys.add("type"); values.add(DQ_GEN + " + \"arrayCreate\" + " + DQ_GEN);
+ keys.add("array"); values.add(generateJSONObjectGenerator(arrayClass, arrayObject));
+ keys.add("dimension"); values.add(dimension);
+ keys.add("threadId"); values.add(threadId);
+ keys.add("lineNum"); values.add(lineNum);
+ keys.add("time"); values.add(timeStamp);
+ return "$_ = $proceed($$); " +
+ Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+ @Override
+ public String generateInsertBeforeStatements(
+ CtBehavior m, String methodSignature,
+ String thisClass, String thisObject,
+ List argClasses, List argObjects,
+ String threadId, String timeStamp) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ if (!(m instanceof CtConstructor)) {
+ keys.add("type"); values.add(DQ_GEN + " + \"methodEntry\" + " + DQ_GEN);
+ } else {
+ keys.add("type"); values.add(DQ_GEN + " + \"constructorEntry\" + " + DQ_GEN);
+ }
+ keys.add("signature"); values.add(DQ_GEN + " + " + methodSignature + " + " + DQ_GEN);
+ if (!(m instanceof CtConstructor)) {
+ keys.add("receiver"); values.add(generateJSONObjectGenerator(thisClass, thisObject));
+ } else {
+ keys.add("class"); values.add(DQ_GEN + " + " + thisClass + " + " + DQ_GEN);
+ }
+ ArrayList argList = new ArrayList<>();
+ for (int i = 0; i < argClasses.size(); i++) {
+ argList.add(generateJSONObjectGenerator(argClasses.get(i), argObjects.get(i)));
+ }
+ keys.add("args"); values.add(generateJSONArrayGenerator(argList));
+ keys.add("threadId"); values.add(threadId);
+ keys.add("time"); values.add(timeStamp);
+ return Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+ @Override
+ public String generateInsertAfterStatements(CtClass cls, CtBehavior m,
+ String thisClass, String thisObject, String returnedClass, String returnedObject,
+ String threadId, String timeStamp,
+ boolean isCallerSideInstrumentation) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ if (!(m instanceof CtConstructor)) {
+ keys.add("type"); values.add(DQ_GEN + " + \"methodExit\" + " + DQ_GEN);
+ } else {
+ keys.add("type"); values.add(DQ_GEN + " + \"constructorExit\" + " + DQ_GEN);
+ }
+ keys.add("shortSignature"); values.add(DQ_GEN + " + \"" + m.getLongName().replace('$', '.') + "\" + " + DQ_GEN); // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ if (!(m instanceof CtConstructor)) {
+ keys.add("receiver"); values.add(generateJSONObjectGenerator(thisClass, thisObject));
+ }
+ keys.add("returnValue"); values.add(generateJSONObjectGenerator(returnedClass, returnedObject));
+ keys.add("threadId"); values.add(threadId);
+ keys.add("time"); values.add(timeStamp);
+ return Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+ @Override
+ public String generateInsertStatementsForCall(CtBehavior m, String lineNum, String threadId) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ keys.add("type"); values.add(DQ_GEN + " + \"methodCall\" + " + DQ_GEN);
+ keys.add("callerSideSignature"); values.add(DQ_GEN + " + \"" + m.getLongName().replace('$', '.') + "\" + " + DQ_GEN); // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ keys.add("threadId"); values.add(threadId);
+ keys.add("lineNum"); values.add(lineNum);
+ return Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+ @Override
+ public String generateInsertStatementsForBlockEntry(
+ CtMethod m, String blockId, String incomings,
+ String threadId, String lineNum, String timeStamp) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ keys.add("type"); values.add(DQ_GEN + " + \"blockEntry\" + " + DQ_GEN);
+ keys.add("methodSignature"); values.add(DQ_GEN + " + \"" + m.getLongName().replace('$', '.') + "\" + " + DQ_GEN); // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ keys.add("blockId"); values.add(blockId);
+// keys.add("blockPos"); values.add(blockPos);
+// keys.add("blockLen"); values.add(blockLen);
+ keys.add("incomings"); values.add(incomings);
+ keys.add("threadId"); values.add(threadId);
+ keys.add("lineNum"); values.add(lineNum);
+ keys.add("time"); values.add(timeStamp);
+ return Tracer.TRACER + "MyPrintStream.println(" + generateJSONMapGenerator(keys, values) + " + \",\");";
+ }
+
+ private String generateJSONObjectGenerator(String className, String objectId) {
+ ArrayList keys = new ArrayList<>();
+ ArrayList values = new ArrayList<>();
+ keys.add("class"); values.add(DQ_GEN + " + " + className + " + " + DQ_GEN);
+ keys.add("id"); values.add(objectId);
+ return generateJSONMapGenerator(keys, values);
+ }
+
+ private String generateJSONMapGenerator(ArrayList keys, ArrayList valueGenerators) {
+ String mapJSON = "\"{\" + ";
+ String delimiter = "";
+ for (int i = 0; i < keys.size(); i++) {
+ mapJSON += delimiter + "\"\\\"" + keys.get(i) + "\\\":\" + " + valueGenerators.get(i);
+ delimiter = " + \",\" + ";
+ }
+ mapJSON += " + \"}\"";
+ return mapJSON;
+ }
+ private String generateJSONArrayGenerator(ArrayList valueGenerators) {
+ String arrayJSON = "\"[\"";
+ String delimiter = " + ";
+ for (int i = 0; i < valueGenerators.size(); i++) {
+ arrayJSON += delimiter + valueGenerators.get(i);
+ delimiter = " + \",\" + ";
+ }
+ arrayJSON += " + \"]\"";
+ return arrayJSON;
+ }
+
+ public static void arraySetOutput(String arrayType, String arrayId, int index, String valueType, String valueId, long threadId, long timeStamp) {
+ ArrayList keys = new ArrayList();
+ ArrayList values = new ArrayList();
+ keys.add("type"); values.add("\"arraySet\"");
+ keys.add("array"); values.add(generateJSONObjectOutput(arrayType, arrayId));
+ keys.add("index"); values.add(Integer.toString(index));
+ keys.add("value"); values.add(generateJSONObjectOutput(valueType, valueId));
+ keys.add("threadId"); values.add(Long.toString(threadId));
+ keys.add("time"); values.add(Long.toString(timeStamp));
+ MyPrintStream.println(generateJSONMapOutput(keys, values) + ",");
+ }
+
+ public static void arrayGetOutput(String arrayType, String arrayId, int index, String valueType, String valueId, long threadId, long timeStamp) {
+ ArrayList keys = new ArrayList();
+ ArrayList values = new ArrayList();
+ keys.add("type"); values.add("\"arrayGet\"");
+ keys.add("array"); values.add(generateJSONObjectOutput(arrayType, arrayId));
+ keys.add("index"); values.add(Integer.toString(index));
+ keys.add("value"); values.add(generateJSONObjectOutput(valueType, valueId));
+ keys.add("threadId"); values.add(Long.toString(threadId));
+ keys.add("time"); values.add(Long.toString(timeStamp));
+ MyPrintStream.println(generateJSONMapOutput(keys, values) + ",");
+ }
+
+ private static String generateJSONObjectOutput(String className, String objectId) {
+ ArrayList keys = new ArrayList();
+ ArrayList values = new ArrayList();
+ keys.add("class"); values.add("\"" + className + "\"");
+ keys.add("id"); values.add(objectId);
+ return generateJSONMapOutput(keys, values);
+ }
+
+ private static String generateJSONMapOutput(ArrayList keys, ArrayList valueGenerators) {
+ String mapJSON = "{";
+ String delimiter = "";
+ for (int i = 0; i < keys.size(); i++) {
+ mapJSON += delimiter + "\"" + keys.get(i) + "\":" + valueGenerators.get(i);
+ delimiter = ",";
+ }
+ mapJSON += "}";
+ return mapJSON;
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/MyPrintStream.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/MyPrintStream.java
new file mode 100644
index 0000000..6ddba5d
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/MyPrintStream.java
@@ -0,0 +1,98 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.util.ArrayList;
+
+/**
+ * �g���[�X�o�͗p���[�e�B���e�B
+ *
+ * @author Nitta
+ *
+ */
+public class MyPrintStream extends Thread {
+ private static MyPrintStream theInstance;
+ private static ArrayList output;
+ private static String s;
+// private static boolean bFlushed = false;
+// private static int count = 0;
+
+ private static MyPrintStream getInstance() {
+ if (theInstance == null) {
+ theInstance = new MyPrintStream();
+ output = new ArrayList();
+ Runtime.getRuntime().addShutdownHook(theInstance); // �V���b�g�_�E���p
+// theInstance.start();
+ }
+ return theInstance;
+ }
+
+ public static void print(int n) {
+ getInstance()._print(n);
+ }
+
+ public static void print(String s) {
+ getInstance()._print(s);
+ }
+
+ public static void println() {
+ getInstance()._println();
+ }
+
+ public static void println(String s) {
+ getInstance()._println(s);
+ }
+
+ public void run() {
+// if (count == 0) {
+// // �ʏ�̃g���[�X�o��
+// count++;
+// String s;
+// Runtime.getRuntime().addShutdownHook(new MyPrintStream()); // �V���b�g�_�E���p�ɂ����ЂƂC���X�^���X���쐬����
+// while(!bFlushed) {
+// try {
+// Thread.sleep(10);
+// if (output.size() > 0) {
+// synchronized (output) {
+// s = output.remove(0);
+// }
+// System.out.println(s);
+// }
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// }
+// } else {
+ // �V���b�g�_�E�����Ƀo�b�t�@�Ɏc�����g���[�X���o�͂���
+// bFlushed = true;
+ for (int n = 0; n < output.size(); n++) {
+ System.out.println(output.get(n));
+ }
+// }
+ }
+
+ private void _print(int n) {
+ if (s == null) s = new String();
+ s += n;
+ }
+
+ private void _print(String s1) {
+ if (s == null) s = new String();
+ s += s1;
+ }
+
+ private void _println() {
+ if (s == null) s = new String();
+ synchronized (output) {
+ output.add(s);
+ }
+ s = new String();
+ }
+
+ private void _println(String s1) {
+ if (s == null) s = new String();
+ s += s1;
+ synchronized (output) {
+ output.add(s);
+ }
+ s = new String();
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java
new file mode 100644
index 0000000..50c0bb5
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/OutputStatementsGenerator.java
@@ -0,0 +1,255 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.util.ArrayList;
+
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import javassist.Modifier;
+import javassist.NotFoundException;
+import javassist.bytecode.analysis.ControlFlow.Block;
+import javassist.expr.FieldAccess;
+import javassist.expr.NewArray;
+
+/**
+ * �g���[�X�o�͂��s�����s��������N���X�i�t�H�[�}�b�g�ˑ�������ITraceGenerator�Ɉڏ��j
+ *
+ * @author Nitta
+ *
+ */
+public class OutputStatementsGenerator {
+ private ITraceGenerator generator;
+
+ public OutputStatementsGenerator(ITraceGenerator generator) {
+ this.generator = generator;
+ }
+
+ public ITraceGenerator getGenerator() {
+ return generator;
+ }
+
+ public String generateReplaceStatementsForFieldSet(CtClass cc, FieldAccess f, int line) {
+ String fieldName = "\"" + f.getClassName() + "." + f.getFieldName() + "\"";
+ String containerClass = "(($0 != null)?$0.getClass().getName():\"" + cc.getName() + "\")";
+ String containerObject = "(($0 != null)?System.identityHashCode($0):0)";
+ String valueClass = "(($1 != null)?$1.getClass().getName():\"---\")";
+ String valueObject = "(($1 != null)?System.identityHashCode($1):0)";
+ String threadId = "Thread.currentThread().getId()";
+ String lineNum = "\"" + line + "\"";
+ String timeStamp = "System.nanoTime()";
+ return generator.generateReplaceStatementsForFieldSet(fieldName, containerClass, containerObject, valueClass, valueObject, threadId, lineNum, timeStamp);
+ }
+
+ public String generateReplaceStatementsForFieldGet(CtClass cc, CtBehavior m, FieldAccess f, int line) {
+ String fieldName = "\"" + f.getClassName() + "." + f.getFieldName() + "\"";
+ String thisClass;
+ String thisObject;
+ if ((m.getModifiers() & Modifier.STATIC) == 0 && m instanceof CtMethod) {
+ thisClass = "this.getClass().getName()";
+ thisObject = "System.identityHashCode(this)";
+ } else {
+ // static���\�b�h���R���X�g���N�^�̏ꍇ
+ thisClass = "\"" + cc.getName() + "\"";
+ thisObject = "\"0\"";
+ }
+ String containerClass = "(($0 != null)?$0.getClass().getName():\"---\")";
+ String containerObject = "(($0 != null)?System.identityHashCode($0):0)";
+ String valueClass = "(($_ != null)?$_.getClass().getName():\"---\")";
+ String valueObject = "(($_ != null)?System.identityHashCode($_):0)";
+ String threadId = "Thread.currentThread().getId()";
+ String lineNum = "\"" + line + "\"";
+ String timeStamp = "System.nanoTime()";
+ return generator.generateReplaceStatementsForFieldGet(fieldName, thisClass, thisObject, containerClass, containerObject, valueClass, valueObject, threadId, lineNum, timeStamp);
+ }
+
+
+ public String generateReplaceStatementsForNewArray(NewArray a, int line) {
+ String arrayClass = "(($_ != null)?$_.getClass().getName():\"---\")";
+ String arrayObject = "(($_ != null)?System.identityHashCode($_):0)";
+ String dimension = "\"" + Integer.toString(a.getDimension()) + "\"";
+ String threadId = "Thread.currentThread().getId()";
+ String lineNum = "\"" + line + "\"";
+ String timeStamp = "System.nanoTime()";
+ return generator.generateReplaceStatementsForNewArray(arrayClass, arrayObject, dimension, threadId, lineNum, timeStamp);
+ }
+
+ public String generateReplaceStatementsForCall(CtClass cls, CtBehavior m, int line, boolean canManipulateCalledMethod) throws NotFoundException {
+ if (canManipulateCalledMethod) {
+ // �Ăяo����ɖ��ߍ��ނ��Ƃ��ł���ꍇ
+ return generateInsertStatementsForCall(cls, m, line) + " $_ = $proceed($$);";
+ } else {
+ // �Ăяo����ɖ��ߍ��ނ��Ƃ��ł��Ȃ��ꍇ
+ return generateInsertStatementsForCall(cls, m, line) + generateInsertBeforeStatements(cls, m, true) + " $_ = $proceed($$); " + generateInsertAfterStatements(cls, m, true);
+ }
+ }
+
+ public String generateInsertBeforeStatementsForMethodBody(CtClass cls, CtBehavior m) throws NotFoundException {
+ return "{" + generateInsertBeforeStatements(cls, m, false) + "}";
+ }
+
+ public String generateInsertAfterStatementsForMethodBody(CtClass cls, CtBehavior m) throws NotFoundException {
+ return "{" + generateInsertAfterStatements(cls, m, false) + "}";
+ }
+
+ /**
+ * �g���[�X�o�͗p�̖��ߗ������
+ * @param cls �ΏۃN���X
+ * @param m �Ώۃ��\�b�h(�R���X�g���N�^)
+ * @param isCallerSideInstrumentation ���ߗ���Ăяo�����ɑ}�����邩�Ăяo����鑤�ɑ}�����邩?
+ * @return
+ * @throws NotFoundException
+ */
+ private String generateInsertBeforeStatements(CtClass cls, CtBehavior m, boolean isCallerSideInstrumentation) throws NotFoundException {
+ // ���\�b�h�V�O�j�`���̍\��
+ String declaredClassName = cls.getName();
+ String modifiers = "";
+ if ((m.getModifiers() & Modifier.PUBLIC) != 0) {
+ modifiers = "public ";
+ } else if ((m.getModifiers() & Modifier.PRIVATE) != 0) {
+ modifiers = "private ";
+ } else if ((m.getModifiers() & Modifier.PROTECTED) != 0) {
+ modifiers = "protected ";
+ }
+ if ((m.getModifiers() & Modifier.STATIC) != 0) {
+ modifiers += "static ";
+ }
+ if ((m.getModifiers() & Modifier.FINAL) != 0) {
+ modifiers += "final ";
+ }
+ if ((m.getModifiers() & Modifier.SYNCHRONIZED) != 0) {
+ modifiers += "synchronized ";
+ }
+ String thisClass;
+ String thisObject;
+ String methodSignature = null;
+ if ((m.getModifiers() & Modifier.STATIC) != 0) {
+ // static���\�b�h�̏ꍇ
+ methodSignature = "\"" + modifiers + ((CtMethod)m).getReturnType().getName() + " " + m.getLongName().replace('$', '.') + "\""; // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ thisClass = "\"" + declaredClassName + "\"";
+ thisObject = "\"0\"";
+ } else if (m instanceof CtConstructor) {
+ // �R���X�g���N�^�̏ꍇ
+ methodSignature = "\"" + modifiers + m.getLongName().replace('$', '.') + "\""; // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ thisClass = "\"" + declaredClassName + "\"";
+ thisObject = "\"0\"";
+ } else {
+ // �ʏ탁�\�b�h�̏ꍇ
+ methodSignature = "\"" + modifiers + ((CtMethod)m).getReturnType().getName() + " " + m.getLongName().replace('$', '.') + "\""; // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ if (!isCallerSideInstrumentation) {
+ // �Ăяo����ɖ��ߍ��ޏꍇ(�ʏ�)
+ thisClass = "this.getClass().getName()";
+ thisObject = "System.identityHashCode(this)";
+ } else {
+ // �ďo�����ɖ��ߍ��ޏꍇ(�W���N���X�̌ďo��)
+ thisClass = "$0.getClass().getName()";
+ thisObject = "System.identityHashCode($0)";
+ }
+ }
+ // �����̏o�͎��̍\��
+ int p = 0;
+ CtClass parameterClasses[] = m.getParameterTypes();
+ ArrayList argClasses = new ArrayList<>();
+ ArrayList argObjects = new ArrayList<>();
+ for (CtClass c : parameterClasses) {
+ if (!c.isPrimitive()) {
+ argClasses.add("($" + (p + 1) + ").getClass().getName()");
+ argObjects.add("System.identityHashCode($" + (p + 1) + ")");
+ } else {
+ argClasses.add("\"" + c.getName() + "\""); // ��{�^�̏ꍇ�AgetClass()�ł��Ȃ�����
+ argObjects.add("$" + (p + 1));
+ }
+ p++;
+ }
+
+ String threadId = "Thread.currentThread().getId()";
+ String timeStamp = "System.nanoTime()";
+ return generator.generateInsertBeforeStatements(m, methodSignature, thisClass, thisObject, argClasses, argObjects, threadId, timeStamp);
+ }
+
+ private String generateInsertAfterStatements(CtClass cls, CtBehavior m, boolean isCallerSideInstrumentation) throws NotFoundException {
+ String declaredClassName = cls.getName();
+ String returnedClass;
+ String returnedObject;
+ String thisClass;
+ String thisObject;
+ if ((m.getModifiers() & Modifier.STATIC) != 0) {
+ // static���\�b�h�̏ꍇ
+ if (!((CtMethod)m).getReturnType().isPrimitive() || ((CtMethod)m).getReturnType() == CtClass.voidType) {
+ returnedClass = "(($_ != null)?$_.getClass().getName():\"void\")";
+ returnedObject = "(($_ != null)?System.identityHashCode($_):0)";
+ thisClass = "\"" + declaredClassName + "\"";
+ thisObject = "\"0\"";
+ } else {
+ returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\"";
+ returnedObject = "$_";
+ thisClass = "\"" + declaredClassName + "\"";
+ thisObject = "\"0\"";
+ }
+ } else if (m instanceof CtConstructor) {
+ // �R���X�g���N�^�̏ꍇ
+ if (!isCallerSideInstrumentation) {
+ // �Ăяo����ɖ��ߍ��ޏꍇ(�ʏ�)
+ returnedClass = "$0.getClass().getName()";
+ returnedObject = "System.identityHashCode($0)";
+ thisClass = "\"" + declaredClassName + "\"";
+ thisObject = "System.identityHashCode($0)";
+ } else {
+ // �ďo�����ɖ��ߍ��ޏꍇ(�W���N���X�������̓f�t�H���g�R���X�g���N�^�̌ďo���A�܂��͐e�R���X�g���N�^�̌ďo��)
+ returnedClass = "(($_ != null)?$_.getClass().getName():$0.getClass().getName())";
+ returnedObject = "(($_ != null)?System.identityHashCode($_):System.identityHashCode($0))";
+ thisClass = "\"" + declaredClassName + "\"";
+ thisObject = "(($_ != null)?System.identityHashCode($_):System.identityHashCode($0))";
+ }
+ } else {
+ // �ʏ�̃��\�b�h�̏ꍇ
+ if (!isCallerSideInstrumentation) {
+ // �Ăяo����ɖ��ߍ��ޏꍇ(�ʏ�)
+ if (!((CtMethod)m).getReturnType().isPrimitive() || ((CtMethod)m).getReturnType() == CtClass.voidType) {
+ returnedClass = "(($_ != null)?$_.getClass().getName():\"void\")";
+ returnedObject = "(($_ != null)?System.identityHashCode($_):0)";
+ thisClass = "this.getClass().getName()";
+ thisObject = "System.identityHashCode(this)";
+ } else {
+ returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\"";
+ returnedObject = "$_";
+ thisClass = "this.getClass().getName()";
+ thisObject = "System.identityHashCode(this)";
+ }
+ } else {
+ // �ďo�����ɖ��ߍ��ޏꍇ(�W���N���X�̌ďo��)
+ if (!((CtMethod)m).getReturnType().isPrimitive() || ((CtMethod)m).getReturnType() == CtClass.voidType) {
+ returnedClass = "(($_ != null)?$_.getClass().getName():\"void\")";
+ returnedObject = "(($_ != null)?System.identityHashCode($_):0)";
+ thisClass = "$0.getClass().getName()";
+ thisObject = "System.identityHashCode($0)";
+ } else {
+ returnedClass = "\"" + ((CtMethod)m).getReturnType().getName() +"\"";
+ returnedObject = "$_";
+ thisClass = "$0.getClass().getName()";
+ thisObject = "System.identityHashCode($0)";
+ }
+ }
+ }
+ String threadId = "Thread.currentThread().getId()";
+ String timeStamp = "System.nanoTime()";
+ return generator.generateInsertAfterStatements(cls, m, thisClass, thisObject, returnedClass, returnedObject, threadId, timeStamp, isCallerSideInstrumentation);
+ }
+
+ private String generateInsertStatementsForCall(CtClass cls, CtBehavior m, int line) {
+ String lineNum = "\"" + line + "\"";
+ String threadId = "Thread.currentThread().getId()";
+ return generator.generateInsertStatementsForCall(m, lineNum, threadId);
+ }
+
+ public String generateInsertStatementsForBlockEntry(CtMethod m, int id, Block block, int line) {
+ String blockId = "\"" + id + "\"";
+// String blockPos = "\"" + block.position() + "\"";
+// String blockLen = "\"" + block.length() + "\"";
+ String incomings = "\"" + block.incomings() + "\"";
+ String threadId = "Thread.currentThread().getId()";
+ String lineNum = "\"" + line + "\"";
+ String timeStamp = "System.nanoTime()";
+ return generator.generateInsertStatementsForBlockEntry(m, blockId, incomings, threadId, lineNum, timeStamp);
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/PlainTextTraceGenerator.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/PlainTextTraceGenerator.java
new file mode 100644
index 0000000..0da32cd
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/PlainTextTraceGenerator.java
@@ -0,0 +1,115 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.util.List;
+
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+
+/**
+ * �]���̃g���[�X�o�͗p�̎��s��������
+ * @author Nitta
+ *
+ */
+public class PlainTextTraceGenerator implements ITraceGenerator {
+ public static final String LINE_AND_THREAD = "\":Line \" + (" + Tracer.TRACER + "Tracer.lineNo++) + \":ThreadNo \" + ";
+ public static final String LINE = "\":Line \" + (" + Tracer.TRACER + "Tracer.lineNo++) + \":\"";
+
+ @Override
+ public String generateReplaceStatementsForFieldSet(
+ String fieldName, String containerClass, String containerObject,
+ String valueClass, String valueObject, String threadId, String lineNum, String timeStamp) {
+ return "$proceed($$); " +
+ Tracer.TRACER + "MyPrintStream.println(\"set:\" + " + containerClass + " + \":\" + " + containerObject + " + \":\" + " +
+ valueClass + " + \":\" + " + valueObject + " + " + LINE_AND_THREAD + threadId + ");";
+ }
+
+ @Override
+ public String generateReplaceStatementsForFieldGet(
+ String fieldName, String thisClass, String thisObject, String containerClass, String containerObject,
+ String valueClass, String valueObject, String threadId, String lineNum, String timeStamp) {
+ return "$_ = $proceed(); " +
+ Tracer.TRACER + "MyPrintStream.println(\"get:\" + " + thisClass + " + \":\" + " + thisObject + " + \":\" + " +
+ containerClass + " + \":\" + " + containerObject + " + \":\" + " +
+ valueClass + " + \":\" + " + valueObject + " + " + LINE_AND_THREAD + threadId + ");";
+ }
+
+ @Override
+ public String generateReplaceStatementsForNewArray(
+ String arrayClass, String arrayObject, String dimension,
+ String threadId, String lineNum, String timeStamp) {
+ return "$_ = $proceed($$);";
+ }
+
+ @Override
+ public String generateInsertBeforeStatements(CtBehavior m, String methodSignature,
+ String thisClass, String thisObject,
+ List argClasses, List argObjects,
+ String threadId, String timeStamp) {
+ String newOutput = "";
+ String methodOutput = "";
+ String classOutput = "";
+ String argsOutput = "";
+ // �����̏o��
+ String delimiter = Tracer.TRACER + "MyPrintStream.println(\"Args:\" + ";
+ for (int p = 0; p < argClasses.size(); p++) {
+ argsOutput += delimiter + argClasses.get(p) + " + \":\" + " + argObjects.get(p);
+ delimiter = " + \":\" + ";
+ }
+ if (argClasses.size() > 0) {
+ argsOutput += " + " + LINE_AND_THREAD + threadId + ");";
+ }
+ if (m instanceof CtConstructor) {
+ // �R���X�g���N�^�̏ꍇ
+ newOutput = Tracer.TRACER + "MyPrintStream.println(\"New \" + " + thisClass + " + \":\" + " + thisObject + " + " + LINE_AND_THREAD + threadId + ");";
+ }
+ methodOutput = Tracer.TRACER + "MyPrintStream.println(\"Method \" + " + thisClass + " + \",\" + " + methodSignature
+ + " + \":\" + " + thisObject + " + " + LINE + " + " + timeStamp + " + \":ThreadNo \" + " + threadId + ");";
+ classOutput = Tracer.TRACER + "MyPrintStream.println(\"Class \" + " + thisClass + " + \":\" + " + thisObject + " + " + LINE_AND_THREAD + threadId + ");";
+
+ return newOutput + methodOutput + classOutput + argsOutput;
+ }
+
+ @Override
+ public String generateInsertAfterStatements(CtClass cls, CtBehavior m,
+ String thisClass, String thisObject,
+ String returnedClass, String returnedObject,
+ String threadId, String timeStamp, boolean isCallerSideInstrumentation) {
+ String shortName = null;
+ String invocationType = null;
+ if (m instanceof CtConstructor) {
+ // �R���X�g���N�^�̏ꍇ
+ shortName = m.getName().replace('$', '.') + "()"; // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ invocationType = "initialization";
+ } else {
+ // �ʏ�̃��\�b�h��������static���\�b�h�̏ꍇ
+ shortName = cls.getSimpleName().replace('$', '.') + "." + m.getName() + "()"; // AspectJ�ł̓��\�b�h�V�O�j�`�����ł͖����N���X�̓h�b�g�ŋ����
+ if (!isCallerSideInstrumentation) {
+ // �Ăяo����ɖ��ߍ��ޏꍇ(�ʏ�)
+ invocationType = "execution";
+ } else {
+ // �ďo�����ɖ��ߍ��ޏꍇ(�W���N���X�̌ďo��)
+ invocationType = "call";
+ }
+ }
+
+ String returnOutput = Tracer.TRACER + "MyPrintStream.print(\"Return " + invocationType + "(" + shortName + "):\" + " + returnedClass + " + \":\" + " + returnedObject + " + \":\");" +
+ Tracer.TRACER + "MyPrintStream.println(\"\" + " + thisObject + " + " + LINE_AND_THREAD + threadId + ");";
+
+ return returnOutput;
+ }
+
+ @Override
+ public String generateInsertStatementsForCall(CtBehavior m, String lineNum,
+ String threadId) {
+ return "";
+ }
+
+ @Override
+ public String generateInsertStatementsForBlockEntry(
+ CtMethod m, String blockId, String incomings,
+ String threadId, String lineNum, String timeStamp) {
+ return "";
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java
new file mode 100644
index 0000000..731e727
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/Tracer.java
@@ -0,0 +1,212 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLDecoder;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CodeConverter;
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.analysis.ControlFlow;
+import javassist.bytecode.analysis.ControlFlow.Block;
+import javassist.expr.ExprEditor;
+import javassist.expr.FieldAccess;
+import javassist.expr.MethodCall;
+import javassist.expr.NewArray;
+import javassist.expr.NewExpr;
+
+/**
+ * �g���[�X�o�͕���Ώۃp�b�P�[�W���ɐD�荞�ރN���X
+ *
+ * @author Nitta
+ *
+ */
+public class Tracer {
+ public static int lineNo = 1;
+ public static final String TRACER = "org.ntlab.traceCollector.tracer.";
+ private static final String STANDARD_CLASSES = "java.util.ListIterator|java.util.Iterator|java.util.List|java.util.Vector|java.util.ArrayList|java.util.Stack|java.util.Map|java.util.HashMap|java.util.Set|java.util.HashSet|java.util.Hashtable|java.util.LinkedList|java.lang.Thread";
+ private static final String CONCRETE_STANDARD_CLASSES = "java.util.Vector|java.util.ArrayList|java.util.Stack |java.util.HashMap|java.util.HashSet|java.util.Hashtable|java.util.LinkedList|java.lang.Thread";
+ private static final String EXCEPT_FOR_METHODS = "java.lang.Thread.currentThread..|java.lang.Thread.getId..";
+ private static final String STANDARD_LIB = "java.";
+ private static OutputStatementsGenerator outputStatementsGenerator = null;
+ private static CodeConverter conv = new CodeConverter();
+
+ public static void main(String[] args) {
+ initialize(new OutputStatementsGenerator(new JSONTraceGenerator())); // �����ŏo�̓t�H�[�}�b�g���w�肷��
+ packageInstrumentation("worstCase"); // �w�肵���p�b�P�[�W�����̑S�N���X�ɃC���X�g�D�������e�[�V�������s��
+ }
+
+ /**
+ * �o�͕���������w�肵�ăC���X�g�D�������e�[�V�����̏��������s��
+ *
+ * @param outputStatementsGenerator �o�͕�������(�o�̓t�H�[�}�b�g���w��ł���)
+ */
+ public static void initialize(OutputStatementsGenerator outputStatementsGenerator) {
+ // �z��ւ̃A�N�Z�X�̌��o
+ Tracer.outputStatementsGenerator = outputStatementsGenerator; // �����ŏo�̓t�H�[�}�b�g���w�肷��
+ if (!(Tracer.outputStatementsGenerator.getGenerator() instanceof PlainTextTraceGenerator)) {
+ //
+ ClassPool cp = ClassPool.getDefault();
+ CtClass cc;
+ try {
+ cc = cp.get(TRACER + "JSONArrayAdvisor"); // JSON�̏ꍇ�̂ݔz��A�N�Z�X���o�͂���
+ conv.replaceArrayAccess(cc, new CodeConverter.DefaultArrayAccessReplacementMethodNames());
+ } catch (NotFoundException e1) {
+ e1.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * �������ς݂�?
+ * @return �������ς�: true, ����ȊO: false
+ */
+ public static boolean isInitialized() {
+ return (outputStatementsGenerator != null);
+ }
+
+ /**
+ * �w�肵���p�b�P�[�W���̃N���X�ɃC���X�g�D�������e�[�V�������s��
+ *
+ * @param packageName �p�b�P�[�W��
+ */
+ public static void packageInstrumentation(String packageName) {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ URL resource = loader.getResource(packageName);
+ File dir;
+ try {
+ dir = new File(URLDecoder.decode(resource.getPath(), "UTF-8"));
+ for (String file : dir.list()) {
+ if (file.endsWith(".class")) {
+ String className = packageName + "." + file.replace(".class", "");
+ classInstrumentation(className);
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �w�肵���N���X�ɃC���X�g�D�������e�[�V�������s��
+ *
+ * @param className �N���X��
+ */
+ public static void classInstrumentation(String className) {
+ ClassPool cp = ClassPool.getDefault();
+ CtClass cc;
+ try {
+ cc = cp.get(className);
+ classInstrumentation(cc);
+ } catch (NotFoundException | BadBytecode | CannotCompileException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �w�肵���N���X�ɃC���X�g�D�������e�[�V�������s��
+ *
+ * @param cc Javassist�̃N���X�I�u�W�F�N�g
+ */
+ public static void classInstrumentation(CtClass cc) throws BadBytecode, NotFoundException, CannotCompileException, IOException {
+ for (final CtConstructor c : cc.getDeclaredConstructors()) {
+ methodInstrumentation(cc, c);
+ }
+ for (final CtMethod m : cc.getDeclaredMethods()) {
+ methodInstrumentation(cc, m);
+ }
+ cc.instrument(conv);
+ }
+
+ private static void methodInstrumentation(final CtClass cc, final CtBehavior m) throws BadBytecode, NotFoundException, CannotCompileException {
+ // ���\�b�h�{�̓��̊e�u���b�N�̍ŏ��ɏo�͕���}������(�o�͕��̑}���Ńu���b�N�������Ă��܂��̂ŁA��ɑ}�����Ă���)
+ Block[] blocks = null;
+ if (m instanceof CtMethod && !m.isEmpty()) {
+ ControlFlow cf = new ControlFlow((CtMethod)m);
+ blocks = cf.basicBlocks();
+ for (int i = blocks.length - 1; i >= 0; i--) {
+ int blockPos = m.getMethodInfo().getLineNumber(blocks[i].position());
+ m.insertAt(blockPos, outputStatementsGenerator.generateInsertStatementsForBlockEntry((CtMethod)m, i, blocks[i], blockPos));
+ }
+ }
+
+ // ���\�b�h�{�̓��̃t�B�[���h�A�N�Z�X�ƃ��\�b�h�Ăяo����u��������
+ m.instrument(new ExprEditor() {
+ public void edit(FieldAccess f) throws CannotCompileException {
+ if (f.isReader()) {
+ if (!f.getFieldName().contains("$")) { // AspectJ�ł� final local �ϐ�����̃Q�b�g�͖��������̂ŁA����ɍ��킹�ď��O����
+ f.replace(outputStatementsGenerator.generateReplaceStatementsForFieldGet(cc, m, f, f.getLineNumber()));
+ }
+ } else {
+ if (!f.getFieldName().contains("$")) { // ���̏������Ȃ��ƂȂ���������i�����t�B�[���h?�ւ̃Z�b�g�������āA������E���ė����Ă�?�j
+ f.replace(outputStatementsGenerator.generateReplaceStatementsForFieldSet(cc, f, f.getLineNumber()));
+ }
+ }
+ }
+ public void edit(MethodCall c) throws CannotCompileException {
+ try {
+ CtMethod m = c.getMethod();
+ String className = m.getDeclaringClass().getName();
+ if (!className.startsWith(STANDARD_LIB) && !className.startsWith(TRACER)) {
+ // �ʏ�̃��\�b�h�̌Ăяo��
+ c.replace(outputStatementsGenerator.generateReplaceStatementsForCall(m.getDeclaringClass(), m, c.getLineNumber(), true));
+ } else if (className.matches(STANDARD_CLASSES) && !m.getLongName().matches(EXCEPT_FOR_METHODS)) {
+ // �W���N���X�̃��\�b�h�Ăяo���i�Ăяo����Ƀo�C�g�R�[�h�ߍ��߂Ȃ��j
+ c.replace(outputStatementsGenerator.generateReplaceStatementsForCall(m.getDeclaringClass(), m, c.getLineNumber(), false));
+ }
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ public void edit(NewExpr n) throws CannotCompileException {
+ try {
+ CtConstructor m = n.getConstructor();
+ String className = m.getDeclaringClass().getName();
+ if (!className.startsWith(STANDARD_LIB) && !className.startsWith(TRACER)) {
+ // �ʏ�̃R���X�g���N�^�̌Ăяo��
+ n.replace(outputStatementsGenerator.generateReplaceStatementsForCall(m.getDeclaringClass(), m, n.getLineNumber(), true));
+ } else if (m.getDeclaringClass().getName().matches(CONCRETE_STANDARD_CLASSES)) {
+ // �W���N���X�̃R���X�g���N�^�Ăяo���i�Ăяo����Ƀo�C�g�R�[�h�ߍ��߂Ȃ��j
+ n.replace(outputStatementsGenerator.generateReplaceStatementsForCall(m.getDeclaringClass(), m, n.getLineNumber(), false));
+ }
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ public void edit(NewArray a) throws CannotCompileException {
+ a.replace(outputStatementsGenerator.generateReplaceStatementsForNewArray(a, a.getLineNumber()));
+ }
+// public void edit(ConstructorCall c) throws CannotCompileException {
+// try {
+// CtConstructor m = c.getConstructor();
+// if (m.getDeclaringClass().getName().matches(CONCRETE_STANDARD_CLASSES)) {
+// c.replace(generateReplaceStatementsForCall(m.getDeclaringClass(), m));
+// }
+// } catch (NotFoundException e) {
+// e.printStackTrace();
+// }
+// }
+ });
+
+ // ���\�b�h�p�̏o�͕�������
+ if (!m.isEmpty()) {
+ // ���\�b�h�̎��s�O��ɏo�͕���}������
+ m.insertBefore(outputStatementsGenerator.generateInsertBeforeStatementsForMethodBody(cc, m));
+ m.insertAfter(outputStatementsGenerator.generateInsertAfterStatementsForMethodBody(cc, m));
+ } else {
+ // ���\�b�h�{�̂���̂Ƃ��̓R���X�g���N�^�̏ꍇ�̂�(=�f�t�H���g�R���X�g���N�^)�{�̂ɏo�͕���ݒ肷��
+ if (m instanceof CtConstructor) {
+ m.setBody(outputStatementsGenerator.generateInsertAfterStatementsForMethodBody(cc, m));
+ m.insertBefore(outputStatementsGenerator.generateInsertBeforeStatementsForMethodBody(cc, m));
+ }
+ }
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java
new file mode 100644
index 0000000..e459a71
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/tracer/TracerClassLoader.java
@@ -0,0 +1,45 @@
+package org.ntlab.traceCollector.tracer;
+
+import java.security.ProtectionDomain;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+
+public class TracerClassLoader extends ClassLoader {
+
+ public TracerClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ @Override
+ protected synchronized Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (!Tracer.isInitialized()) Tracer.initialize(new OutputStatementsGenerator(new JSONTraceGenerator())); // �����ŏo�̓t�H�[�}�b�g���w�肷��
+
+ // "java"�Ŏn�܂�p�b�P�[�W�̓V�X�e���n�Ȃ̂Ńf�t�H���g�̃N���X���[�_�[�ɔC����
+ if (name.startsWith("java") || name.startsWith("sun.") || name.startsWith(Tracer.TRACER)) {
+ return super.loadClass(name, resolve);
+ }
+
+ try {
+ // ���[�h�������N���X��Javassist������擾
+ ClassPool classPool = ClassPool.getDefault();
+ CtClass cc = classPool.get(name);
+ if (!cc.isFrozen()) {
+ // �ύX�\�ȂƂ������C���X�g�D�������e�[�V�������s��
+ Tracer.classInstrumentation(cc);
+ }
+
+ // �����̃N���X���[�_�[���w�肵��JavaVM�̃N���X�ɕϊ�
+ ProtectionDomain pd = this.getClass().getProtectionDomain();
+ Class c = cc.toClass(this, pd);
+
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+
+ } catch (Exception e) {
+ return super.loadClass(name, resolve);
+ }
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerLaunchShortcut.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerLaunchShortcut.java
new file mode 100644
index 0000000..51dab40
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerLaunchShortcut.java
@@ -0,0 +1,166 @@
+package org.ntlab.traceCollector.ui;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
+import org.eclipse.jdt.internal.debug.ui.launcher.MainMethodSearchEngine;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+
+public class TracerLaunchShortcut extends org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut {
+
+ /**
+ * �g���|�C���g org.eclipse.debug.core.launchConfigurationTypes �� ID
+ */
+ private static final String LAUNCH_CONFIGURATION_TYPE_ID = "org.ntlab.traceCollector.lunchConfigurationType";
+
+ /**
+ * Returns the Java elements corresponding to the given objects. Members are translated
+ * to corresponding declaring types where possible.
+ *
+ * @param objects selected objects
+ * @return corresponding Java elements
+ * @since 3.5
+ */
+ protected IJavaElement[] getJavaElements(Object[] objects) {
+ List list= new ArrayList(objects.length);
+ for (int i = 0; i < objects.length; i++) {
+ Object object = objects[i];
+ if (object instanceof IAdaptable) {
+ IJavaElement element = (IJavaElement) ((IAdaptable)object).getAdapter(IJavaElement.class);
+ if (element != null) {
+ if (element instanceof IMember) {
+ // Use the declaring type if available
+ IJavaElement type= ((IMember)element).getDeclaringType();
+ if (type != null) {
+ element= type;
+ }
+ }
+ list.add(element);
+ }
+ }
+ }
+ return (IJavaElement[]) list.toArray(new IJavaElement[list.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#createConfiguration(org.eclipse.jdt.core.IType)
+ */
+ protected ILaunchConfiguration createConfiguration(IType type) {
+ ILaunchConfiguration config = null;
+ ILaunchConfigurationWorkingCopy wc = null;
+ try {
+ ILaunchConfigurationType configType = getConfigurationType();
+ wc = configType.newInstance(null, getLaunchManager().generateLaunchConfigurationName(type.getTypeQualifiedName('.')));
+ wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, type.getFullyQualifiedName());
+ wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, type.getJavaProject().getElementName());
+ wc.setMappedResources(new IResource[] {type.getUnderlyingResource()});
+ config = wc.doSave();
+ } catch (CoreException exception) {
+ MessageDialog.openError(JDIDebugUIPlugin.getActiveWorkbenchShell(), LauncherMessages.JavaLaunchShortcut_3, exception.getStatus().getMessage());
+ }
+ return config;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#getConfigurationType()
+ */
+ protected ILaunchConfigurationType getConfigurationType() {
+ return getLaunchManager().getLaunchConfigurationType(LAUNCH_CONFIGURATION_TYPE_ID);
+ }
+
+ /**
+ * Returns the singleton launch manager.
+ *
+ * @return launch manager
+ */
+ private ILaunchManager getLaunchManager() {
+ return DebugPlugin.getDefault().getLaunchManager();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#findTypes(java.lang.Object[], org.eclipse.jface.operation.IRunnableContext)
+ */
+ protected IType[] findTypes(Object[] elements, IRunnableContext context) throws InterruptedException, CoreException {
+ try {
+ if(elements.length == 1) {
+ IType type = isMainMethod(elements[0]);
+ if(type != null) {
+ return new IType[] {type};
+ }
+ }
+ IJavaElement[] javaElements = getJavaElements(elements);
+ MainMethodSearchEngine engine = new MainMethodSearchEngine();
+ int constraints = IJavaSearchScope.SOURCES;
+ constraints |= IJavaSearchScope.APPLICATION_LIBRARIES;
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(javaElements, constraints);
+ return engine.searchMainMethods(context, scope, true);
+ } catch (InvocationTargetException e) {
+ throw (CoreException)e.getTargetException();
+ }
+ }
+
+ /**
+ * Returns the smallest enclosing IType if the specified object is a main method, or null
+ * @param o the object to inspect
+ * @return the smallest enclosing IType of the specified object if it is a main method or null if it is not
+ */
+ private IType isMainMethod(Object o) {
+ if(o instanceof IAdaptable) {
+ IAdaptable adapt = (IAdaptable) o;
+ IJavaElement element = (IJavaElement) adapt.getAdapter(IJavaElement.class);
+ if(element != null && element.getElementType() == IJavaElement.METHOD) {
+ try {
+ IMethod method = (IMethod) element;
+ if(method.isMainMethod()) {
+ return method.getDeclaringType();
+ }
+ }
+ catch (JavaModelException jme) {JDIDebugUIPlugin.log(jme);}
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#getTypeSelectionTitle()
+ */
+ protected String getTypeSelectionTitle() {
+ return LauncherMessages.JavaApplicationLaunchShortcut_0;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#getEditorEmptyMessage()
+ */
+ protected String getEditorEmptyMessage() {
+ return LauncherMessages.JavaApplicationLaunchShortcut_1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaLaunchShortcut#getSelectionEmptyMessage()
+ */
+ protected String getSelectionEmptyMessage() {
+ return LauncherMessages.JavaApplicationLaunchShortcut_2;
+ }
+}
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerLocalJavaApplicationTabGroup.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerLocalJavaApplicationTabGroup.java
new file mode 100644
index 0000000..22145f2
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerLocalJavaApplicationTabGroup.java
@@ -0,0 +1,33 @@
+package org.ntlab.traceCollector.ui;
+
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.EnvironmentTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab;
+
+public class TracerLocalJavaApplicationTabGroup
+ extends org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup {
+
+ /**
+ * @see ILaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String)
+ */
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
+ new JavaMainTab(),
+ new JavaArgumentsTab(),
+ new JavaJRETab(),
+ new JavaClasspathTab(),
+ // new SourceLookupTab(),
+ new EnvironmentTab(),
+ new TracerTab(),
+ new CommonTab()
+ };
+ setTabs(tabs);
+ }
+
+}
\ No newline at end of file
diff --git a/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerTab.java b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerTab.java
new file mode 100644
index 0000000..b17f0f3
--- /dev/null
+++ b/org.ntlab.traceCollector/src/org/ntlab/traceCollector/ui/TracerTab.java
@@ -0,0 +1,81 @@
+package org.ntlab.traceCollector.ui;
+
+import java.lang.reflect.InvocationTargetException;
+
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.internal.ui.SWTFactory;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
+import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.internal.debug.ui.launcher.DebugTypeSelectionDialog;
+import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
+import org.eclipse.jdt.internal.debug.ui.launcher.MainMethodSearchEngine;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Image;
+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.Group;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+
+public class TracerTab extends org.eclipse.debug.ui.AbstractLaunchConfigurationTab {
+
+ private static final String TAB_NAME = "Tracer Settings";
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite composite =
+ SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_BOTH);
+
+ ((GridLayout)composite.getLayout()).verticalSpacing = 0;
+
+ }
+
+ private Group createGroup(Composite parent, String title) {
+ return SWTFactory.createGroup(parent, title, 2, 1, GridData.FILL_HORIZONTAL);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String getName() {
+ return TAB_NAME;
+ }
+
+}