package er.profiling;
import java.text.DecimalFormat;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.webobjects.appserver.WOApplication;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WOElement;
import com.webobjects.appserver.WORequest;
import com.webobjects.appserver.WORequestHandler;
import com.webobjects.appserver.WOResponse;
import com.webobjects.eoaccess.EOSQLExpression;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.foundation.NSArray;
import er.profiling.delegates.PFHeatMap;
public class PFProfilerRequestHandler extends WORequestHandler {
public PFProfilerRequestHandler() {
}
protected void appendSingleNodeStatsToResponse(PFStatsNode stats, WOResponse response, WOContext context, float minimumPercentage, Set<String> filters,
Set<PFStatsNode> renderedStats, boolean tree) {
if (tree && filters != null && stats.parentStats() != null && !renderedStats.contains(stats.parentStats())) {
appendSingleNodeStatsToResponse(stats.parentStats(), response, context, minimumPercentage, filters, renderedStats, tree);
}
if (tree) {
int depth = stats.depth();
for (int i = 0; i < depth; i++) {
if (i == depth - 1) {
response.appendContentString("+-");
} else {
response.appendContentString("| ");
}
}
}
if (stats.hasErrors()) {
response.appendContentString("<font color=\"red\">");
}
else if (stats.isImportant()) {
response.appendContentString("<font color=\"black\">");
}
response.appendContentString("[" + String.format("%5.2f", stats.durationMillis()) + "ms / " + DecimalFormat.getPercentInstance().format(stats.percentage()) + "] ");
response.appendContentString(stats.name());
if (stats.type() != null) {
response.appendContentString(" (" + stats.type() + ")");
}
if (stats.hasErrors()) {
for (String error : stats.errors()) {
response.appendContentString(" <b>" + error + "</b> ");
}
}
Object target = stats.target();
if (target instanceof WORequest) {
response.appendContentString(": " + ((WORequest) target).uri());
} else if (target instanceof WOElement) {
response.appendContentString(": " + ((WOElement) target).getClass().getSimpleName());
} else if (target instanceof EOSQLExpression) {
response.appendContentString(": " + ((EOSQLExpression) target).statement());
} else if (target instanceof EOFetchSpecification) {
response.appendContentString(": entity=" + ((EOFetchSpecification) target).entityName() + ", qualifier=" + ((EOFetchSpecification) target).qualifier());
} else {
response.appendContentString(": " + target);
}
if (stats.counters() != null) {
response.appendContentString(", ");
response.appendContentString(stats.counters().toString());
}
if (stats.hasErrors()) {
response.appendContentString("</font>");
}
else if (stats.isImportant()) {
response.appendContentString("</font>");
}
response.appendContentString("\n");
renderedStats.add(stats);
}
protected void appendNodesStatsToResponse(PFStatsNode stats, WOResponse response, WOContext context, float minimumPercentage, Set<String> filters,
Set<PFStatsNode> renderedStats, boolean tree) {
if (stats != null) {
if ((filters == null || filters.contains(stats.name())) && stats.isAtLeastPercentage(minimumPercentage)) {
appendSingleNodeStatsToResponse(stats, response, context, minimumPercentage, filters, renderedStats, tree);
}
List<PFStatsNode> children = stats.children();
if (children != null) {
for (PFStatsNode child : children) {
appendNodesStatsToResponse(child, response, context, minimumPercentage, filters, renderedStats, tree);
}
}
}
}
@Override
public WOResponse handleRequest(WORequest request) {
WOContext context = WOApplication.application().createContextForRequest(request);
WOResponse response = WOApplication.application().createResponseInContext(context);
String requestPath = request.requestHandlerPath();
if ("heat".equals(requestPath)) {
PFHeatMap.setHeatEnabled(!PFHeatMap.isHeatEnabled());
response.appendContentString("<script>window.close();</script>");
} else {
String id = request.stringFormValueForKey("id");
PFStatsNode stats = PFProfiler.statsWithID(id);
response.appendContentString("<html><body>");
response.appendContentString("<pre style=\"color: grey\">");
if (stats == null) {
response.appendContentString("Unknown stats id #" + stats);
} else {
String filter = request.stringFormValueForKey("filter");
Set<String> filters = null;
if (filter != null) {
filters = new HashSet<>();
NSArray filterNamesArray = NSArray.componentsSeparatedByString(filter, ",");
Enumeration filterNamesEnum = filterNamesArray.objectEnumerator();
while (filterNamesEnum.hasMoreElements()) {
Object filterName = filterNamesEnum.nextElement();
filters.add((String) filterName);
}
}
float minimumPercentage = 0.0f;
String minimumPercentageStr = request.stringFormValueForKey("min");
if (minimumPercentageStr != null) {
minimumPercentage = Float.parseFloat(minimumPercentageStr);
}
boolean tree = "tree".equals(requestPath);
PFStatsChecker.checkForErrors(stats);
appendNodesStatsToResponse(stats, response, context, minimumPercentage, filters, new HashSet<>(), tree);
}
response.appendContentString("</pre>");
response.appendContentString("</body></html>");
}
return response;
}
}