Package org.geonetwork.map.wmc

Source Code of org.geonetwork.map.wmc.WmcServlet$TempFile

package org.geonetwork.map.wmc;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.fao.geonet.Constants;
import org.geonetwork.http.proxy.util.RequestUtil;
import org.pvalsecc.misc.FileUtilities;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


public class WmcServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public static final Logger LOGGER = Logger.getLogger(WmcServlet.class);

    private final String WMC_CONTENT_TYPE = "application/vnd.ogc.context+xml";

    private final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?>";

    private static final String CREATE_URL = "/create.wmc";
    private static final String LOAD_URL = "/load.wmc";

    protected static final String TEMP_FILE_PREFIX = "geonetwork-wmc";
    protected static final String TEMP_FILE_SUFFIX = ".cml";
    private static final int TEMP_FILE_PURGE_SECONDS = 600;

    private File tempDir = null;

    /**
     * Map of temporary files.
     */
    private final Map<String, TempFile> tempFiles = new HashMap<String, TempFile>();

    @Override
    public void init() throws ServletException {
        //get rid of the temporary files that where present before the applet was started.
        File dir = getTempDir();
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; ++i) {
            File file = files[i];
            final String name = file.getName();
            if (name.startsWith(TEMP_FILE_PREFIX) &&
                    name.endsWith(TEMP_FILE_SUFFIX)) {
                deleteFile(file);
            }
        }
    }


    @Override
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        //do the routing in function of the actual URL
        final String additionalPath = httpServletRequest.getPathInfo();

        if (additionalPath.startsWith("/") && additionalPath.endsWith(TEMP_FILE_SUFFIX)) {
            getWMC(httpServletResponse, additionalPath.substring(1, additionalPath.length() - 4));
        } else {
            error(httpServletResponse, "Unknown method: " + additionalPath, 404);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        final String additionalPath = request.getPathInfo();
        final PrintWriter out = response.getWriter();
        response.setContentType("text/html");
        response.setHeader("Cache-Control", "no-cache");


        // Method call: Create Web Map Context
        if (additionalPath.equals(CREATE_URL)) {
            TempFile tempFile = null;
            try {
                tempFile = doCreateWMCFile(request);
            } catch (Throwable e) {
                deleteFile(tempFile);
                out.write("{success: true, error: '" + e.getMessage() + "'}");
                return;
            }

            final String id = generateId(tempFile);
            out.write("{success: true, url: '" + getBaseUrl(request) + "/" + id + TEMP_FILE_SUFFIX + "'}");

            addTempFile(tempFile, id);

        // Method call: Load Web Map Context
        } else if (additionalPath.equals(LOAD_URL)) {

            response.setContentType("text/html");
            response.setHeader("Cache-Control", "no-cache");

            boolean isMultipart = ServletFileUpload.isMultipartContent(request);

            if (!isMultipart) {
                out.write("{success: false, error: 'Error loading WMC'}");
                out.flush();

                return;
            }

             try {
                // Create a factory for disk-based file items
                FileItemFactory factory = new DiskFileItemFactory();

                // Create a new file upload handler
                ServletFileUpload upload = new ServletFileUpload(factory);

                // Parse the request
                @SuppressWarnings("unchecked")
                List<FileItem> items = upload.parseRequest(request);


                // Process the uploaded items
                for (FileItem item : items) {
                    if (!item.isFormField()) {
                        byte[] data = item.get();

                        //create a temporary file that will contain the WMC
                        TempFile tempFile = new TempFile(File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX, getTempDir()));
                        final String id = generateId(tempFile);
                        try {
                            Writer fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), Constants.ENCODING));
                            fw.write(new String(data, Constants.ENCODING));
                            fw.close();
                            out.write("{success: true, url: '" + getBaseUrl(request) + "/" + id + TEMP_FILE_SUFFIX + "'}");

                        } catch (IOException e) {
                            deleteFile(tempFile);
                            out.write("{success: false, error: '" + e.getMessage() + "'}");

                        }
                        addTempFile(tempFile, id);
                       
                        break;
                    }
                }

            } catch (Exception e) {
               out.write("{success: false, error: '" + e.getMessage() + "'}");
            }


        // Unknow method call
        } else {
            out.write("{success: false, error: 'Unknown method: '" + additionalPath + "'}");
            //error(response, "Unknown method: " + additionalPath, 404);
        }
    }

    /**
     * To get the WMC created previously.
     */
    protected void getWMC(HttpServletResponse httpServletResponse, String id) throws IOException {
        final File file;
        synchronized (tempFiles) {
            file = tempFiles.get(id);
        }
        if (file == null) {
            error(httpServletResponse, "File with id=" + id + " unknown", 404);
            return;
        }

        sendWmcFile(httpServletResponse, file);
    }

    protected void addTempFile(TempFile tempFile, String id) {
        synchronized (tempFiles) {
            tempFiles.put(id, tempFile);
        }
    }

    /**
     * Get the ID to use in function of the filename (filename without the prefix and the extension).
     */
    protected String generateId(File tempFile) {
        final String name = tempFile.getName();
        return name.substring(
                TEMP_FILE_PREFIX.length(),
                name.length() - TEMP_FILE_SUFFIX.length());
    }

    protected String getBaseUrl(HttpServletRequest httpServletRequest) {
        final String additionalPath = httpServletRequest.getPathInfo();
        String fullUrl = httpServletRequest.getParameter("url");
        if (fullUrl != null) {
            return fullUrl.replaceFirst(additionalPath + "$", "");
        } else {
            return httpServletRequest.getRequestURL().toString().replaceFirst(additionalPath + "$", "");
        }
    }

    /**
     * Do the actual work of creating the WMC temporary file.
     */
    protected TempFile doCreateWMCFile(HttpServletRequest httpServletRequest) throws IOException {

        //create a temporary file that will contain the WMC
        TempFile tempFile = new TempFile(File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX, getTempDir()));
        try {
            String wmcContent = RequestUtil.inputStreamAsString(httpServletRequest);
            wmcContent = XML_HEADER + "\n" + wmcContent;

            Writer fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), Constants.ENCODING));
            fw.write(wmcContent);
            fw.close();

            return tempFile;
        } catch (IOException e) {
            deleteFile(tempFile);
            throw e;
        }
    }


    /**
     * copy the WMC into the output stream
     */
    protected void sendWmcFile(HttpServletResponse httpServletResponse, File tempFile) throws IOException {
        FileInputStream pdf = null;
        try {
            pdf = new FileInputStream(tempFile);
            final OutputStream response = httpServletResponse.getOutputStream();
            httpServletResponse.setContentType(WMC_CONTENT_TYPE);
            httpServletResponse.setHeader("Content-disposition", "attachment; filename=" + tempFile.getName());
            FileUtilities.copyStream(pdf, response);
            response.close();
        } finally {
            if(pdf != null) {
                IOUtils.closeQuietly(pdf);
            }
        }
    }

    /**
     * Send an error XXX to the client with an exception
     */
    protected void error(HttpServletResponse httpServletResponse, String message, int code) {
        try {
            httpServletResponse.setContentType("text/plain");
            httpServletResponse.setStatus(code);
            PrintWriter out = httpServletResponse.getWriter();
            out.println("Error while generating WMC:");
            out.println(message);
            out.close();
            LOGGER.error("Error while generating WMC: " + message);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }


    /**
     * If the file is defined, delete it.
     */
    protected void deleteFile(File file) {
        if (file != null) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Deleting PDF file: " + file.getName());
            }
            if (!file.delete()) {
                LOGGER.warn("Cannot delete file:" + file.getAbsolutePath());
            }
        }
    }

    /**
     * Get and cache the temporary directory to use for saving the generated WMC files.
     */
    protected File getTempDir() {
        if (tempDir == null) {
            tempDir = (File) getServletContext().
                    getAttribute("javax.servlet.context.tempdir");
            LOGGER.debug("Using '" + tempDir.getAbsolutePath() + "' as temporary directory");
        }
        return tempDir;
    }

    /**
     * Will purge all the known temporary files older than TEMP_FILE_PURGE_SECONDS.
     */
    protected void purgeOldTemporaryFiles() {
        final long minTime = System.currentTimeMillis() - TEMP_FILE_PURGE_SECONDS * 1000L;
        synchronized (tempFiles) {
            Iterator<Map.Entry<String, TempFile>> it = tempFiles.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, TempFile> entry = it.next();
                if (entry.getValue().creationTime < minTime) {
                    deleteFile(entry.getValue());
                    it.remove();
                }
            }
        }
    }

    protected static class TempFile extends File {
        private static final long serialVersionUID = 1L;
        private final long creationTime;

        public TempFile(File tempFile) {
            super(tempFile.getAbsolutePath());
            creationTime = System.currentTimeMillis();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = super.hashCode();
            result = prime * result + (int) (creationTime ^ (creationTime >>> 32));
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!super.equals(obj))
                return false;
            if (getClass() != obj.getClass())
                return false;
            TempFile other = (TempFile) obj;
            if (creationTime != other.creationTime)
                return false;
            return true;
        }
       
    }
}
TOP

Related Classes of org.geonetwork.map.wmc.WmcServlet$TempFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.