Java tutorial
/** * Project Wonderland * * Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved * * Redistributions in source code form must reproduce the above * copyright and this condition. * * The contents of this file are subject to the GNU General Public * License, Version 2 (the "License"); you may not use this file * except in compliance with the License. A copy of the License is * available at http://www.opensource.org/licenses/gpl-license.php. * * Sun designates this particular file as subject to the "Classpath" * exception as provided by Sun in the License file that accompanied * this code. */ package org.jdesktop.wonderland.modules.contentrepo.web.servlet; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.jdesktop.wonderland.front.admin.AdminRegistration; import org.jdesktop.wonderland.modules.contentrepo.common.ContentCollection; import org.jdesktop.wonderland.modules.contentrepo.common.ContentNode; import org.jdesktop.wonderland.modules.contentrepo.common.ContentRepositoryException; import org.jdesktop.wonderland.modules.contentrepo.common.ContentResource; import org.jdesktop.wonderland.modules.contentrepo.web.spi.WebContentRepository; import org.jdesktop.wonderland.modules.contentrepo.web.spi.WebContentRepositoryRegistry; import org.jdesktop.wonderland.utils.RunUtil; /** * * @author jkaplan */ public class BrowserServlet extends HttpServlet implements ServletContextListener { private static final Logger logger = Logger.getLogger(BrowserServlet.class.getName()); private AdminRegistration ar; /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext sc = getServletContext(); // get the repository WebContentRepositoryRegistry reg = WebContentRepositoryRegistry.getInstance(); WebContentRepository wcr = reg.getRepository(sc); if (wcr == null) { error(request, response, "No content repositories found. <br>" + "Please contact your system administrator for assistance."); return; } try { ContentNode node = translatePath(wcr, request.getPathInfo()); if (node == null) { error(request, response, "Path " + request.getPathInfo() + " not found."); return; } String action = request.getParameter("action"); if (action == null && ServletFileUpload.isMultipartContent(request)) { action = "upload"; } if (action != null) { node = handleAction(request, response, node, action); if (node == null) { // indicates that the action has handled forwarding on // its own, for example to the error page return; } } DirectoryEntry current = new DirectoryEntry(node); request.setAttribute("current", current); if (node instanceof ContentCollection) { handleCollection(request, response, (ContentCollection) node); } else if (node instanceof ContentResource) { handleResource(request, response, (ContentResource) node); } else { error(request, response, "Unknown node type " + node.getClass()); } } catch (ContentRepositoryException cre) { throw new ServletException(cre); } } protected void error(HttpServletRequest request, HttpServletResponse response, String message) throws ServletException, IOException { request.setAttribute("message", message); RequestDispatcher rd = getServletContext().getRequestDispatcher("/error.jsp"); rd.forward(request, response); } protected ContentNode translatePath(WebContentRepository wcr, String path) throws ContentRepositoryException { // find the root (system or users) ContentCollection root = null; if (path == null || path.equals("/")) { root = wcr.getRoot(); } else if (path.startsWith("/system")) { path = path.substring("/system".length()); root = wcr.getSystemRoot(); } else if (path.startsWith("/users/")) { path = path.substring("/users/".length()); String userId = path; int endIdx = path.indexOf("/"); if (endIdx != -1) { userId = path.substring(0, endIdx); path = path.substring(endIdx); } else { path = null; } root = wcr.getUserRoot(userId); } else { root = wcr.getRoot(); } if (root == null) { return null; } if (path == null || path.length() == 0 || path.equals("/")) { return root; } return root.getChild(path); } protected ContentNode handleAction(HttpServletRequest request, HttpServletResponse response, ContentNode node, String action) throws ServletException, IOException, ContentRepositoryException { if (action.equalsIgnoreCase("mkdir")) { return handleMkdir(request, response, node, action); } else if (action.equalsIgnoreCase("delete")) { return handleDelete(request, response, node, action); } else if (action.equalsIgnoreCase("upload")) { return handleUpload(request, response, node, action); } else { // do nothing return node; } } protected ContentNode handleMkdir(HttpServletRequest request, HttpServletResponse response, ContentNode node, String action) throws ServletException, IOException, ContentRepositoryException { String dirName = request.getParameter("dirname"); if (dirName == null || dirName.trim().length() == 0) { error(request, response, "Invalid name"); return null; } if (!(node instanceof ContentCollection)) { error(request, response, "Not a directory"); return null; } ((ContentCollection) node).createChild(dirName, ContentNode.Type.COLLECTION); return node; } protected ContentNode handleDelete(HttpServletRequest request, HttpServletResponse response, ContentNode node, String action) throws ServletException, IOException, ContentRepositoryException { ContentCollection parent = node.getParent(); if (parent == null) { error(request, response, "Cannot delete top-level node."); return null; } parent.removeChild(node.getName()); return parent; } protected ContentNode handleUpload(HttpServletRequest request, HttpServletResponse response, ContentNode node, String action) throws ServletException, IOException, ContentRepositoryException { if (!(node instanceof ContentCollection)) { error(request, response, "Not a directory"); return null; } ContentCollection dir = (ContentCollection) node; /* Check that we have a file upload request */ boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart == false) { logger.warning("[Runner] UPLOAD Bad request"); String message = "Unable to recognize upload request. Please " + "try again."; response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); return null; } // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(); // Parse the request try { FileItemIterator iter = upload.getItemIterator(request); while (iter.hasNext() == true) { FileItemStream item = iter.next(); String name = item.getName(); InputStream stream = item.openStream(); if (item.isFormField() == false) { ContentResource child = (ContentResource) dir.createChild(name, ContentNode.Type.RESOURCE); File tmp = File.createTempFile("contentupload", "tmp"); RunUtil.writeToFile(stream, tmp); child.put(tmp); tmp.delete(); } } return node; } catch (FileUploadException excp) { /* Log an error to the log and write an error message back */ logger.log(Level.WARNING, "[Runner] UPLOAD Failed", excp); String message = "Unable to upload runner for some reason."; response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); return null; } catch (IOException excp) { /* Log an error to the log and write an error message back */ logger.log(Level.WARNING, "[Runner] UPLOAD Failed", excp); String message = "Unable to upload runner for some reason."; response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); return null; } } protected void handleCollection(HttpServletRequest request, HttpServletResponse response, ContentCollection c) throws ServletException, IOException, ContentRepositoryException { // set the path of this collection request.setAttribute("path", c.getPath()); Collection<DirectoryEntry> entries = new ArrayList<DirectoryEntry>(); for (ContentNode child : c.getChildren()) { DirectoryEntry de = new DirectoryEntry(child); switch (de.getType()) { case DIRECTORY: de.addAction(new DirectoryAction("delete", "delete")); break; case FILE: de.addAction(new DirectoryAction("delete", "delete")); break; } entries.add(de); } request.setAttribute("entries", entries); RequestDispatcher rd = getServletContext().getRequestDispatcher("/browse.jsp"); rd.forward(request, response); } protected void handleResource(HttpServletRequest request, HttpServletResponse response, ContentResource r) throws ServletException, IOException, ContentRepositoryException { // set the type String mimeType = getServletContext().getMimeType(r.getName()); if (mimeType == null) { mimeType = "application/octet-stream"; } response.setContentType(mimeType); if (r.getSize() > 0) { response.setContentLength((int) r.getSize()); } // write the data InputStream is = r.getInputStream(); byte[] buffer = new byte[16 * 1024]; int read; while ((read = is.read(buffer)) > 0) { response.getOutputStream().write(buffer, 0, read); } response.getOutputStream().close(); } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> public void contextInitialized(ServletContextEvent sce) { // register with the admininstration page ServletContext sc = sce.getServletContext(); ar = new AdminRegistration("Manage Content", "/content-repository/wonderland-content-repository/browse"); ar.setFilter(AdminRegistration.ADMIN_FILTER); AdminRegistration.register(ar, sc); } public void contextDestroyed(ServletContextEvent sce) { // register with the admininstration page ServletContext sc = sce.getServletContext(); AdminRegistration.unregister(ar, sc); } public static class DirectoryEntry { public enum Type { FILE, DIRECTORY }; private String name; private String path; private Type type; private List<DirectoryAction> actions; public DirectoryEntry(ContentNode node) { name = node.getName(); path = node.getPath(); if (path.equals("")) { path = "/"; } if (node instanceof ContentCollection) { type = Type.FILE; } else { type = Type.DIRECTORY; } actions = new ArrayList<DirectoryAction>(); } public void addAction(DirectoryAction action) { actions.add(action); } public List<DirectoryAction> getActions() { return actions; } public String getName() { return name; } public String getPath() { return path; } public Type getType() { return type; } } public static class DirectoryAction { private String name; private String url; public DirectoryAction(String name, String url) { this.name = name; this.url = url; } public String getName() { return name; } public String getUrl() { return url; } } }