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.servlet.ServletContext;
023import javax.servlet.ServletException;
024import javax.servlet.http.HttpServlet;
025import javax.servlet.http.HttpServletRequest;
026import javax.servlet.http.HttpServletResponse;
027import org.apache.commons.fileupload.FileItem;
028import org.apache.commons.fileupload.FileUploadException;
029import org.apache.commons.fileupload.disk.DiskFileItemFactory;
030import org.apache.commons.fileupload.servlet.ServletFileUpload;
031import org.modeshape.common.util.FileUtil;
032import org.modeshape.web.server.Connector;
033import org.modeshape.web.shared.RestoreParams;
034
035/**
036 *
037 * @author kulikov
038 */
039public class BackupUploadServlet extends HttpServlet {
040
041    private static final long serialVersionUID = 1505304380334878522L;
042    private final static String CONTENT_PARAMETER = "Upload content";
043    private final static String REPOSITORY_NAME_PARAMETER = "repository";
044    private final static String INCLUDE_BINARY_PARAMETER = "Include binaries";
045    private final static String REINDEX_ON_FINISH_PARAMETER = "Reindex on finish";
046    private final static String REPOSITORY_CONNECTOR = "connector";
047    private final static String DESTINATION_URL = "/tree/%s/";
048    private ServletFileUpload upload;
049    private File tempDir;
050
051    /**
052     * Processes requests for both HTTP
053     * <code>GET</code> and
054     * <code>POST</code> methods.
055     *
056     * @param request servlet request
057     * @param response servlet response
058     * @throws ServletException if a servlet-specific error occurs
059     * @throws IOException if an I/O error occurs
060     */
061    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
062            throws ServletException, IOException {
063        List<FileItem> items;
064        // Parse the request
065        try {
066            items = upload.parseRequest(request);
067        } catch (FileUploadException e) {
068            throw new ServletException(e);
069        }
070
071        String repository = getParameter(items, REPOSITORY_NAME_PARAMETER);
072        String incBinaries = getParameter(items, INCLUDE_BINARY_PARAMETER);
073        String reindexOnFinish = getParameter(items, REINDEX_ON_FINISH_PARAMETER);
074
075        RestoreParams params = new RestoreParams();
076        params.setIncludeBinaries(Boolean.valueOf(incBinaries));
077        params.setReindexOnFinish(Boolean.valueOf(reindexOnFinish));
078        
079        InputStream in = getStream(items);
080
081        File dir = new File(tempDir.getAbsolutePath() + File.pathSeparator + 
082                Long.toString(System.currentTimeMillis()));
083        
084        FileUtil.unzip(in, dir.getAbsolutePath());
085        Connector connector = (Connector) request.getSession().getAttribute(REPOSITORY_CONNECTOR);
086
087        try {
088            connector.find(repository).restore(dir.getAbsolutePath(), params);
089        } catch (Exception e) {
090            throw new ServletException(e);
091        }
092
093        String uri = request.getContextPath()
094                + String.format(DESTINATION_URL, repository);
095        response.sendRedirect(uri);
096    }
097
098    /**
099     * Extracts value of the parameter with given name.
100     *
101     * @param items
102     * @param name
103     * @return parameter value or null.
104     */
105    private String getParameter(List<FileItem> items, String name) {
106        for (FileItem i : items) {
107            if (i.isFormField() && i.getFieldName().equals(name)) {
108                return i.getString();
109            }
110        }
111        return null;
112    }
113
114    /**
115     * Gets uploaded file as stream.
116     *
117     * @param items
118     * @return the stream
119     * @throws IOException
120     */
121    private InputStream getStream(List<FileItem> items) throws IOException {
122        for (FileItem i : items) {
123            if (!i.isFormField() && i.getFieldName().equals(CONTENT_PARAMETER)) {
124                return i.getInputStream();
125            }
126        }
127        return null;
128    }
129
130    @Override
131    public void init() {
132        DiskFileItemFactory diskFactory = new DiskFileItemFactory();
133
134        // Configure a repository (to ensure a secure temp location is used)
135        ServletContext servletContext = this.getServletConfig().getServletContext();
136
137        tempDir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
138        diskFactory.setRepository(tempDir);
139
140        // Create a new file upload handler
141        upload = new ServletFileUpload(diskFactory);
142    }
143
144    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
145    /**
146     * Handles the HTTP
147     * <code>GET</code> method.
148     *
149     * @param request servlet request
150     * @param response servlet response
151     * @throws ServletException if a servlet-specific error occurs
152     * @throws IOException if an I/O error occurs
153     */
154    @Override
155    protected void doGet(HttpServletRequest request, HttpServletResponse response)
156            throws ServletException, IOException {
157        processRequest(request, response);
158    }
159
160    /**
161     * Handles the HTTP
162     * <code>POST</code> method.
163     *
164     * @param request servlet request
165     * @param response servlet response
166     * @throws ServletException if a servlet-specific error occurs
167     * @throws IOException if an I/O error occurs
168     */
169    @Override
170    protected void doPost(HttpServletRequest request, HttpServletResponse response)
171            throws ServletException, IOException {
172        processRequest(request, response);
173    }
174
175    /**
176     * Returns a short description of the servlet.
177     *
178     * @return a String containing servlet description
179     */
180    @Override
181    public String getServletInfo() {
182        return "Short description";
183    }
184}