/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.profiler.web.servlets;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.RequestDispatcher;
import org.jboss.profiler.engine.TracerEngine;
import org.jboss.profiler.engine.RunnerEvent;
import org.jboss.profiler.engine.RunnerEventListener;
import org.jboss.profiler.fileProcessor.SpyReader;
import org.jboss.profiler.web.form.FilterForm;
import org.jboss.profiler.model.*;
import java.util.*;
/**
* @author Yoko Seki (y-seki@sdl.hitachi.co.jp)
*/
public class ServletTracer extends HttpServlet
{
PrintWriter out;
boolean processedFiles;
String startMethod;
int startMethodID;
private static final String CONTENT_TYPE = "text/html";
//Initialize global variables
public void init() throws ServletException {
}
protected static StreamHolder openStream (File file) throws IOException {
FileInputStream fileInput = new FileInputStream(file);
InputStream input = null;
if (file.getName().endsWith(".gz")) {
input = new java.util.zip.GZIPInputStream(fileInput);
} else {
input=fileInput;
}
return new StreamHolder(fileInput, input);
}
//Process the HTTP Get request
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
//Process the HTTP Get request
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
//PrintWriter out = response.getWriter();
out = response.getWriter();
try {
HttpSession session = request.getSession();
FilterForm form = (FilterForm)session.getAttribute("filterForm");
org.jboss.profiler.model.JBPProcess spyProcess
= (org.jboss.profiler.model.JBPProcess) form.getJbpProcess();
if ( !(request.getParameter("methodList")).equals("") )
{
processedFiles = request.getParameter("processedFiles")!=null;
startMethodID = Integer.parseInt(request.getParameter("methodList"));
HashMap processMethods = spyProcess.getSpyMethods();
Iterator iter = processMethods.values().iterator();
JBPMethod method = new JBPMethod();
while (iter.hasNext())
{
method = (JBPMethod) iter.next();
if (method.getMethodID()==startMethodID)
{
startMethod = method.getFullName();
break;
}
}
doTrace(form);
}
else if (!(request.getParameter("methodText")).equals(""))
{
startMethod = request.getParameter("methodText");
HashMap processMethods = spyProcess.getSpyMethods();
Iterator iter = processMethods.values().iterator();
HashMap methodMap = new HashMap ();
JBPMethod currentMethod = new JBPMethod();
while (iter.hasNext())
{
currentMethod = (JBPMethod) iter.next();
if ((currentMethod.getFullName()).indexOf(startMethod)>=0)
methodMap.put(new Integer(currentMethod.getMethodID()), (String) currentMethod.getFullName());
}
int methodNum = methodMap.size();
if (methodNum==1)
{
processedFiles = request.getParameter("processedFiles")!=null;
Iterator iter2 = methodMap.keySet().iterator();
Integer hashKey = (Integer) iter2.next();
startMethodID = hashKey.intValue();
startMethod = (String) methodMap.get((Integer)hashKey);
doTrace(form);
}
else if (methodNum==0)
{
out.println("<font size=\"+2\">No methods match the method name. Try again.</font>");
}
else if (methodNum>1)
{
processedFiles = request.getParameter("processedFiles")!=null;
out.println("<form action=\"./JBTTransaction\" method=\"get\"><table align=center><tbody>");
out.println("<tr><td align=center><b>" +
"More than one methods match the method name.<br>" +
"Select a method from the list below.</b></td></tr>");
out.println("<tr><td align=center><SELECT name=\"methodList\">");
Iterator iter3 = methodMap.keySet().iterator();
while (iter3.hasNext())
{
Integer listKey = (Integer) iter3.next();
int listMethodID = listKey.intValue();
String listMethod = (String) methodMap.get((Integer)listKey);
out.println("<OPTION VALUE=\"" + String.valueOf(listMethodID) + "\">" +
listMethod + "</OPTION>");
}
out.println("</SELECT></td></tr>");
if (processedFiles)
{
out.println("<input type=\"hidden\" name=\"processedFiles\" value=\"processedFlies\">");
}
out.println("<tr><td align=center><INPUT TYPE=\"submit\" name=\"Execute\" value=\"Submit\">");
out.println("</td></tr>");
out.println("</tbody></table></form>");
}
}
else
{
out.println("<font size=\"+2\">");
out.println("you didn't designate any method...");
out.println( "Tray again.");
out.println("</font>");
}
}
catch (Throwable e) {
e.printStackTrace(out);
e.printStackTrace(System.out);
}
}
protected void doTrace (FilterForm form) throws IOException
{
String directory = form.getDirectory();
String pid = form.getSelectedPID();
File fileDirectory = new File(directory);
File[] mainFile = fileDirectory.listFiles(new SPYFilterMain(pid));
out.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"./imgs/cssdef.css\">");
File[] files = fileDirectory.listFiles(new SPYFilterThread(pid));
StreamHolder mainStream = openStream(mainFile[0]);
InputStream[] paramStreams = new InputStream[files.length];
StreamHolder[] holders = new StreamHolder[files.length];
// total number of bytes to be processed
long totalLength=mainFile[0].length();
for (int i=0;i<files.length;i++) {
if (processedFiles)
out.println("<br>Opening "+ files[i].getAbsolutePath());
holders[i] = openStream(files[i]);
paramStreams[i] = holders[i].inputStream;
totalLength += files[i].length();
}
out.flush();
SpyReader reader = new SpyReader(mainStream.inputStream,paramStreams);
TracerEngine engine = new TracerEngine(reader);
ProcessListener listener = new ProcessListener(mainStream, holders, out, totalLength);
engine.addRunnerEventListener(listener);
org.jboss.profiler.model.JBPProcess spyProcess
= (org.jboss.profiler.model.JBPProcess) form.getJbpProcess();
engine.targetMethodID = startMethodID;
engine.doTrace(pid,spyProcess); // nao gera output com os arquivos html.gz
form.setJbtTransactions(engine.getCompleteTransactions());
form.setJbtiTransactions(engine.getIncompleteTransactions());
form.setStartMethod(startMethod);
for (int i=0;i<paramStreams.length;i++) {
paramStreams[i].close();
}
mainStream.inputStream.close();
out.println("<br><b><font size=6>Trace Finished.... <a href=\"./transactionViewer.jsp?initial=yes\">click here</a></font></b>");
out.println("</body></html>");
}
//Clean up resources
public void destroy() {
}
class SPYFilterThread implements FilenameFilter {
String pid;
public SPYFilterThread(String pid) {
this.pid=pid;
}
public boolean accept(File file, String name){
return name.startsWith("serverspy_"+pid+"_thread");
}
}
class SPYFilterMain implements FilenameFilter {
String pid;
public SPYFilterMain(String pid) {
this.pid=pid;
}
public boolean accept(File file, String name){
return name.startsWith("serverspy_"+pid+"_main");
}
}
static class ProcessListener implements RunnerEventListener {
PrintWriter out;
StreamHolder mainInput;
StreamHolder [] inputs;
// number of bytes to be processed on GZipFiles
long totalBytes;
public ProcessListener (StreamHolder mainInput, StreamHolder[] inputs, PrintWriter out, long totalBytes) {
this.mainInput = mainInput;
this.inputs=inputs;
this.out=out;
this.totalBytes = totalBytes;
}
protected long calcCurrentPosition() {
try {
int currentPosition=mainInput.fileInputStream.available();
for (int i=0;i<inputs.length;i++) {
currentPosition+=inputs[i].fileInputStream.available();
}
return totalBytes-currentPosition;
}
catch (Exception e) {
out.println("Error -> <b>" + e.toString() + "</b>");
e.printStackTrace(System.out);
return 0;
}
}
protected long calcPercentage() {
long currentPos = calcCurrentPosition();
if (currentPos==0) return 0;
else {
return (int)(((double)currentPos/(double)totalBytes)*100);
}
}
public void processTick(RunnerEvent e) {
out.println("<br><b>Processed " + e.getCurrentRegister() +" registers (" + calcPercentage() + "%)</b>");
System.out.println("Processed " + e.getCurrentRegister() +" registers (" + calcPercentage() + "%)");
out.flush();
}
public void processWarning(int line, String e) {
System.out.println("<br> Error line " + line + "<i> " + e + "</i>");
}
}
}
/** Inner class that will be used to open Streams*/
/*
class StreamHolder {
public StreamHolder(FileInputStream fileInputStream, InputStream inputStream) {
this.fileInputStream=fileInputStream;
this.inputStream = inputStream;
}
FileInputStream fileInputStream;
InputStream inputStream;
}
*/