/*
* 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 org.jboss.profiler.engine.LogFileEngine;
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;
/**
@author Clebert Suconic
*/
public class ServletProcess extends HttpServlet{
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();
try {
HttpSession session = request.getSession();
FilterForm form = (FilterForm)session.getAttribute("filterForm");
if (form==null || form.getDirectory()==null) {
form = new FilterForm();
form.setMessage("Directory is null");
session.setAttribute("filterForm",form);
response.sendRedirect("./mainMenu.jsp");
}
// flags de processamento
boolean detailedOutput = request.getParameter("detailedOutput")!=null;
boolean methodStack = request.getParameter("methodsStack")!=null;
boolean objectsStack = request.getParameter("objectsStack")!=null;
boolean useIteractionsOnOutput = request.getParameter("useIteractionsOnOutput")!=null;
boolean processReleaseObjects = request.getParameter("releaseObjects")!=null;
String directory = form.getDirectory();
String pid = request.getParameter("selectedPID");
form.setSelectedPID(pid);
File fileDirectory = new File(directory);
if (!fileDirectory.isDirectory()) {
form.setMessage(directory + " isn't a directory");
response.sendRedirect("./errorSelection.jsp");
return;
}
File[] mainFile = fileDirectory.listFiles(new SPYFilterMain(pid));
if (mainFile.length==0) {
form.setMessage("PID Main File not found");
response.sendRedirect("./errorSelection.jsp");
return;
}
if (mainFile.length>1) {
form.setMessage("Cannot process more than one file");
response.sendRedirect("./errorSelection.jsp");
return;
}
out.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"./imgs/cssdef.css\">");
out.println("<html><head><title>Processing PID " + request.getParameter("selectedPID") + "</title></head><body>");
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++) {
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);
LogFileEngine engine = new LogFileEngine(reader);
ProcessListener listener = new ProcessListener(mainStream, holders, out, totalLength);
engine.addRunnerEventListener(listener);
engine.setOutputDirectory(fileDirectory);
engine.setProcessStackOnObjects(objectsStack);
engine.setProcessStackOnMethods(methodStack);
engine.setUseIteractionsOnOutput(useIteractionsOnOutput);
engine.setProcessReleaseOnObjects(processReleaseObjects);
String methodSignature = request.getParameter("methodSignature");
if (methodSignature!=null && methodSignature.trim().length()>0) {
engine.addDetailMethod(methodSignature); // voltar
}
if (detailedOutput) System.out.println("using detailedOutput");
engine.doProcess(detailedOutput,pid); // nao gera output com os arquivos html.gz
form.setJbpProcess(engine.getProcess());
for (int i=0;i<paramStreams.length;i++) {
paramStreams[i].close();
}
mainStream.inputStream.close();
out.println("<br><b><font size=6>Process Finished.... <a href=\"./processMethods.jsp\">click here</a></font></b>");
out.println("</body></html>");
}
catch (Throwable e) {
e.printStackTrace(out);
e.printStackTrace(System.out);
}
}
//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;
}