/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.tools.xjc.servlet.reaper;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Launches {@link Compiler} from the form input.
*
* @author
* Ryan Shoemaker
*/
public class DiskManagerServlet extends HttpServlet {
// each compiler session will have a tmp directory whose name
// begins with this string
static final String SESSION_DIR_PREFIX = "jaxbOnTheWeb";
// session directories will be considered "stale" when their
// last modification time is more than this many milliseconds
// ago.
public static final long TIMEOUT = 1000 * 60 * 60;
// the background thread that periodically wakes up and looks
// for disk space to reclaim.
private static Reaper reaperThread;
// this is the root output directory for all client sessions
private static File rootTmpDir;
// text used for the reset button and parameter name
private static final String RESET_BUTTON = "Reset";
/**
* Allocates a new temporary directory for anyone who needs
* time-limited quota-controlled disk storage area.
*/
public synchronized static File createOutDir() throws IOException {
File outDir = File.createTempFile(SESSION_DIR_PREFIX, "");
outDir.delete();
// to avoid another thread from stealing the unique name when one thread
// is here, this method is made synchronized.
outDir.mkdir();
return outDir;
}
/* (non-Javadoc)
* @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
// get the root tmp dir
File tmpFile = File.createTempFile("foo", "");
rootTmpDir = tmpFile.getParentFile();
tmpFile.delete();
// create
reaperThread = new Reaper();
reaperThread.setPriority(Thread.MIN_PRIORITY);
reaperThread.start();
} catch (IOException ioe) {
throw new ServletException(ioe);
}
}
/* (non-Javadoc)
* @see javax.servlet.Servlet#destroy()
*/
public void destroy() {
super.destroy();
// cleanup the disk
deleteAllTmpStorage();
// kill the reaper thread
reaperThread.destroy();
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doIt(request, response);
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void doPost(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doIt(request, response);
}
private static int hits = 0;
private void doIt(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String value = request.getParameter(RESET_BUTTON);
if (value != null) {
// we don't care about the value
deleteAllTmpStorage();
}
// cause the reaper thread to calculate the latest stats
reaperThread.update();
// TODO: format report
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(
"<html><body><h3>DiskManager,v1.22," + ++hits + "</h3>\n"
+ "<p>Tmp dir: "
+ reaperThread.getTmpDir()
+ "\n"
+ "<p>Last reap reclaimed: "
+ reaperThread.getReapedSpace()
+ "b\n"
+ "<p>Current disk usage: "
+ reaperThread.getDiskUsage()
+ "b\n"
+ generateResetButton()
+ "\n<hr>"
+ dumpParams( request )
+ "</body></html>");
}
/**
* @param request
* @return
*/
private String dumpParams(HttpServletRequest request) {
StringBuffer params = new StringBuffer();
params.append( "<h3>params</h3>");
for( Enumeration e = request.getParameterNames(); e.hasMoreElements(); ) {
String param = (String)e.nextElement();
params.append( "name: " + param + " value: " + request.getParameter( param ) + "<br>\n" );
}
return params.toString();
}
/**
* generate the html code for the "reset" button.
*
* @return the button code
*/
private String generateResetButton() {
StringBuffer resetCode = new StringBuffer();
resetCode.append("<p>");
resetCode.append("\tClick the 'reset' button to completely erase all tmp JAXB files\n");
// resetCode.append("\t<form method=\"post\" action=\"diskmanager?" + RESET_BUTTON + "=true\">\n");
resetCode.append("\t<form method=\"post\" action=\"diskmanager\">\n");
resetCode.append("\t\t<input type=\"SUBMIT\" name=\"" + RESET_BUTTON + "\" value=\"" + RESET_BUTTON + "\">\n");
resetCode.append("\t</form>\n");
resetCode.append("</p>\n");
return resetCode.toString();
}
/**
* Accessor for the root directory containing all of the tmp files.
*
* @return the root tmp directory
*/
public static File getRootTmpDir() {
return rootTmpDir;
}
/**
* causes all temp storage to be deleted. This method is called when
* someone clicks the "reset" button in the DiskManager page and when
* the destroy method is invoked.
*/
private void deleteAllTmpStorage() {
reaperThread.deleteAll();
}
}