package com.iggroup.oss.restdoclet.web; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.log4j.Logger; /** * File upload servlet which accepts RESTDoclet generated config jars via POST * and extracts them to a location specified in the POST header. */ public class FileUploadServlet extends HttpServlet { /** * The POST header key specifying the target deployment folder on the web * server */ private static final String RESTDOCLET_DEPLOY = "RESTDOCLET_DEPLOY"; /** * The logger */ private static final Logger LOG = Logger.getLogger(FileUploadServlet.class); private static String configPath; { configPath = System.getenv("RESTDOCLET_DEPLOY"); } /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) * */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.print("Not supported"); } /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) * * This method accepts a jar and extracts to a location specified by the header key RESTDOCLET_DEPLOY */ @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String deploySubDir = request.getHeader(RESTDOCLET_DEPLOY); String deployDir = configPath + File.separator + deploySubDir; File dir = new File(deployDir); deleteDir(dir); if (ServletFileUpload.isMultipartContent(request)) { try { LOG.info("Upload request to " + deployDir); List<FileItem> fileItems = new ServletFileUpload(new DiskFileItemFactory(1024 * 1024, dir)) .parseRequest(request); for (FileItem item : fileItems) { if (item != null) { LOG.debug(item.getName()); JarInputStream jis = new JarInputStream(item.getInputStream()); JarEntry jarEntry; while ((jarEntry = jis.getNextJarEntry()) != null) { extract(jis, jarEntry, deployDir); } } } } catch (Exception e) { LOG.error("Failed to upload to " + configPath, e); } } } /** * Delete the specified directory * * @param dir directory to delete * @return true if the operation succeeded, otherwise return false */ private static boolean deleteDir(File dir) { if (dir.exists()) { LOG.debug("Deleting " + dir); if (dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { LOG.error("Failed to delete " + dir); return false; } } } return dir.delete(); } return false; } /** * Extract a jar entry from a a jar * * @param jin jar input stream * @param e the jar entry to extract * @param dir the location to which to extract the jar entry * @throws IOException something unexpected happened */ private static void extract(JarInputStream jin, JarEntry e, String dir) throws IOException { LOG.debug("Extracting " + e.getName() + " to " + dir); File f = new File(dir + File.separatorChar + e.getName().replace('/', File.separatorChar)); if (e.isDirectory()) { if (!f.exists() && !f.mkdirs() || !f.isDirectory()) { throw new IOException(f + ": could not create directory"); } } else { if (f.getParent() != null) { File d = new File(f.getParent()); if (!d.exists() && !d.mkdirs() || !d.isDirectory()) { throw new IOException(d + ": could not create directory"); } } OutputStream os = new FileOutputStream(f); byte[] b = new byte[512]; int len; while ((len = jin.read(b, 0, b.length)) != -1) { os.write(b, 0, len); } jin.closeEntry(); os.close(); } } }