package org.intrace.output;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.intrace.agent.server.AgentClientConnection;
/**
* Static implementation of the {@link IInstrumentationHandler} interface
*/
public class AgentHelper
{
// Instrumentation handler
private static IInstrumentationHandler instrumentationHandler;
public static void setInstrumentationHandler(IInstrumentationHandler handler)
{
instrumentationHandler = handler;
}
// Output Settings
private static OutputSettings outputSettings = new OutputSettings("");
public static OutputSettings getOutputSettings()
{
return outputSettings;
}
// Set of active network output threads
private static final Map<NetworkDataSenderThread, Object> networkOutputThreads = new ConcurrentHashMap<NetworkDataSenderThread, Object>();
/**
* @param connection
* @param agentArgs
* @return A List of responses from all of the {@link IInstrumentationHandler}
* s and the {@link AgentHelper} itself.
*/
public static List<String> getResponses(AgentClientConnection connection, String agentArgs)
{
List<String> responses = new ArrayList<String>();
// Get the response from the AgentHelper
String response = getResponse(connection, agentArgs);
if (response != null)
{
responses.add(response);
}
// Get responses from all of the IInstrumentationHandlers
if (instrumentationHandler != null)
{
response = instrumentationHandler.getResponse(agentArgs);
if (response != null)
{
responses.add(response);
}
}
return responses;
}
/**
* @param connection
* @param args
* @return The response to the given args or null if no response is required.
* The only response currently implemented is sending back the local
* port for a new network data connection.
*/
private static String getResponse(AgentClientConnection connection, String args)
{
// OutputSettings oldSettings = new OutputSettings(outputSettings);
outputSettings.parseArgs(args);
// if ((oldSettings.isStdoutOutputEnabled() != outputSettings.isStdoutOutputEnabled())
// || (oldSettings.isFileOutputEnabled() != outputSettings
// .isFileOutputEnabled())
// || (oldSettings.isNetOutputEnabled() != outputSettings
// .isNetOutputEnabled()))
// {
//// System.out.println("## Trace Settings Changed");
// }
if (outputSettings.networkTraceOutputRequested)
{
if ((connection == null) || !connection.isTraceConnEstablished())
{
ServerSocket networkSocket;
try
{
networkSocket = new ServerSocket(0);
NetworkDataSenderThread networkOutputThread = new NetworkDataSenderThread(connection,
networkSocket);
networkOutputThread.start(networkOutputThreads);
outputSettings.networkTraceOutputRequested = false;
return Integer.toString(networkSocket.getLocalPort());
}
catch (IOException e)
{
// Do nothing
return null;
}
}
else
{
// System.out.println("## Network Output Already Connected");
return null;
}
}
else
{
return null;
}
}
/**
* @return All of the currently active settings for the {@link AgentHelper}
* along with all of the active {@link IInstrumentationHandler}s
*/
public static Map<String, String> getSettings()
{
Map<String, String> settings = new HashMap<String, String>();
settings.putAll(outputSettings.getSettingsMap());
if (instrumentationHandler != null)
{
settings.putAll(instrumentationHandler.getSettingsMap());
}
return settings;
}
/**
* Write data output to all network data connections.
*
* @param xiTrace
*/
public static void writeDataOutput(Object xiOutput)
{
Set<NetworkDataSenderThread> networkThreads = networkOutputThreads.keySet();
if (networkThreads.size() > 0)
{
for (NetworkDataSenderThread thread : networkThreads)
{
thread.queueData(xiOutput);
}
}
}
/**
* Allow any network output to gracefully shutdown
*/
public static void gracefulShutdown()
{
Set<NetworkDataSenderThread> networkThreads = networkOutputThreads.keySet();
if (networkThreads.size() > 0)
{
for (NetworkDataSenderThread thread : networkThreads)
{
thread.gracefulShutdown();
}
}
}
public static final CriticalBlock INSTRU_CRITICAL_BLOCK = new CriticalBlock();
private static class CriticalBlock implements Thread.UncaughtExceptionHandler
{
@Override
public void uncaughtException(Thread t, Throwable e)
{
// Do nothing
}
}
public static void enter(String className, String methodName, int lineNo)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.enter(className, methodName, lineNo);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
byte byteArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, byteArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
byte[] byteArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, byteArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
short shortArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, shortArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
short[] shortArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, shortArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
int intArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, intArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
int[] intArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, intArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
long longArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, longArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
long[] longArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, longArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
float floatArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, floatArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
float[] floatArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, floatArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
double doubleArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, doubleArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
double[] doubleArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, doubleArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
boolean boolArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, boolArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
boolean[] boolArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, boolArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
char charArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, charArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
char[] charArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, charArrayArg);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
Object objArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
try
{
instrumentationHandler.val(desc, className, methodName, objArg);
}
catch (Throwable th)
{
instrumentationHandler.val(desc, className, methodName, "<InTrace: Exception thrown from toString() on Object arg: " + th.toString() + ">");
}
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
Object[] objArrayArg)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
try
{
instrumentationHandler.val(desc, className, methodName, objArrayArg);
}
catch (Throwable th)
{
instrumentationHandler.val(desc, className, methodName, "<Exception thrown: " + th.toString() + ">");
}
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void val(String desc, String className, String methodName,
int lineNo, Throwable throwable)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.val(desc, className, methodName, lineNo, throwable);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void branch(String className, String methodName, int lineNo)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.branch(className, methodName, lineNo);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
public static void exit(String className, String methodName, int lineNo)
{
Thread currentTh = Thread.currentThread();
UncaughtExceptionHandler handler = currentTh.getUncaughtExceptionHandler();
if (handler != INSTRU_CRITICAL_BLOCK)
{
// Allow instrumentation call to proceed
currentTh.setUncaughtExceptionHandler(INSTRU_CRITICAL_BLOCK);
try
{
if (instrumentationHandler != null)
{
instrumentationHandler.exit(className, methodName, lineNo);
}
}
finally
{
currentTh.setUncaughtExceptionHandler(handler);
}
}
}
}