001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.web; 017 018import java.io.File; 019import java.io.IOException; 020import java.io.InputStream; 021import java.util.List; 022import javax.jcr.Binary; 023import javax.jcr.Node; 024import javax.jcr.Session; 025import javax.jcr.ValueFactory; 026import javax.servlet.ServletContext; 027import javax.servlet.ServletException; 028import javax.servlet.http.HttpServlet; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletResponse; 031import org.apache.commons.fileupload.FileItem; 032import org.apache.commons.fileupload.FileUploadException; 033import org.apache.commons.fileupload.disk.DiskFileItemFactory; 034import org.apache.commons.fileupload.servlet.ServletFileUpload; 035import org.modeshape.common.logging.Logger; 036import org.modeshape.web.server.Connector; 037 038/** 039 * 040 * @author kulikov 041 */ 042public class BinaryContentUploadServlet extends HttpServlet { 043 044 private static final long serialVersionUID = 1505304380334878522L; 045 046 private final static String CONTENT_PARAMETER = "Upload content"; 047 private final static String REPOSITORY_NAME_PARAMETER = "repository"; 048 private final static String WORKSPACE_NAME_PARAMETER = "workspace"; 049 private final static String NODE_PATH_PARAMETER = "path"; 050 private final static String PROPERTY_NAME_PARAMETER = "pname"; 051 private final static String REPOSITORY_CONNECTOR = "connector"; 052 private final static String MIME_TYPE = "jcr:mimeType"; 053 private final static String DESTINATION_URL = "/tree/%s/ws-%s%s"; 054 055 private ServletFileUpload upload; 056 private final Logger logger = Logger.getLogger(BinaryContentServlet.class); 057 058 /** 059 * Processes requests for both HTTP 060 * <code>GET</code> and 061 * <code>POST</code> methods. 062 * 063 * @param request servlet request 064 * @param response servlet response 065 * @throws ServletException if a servlet-specific error occurs 066 * @throws IOException if an I/O error occurs 067 */ 068 protected void processRequest(HttpServletRequest request, HttpServletResponse response) 069 throws ServletException, IOException { 070 List<FileItem> items; 071 // Parse the request 072 try { 073 items = upload.parseRequest(request); 074 } catch (FileUploadException e) { 075 throw new ServletException(e); 076 } 077 078 String repository = getParameter(items, REPOSITORY_NAME_PARAMETER); 079 String workspace = getParameter(items, WORKSPACE_NAME_PARAMETER); 080 String path = getParameter(items, NODE_PATH_PARAMETER); 081 String pname = getParameter(items, PROPERTY_NAME_PARAMETER); 082 083 if (logger.isDebugEnabled()) { 084 logger.debug(String.format("Upload %s at %s/%s%s", 085 pname, repository, workspace, path)); 086 } 087 088 String mimeType = getContentType(items); 089 Connector connector = (Connector) 090 request.getSession().getAttribute(REPOSITORY_CONNECTOR); 091 092 try { 093 Session session = connector.find(repository).session(workspace); 094 ValueFactory valueFactory = session.getValueFactory(); 095 Binary bin = valueFactory.createBinary(getStream(items)); 096 097 Node node = session.getNode(path); 098 node.setProperty(pname, bin); 099 node.setProperty(MIME_TYPE, mimeType); 100 bin.dispose(); 101 } catch (Exception e) { 102 throw new ServletException(e); 103 } 104 105 String uri = request.getContextPath() + 106 String.format(DESTINATION_URL, repository, workspace, path); 107 response.sendRedirect(uri); 108 } 109 110 /** 111 * Extracts value of the parameter with given name. 112 * 113 * @param items 114 * @param name 115 * @return parameter value or null. 116 */ 117 private String getParameter(List<FileItem> items, String name) { 118 for (FileItem i : items) { 119 if (i.isFormField() && i.getFieldName().equals(name)) { 120 return i.getString(); 121 } 122 } 123 return null; 124 } 125 126 /** 127 * Gets uploaded file as stream. 128 * 129 * @param items 130 * @return the stream 131 * @throws IOException 132 */ 133 private InputStream getStream(List<FileItem> items) throws IOException { 134 for (FileItem i : items) { 135 if (!i.isFormField() && i.getFieldName().equals(CONTENT_PARAMETER)) { 136 return i.getInputStream(); 137 } 138 } 139 return null; 140 } 141 142 /** 143 * Determines content-type of the uploaded file. 144 * 145 * @param items 146 * @return the content type 147 */ 148 private String getContentType(List<FileItem> items) { 149 for (FileItem i : items) { 150 if (!i.isFormField() && i.getFieldName().equals(CONTENT_PARAMETER)) { 151 return i.getContentType(); 152 } 153 } 154 return null; 155 } 156 157 @Override 158 public void init() { 159 DiskFileItemFactory diskFactory = new DiskFileItemFactory(); 160 161 // Configure a repository (to ensure a secure temp location is used) 162 ServletContext servletContext = this.getServletConfig().getServletContext(); 163 File tempDir = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); 164 diskFactory.setRepository(tempDir); 165 166 // Create a new file upload handler 167 upload = new ServletFileUpload(diskFactory); 168 } 169 170 171 // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> 172 173 /** 174 * Handles the HTTP 175 * <code>GET</code> method. 176 * 177 * @param request servlet request 178 * @param response servlet response 179 * @throws ServletException if a servlet-specific error occurs 180 * @throws IOException if an I/O error occurs 181 */ 182 @Override 183 protected void doGet(HttpServletRequest request, HttpServletResponse response) 184 throws ServletException, IOException { 185 processRequest(request, response); 186 } 187 188 /** 189 * Handles the HTTP 190 * <code>POST</code> method. 191 * 192 * @param request servlet request 193 * @param response servlet response 194 * @throws ServletException if a servlet-specific error occurs 195 * @throws IOException if an I/O error occurs 196 */ 197 @Override 198 protected void doPost(HttpServletRequest request, HttpServletResponse response) 199 throws ServletException, IOException { 200 processRequest(request, response); 201 } 202 203 /** 204 * Returns a short description of the servlet. 205 * 206 * @return a String containing servlet description 207 */ 208 @Override 209 public String getServletInfo() { 210 return "Short description"; 211 }// </editor-fold> 212}