org.jspresso.framework.server.remote.RemotePeerRegistryServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.jspresso.framework.server.remote.RemotePeerRegistryServlet.java

Source

/*
 * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved.
 *
 *  This file is part of the Jspresso framework.
 *
 *  Jspresso is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Jspresso is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Jspresso.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.jspresso.framework.server.remote;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.jspresso.framework.state.remote.IRemoteStateOwner;
import org.jspresso.framework.util.exception.IExceptionHandler;
import org.jspresso.framework.util.http.HttpRequestHolder;
import org.jspresso.framework.util.image.ImageHelper;
import org.jspresso.framework.util.io.IoHelper;
import org.jspresso.framework.util.remote.registry.IRemotePeerRegistry;

/**
 * This servlet class is used to deliver binary content from remote value
 * states.
 *
 * @author Vincent Vandenschrick
 */
public class RemotePeerRegistryServlet extends HttpServlet {

    /**
     * id.
     */
    private static final String ID_PARAMETER = "id";

    /**
     * height.
     */
    private static final String IMAGE_HEIGHT_PARAMETER = "height";

    /**
     * width.
     */
    private static final String IMAGE_WIDTH_PARAMETER = "width";

    /**
     * PeerRegistry.
     */
    public static final String PEER_REGISTRY = "peerRegistry";

    /**
     * the url pattern to activate a resource download.
     */
    private static final String REGISTRY_SERVLET_URL_PATTERN = "/registry";

    private static final Logger LOG = LoggerFactory.getLogger(RemotePeerRegistryServlet.class);

    private static final long serialVersionUID = -2706982900134792757L;

    /**
     * Computes the url where the resource is available for download.
     *
     * @param request
     *     the incoming HTTP request.
     * @param id
     *     the resource id.
     * @return the resource url.
     */
    public static String computeDownloadUrl(HttpServletRequest request, String id) {
        return computeUrl(request, "?" + ID_PARAMETER + "=" + id);
    }

    /**
     * Computes the url where the image is available for download.
     *
     * @param request
     *     the incoming HTTP request.
     * @param id
     *     the resource id.
     * @param scaledWidth
     *     the scaled width
     * @param scaledHeight
     *     the scaled height
     * @return the resource url.
     */
    public static String computeImageDownloadUrl(HttpServletRequest request, String id, Integer scaledWidth,
            Integer scaledHeight) {
        String downloadUrl = computeDownloadUrl(request, id);
        if (scaledWidth != null) {
            downloadUrl += "&" + IMAGE_WIDTH_PARAMETER + "=" + scaledWidth;
        }
        if (scaledHeight != null) {
            downloadUrl += "&" + IMAGE_HEIGHT_PARAMETER + "=" + scaledHeight;
        }
        return downloadUrl;
    }

    /**
     * Computes the url where the resource is available for upload.
     *
     * @param request
     *     the incoming HTTP request.
     * @param id
     *     the resource id.
     * @return the resource url.
     */
    public static String computeUploadUrl(HttpServletRequest request, String id) {
        return computeUrl(request, "?" + ID_PARAMETER + "=" + id);
    }

    /**
     * Computes the url where the resource is available for download.
     *
     * @param id
     *     the resource id.
     * @return the resource url.
     */
    public static String computeDownloadUrl(String id) {
        HttpServletRequest request = HttpRequestHolder.getServletRequest();
        return computeDownloadUrl(request, id);
    }

    /**
     * Computes the url where the image is available for download. Optionally performs scaling.
     *
     * @param id
     *     the resource id.
     * @param scaledWidth
     *     the scaled width
     * @param scaledHeight
     *     the scaled height
     * @return the resource url.
     */
    public static String computeImageDownloadUrl(String id, Integer scaledWidth, Integer scaledHeight) {
        HttpServletRequest request = HttpRequestHolder.getServletRequest();
        return computeImageDownloadUrl(request, id, scaledWidth, scaledHeight);
    }

    /**
     * Computes the url where the resource is available for upload.
     *
     * @param id
     *     the resource id.
     * @return the resource url.
     */
    public static String computeUploadUrl(String id) {
        HttpServletRequest request = HttpRequestHolder.getServletRequest();
        return computeUploadUrl(request, id);
    }

    private static String computeUrl(HttpServletRequest request, String getParameters) {
        String baseUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                + request.getContextPath() + REGISTRY_SERVLET_URL_PATTERN;
        return baseUrl + getParameters;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String id = request.getParameter(ID_PARAMETER);
        Integer scaledWidth = null;
        Integer scaledHeight = null;

        if (id == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No state id specified.");
            return;
        }

        BufferedInputStream inputStream = null;
        IRemotePeerRegistry peerRegistry = (IRemotePeerRegistry) request.getSession().getAttribute(PEER_REGISTRY);
        IRemoteStateOwner stateOwner = (IRemoteStateOwner) peerRegistry.getRegistered(id);
        Object stateValue = stateOwner.actualValue();
        if (stateValue != null) {
            if (request.getParameter(IMAGE_WIDTH_PARAMETER) != null) {
                scaledWidth = Integer.parseInt(request.getParameter(IMAGE_WIDTH_PARAMETER));
            }
            if (request.getParameter(IMAGE_HEIGHT_PARAMETER) != null) {
                scaledHeight = Integer.parseInt(request.getParameter(IMAGE_HEIGHT_PARAMETER));
            }
            if (scaledWidth != null || scaledHeight != null) {
                stateValue = ImageHelper.scaleImage(stateValue, scaledWidth, scaledHeight);
            }
            if (stateValue instanceof byte[]) {
                inputStream = new BufferedInputStream(new ByteArrayInputStream((byte[]) stateValue));
                response.setContentLength(((byte[]) stateValue).length);
            } else {
                inputStream = new BufferedInputStream(
                        new ByteArrayInputStream(stateValue.toString().getBytes(StandardCharsets.UTF_8.name())));
            }
        }
        if (inputStream != null) {
            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());

            IoHelper.copyStream(inputStream, outputStream);

            inputStream.close();
            outputStream.close();
        }
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String id = request.getParameter(ID_PARAMETER);

        if (id == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No state id specified.");
            return;
        }

        IRemotePeerRegistry peerRegistry = (IRemotePeerRegistry) request.getSession().getAttribute(PEER_REGISTRY);
        try {
            HttpRequestHolder.setServletRequest(request);
            byte[] content;
            if ("application/x-www-form-urlencoded".equals(request.getContentType())) {
                String data = request.getParameter("data");
                content = Base64.decodeBase64(data);
            } else {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                OutputStream out = new BufferedOutputStream(baos);
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);
                List<FileItem> items = upload.parseRequest(request);
                if (items.size() > 0) {
                    FileItem item = items.get(0);
                    IoHelper.copyStream(item.getInputStream(), out);
                }
                out.flush();
                out.close();
                content = baos.toByteArray();
            }

            if (content != null && content.length == 0) {
                content = null;
            }

            IRemoteStateOwner stateOwner = (IRemoteStateOwner) peerRegistry.getRegistered(id);
            stateOwner.setValueFromState(content);

        } catch (Exception ex) {
            if (peerRegistry instanceof IExceptionHandler) {
                ((IExceptionHandler) peerRegistry).handleException(ex, Collections.<String, Object>emptyMap());
            } else {
                LOG.error("An unexpected error occurred while uploading the content.", ex);
            }
        } finally {
            HttpRequestHolder.setServletRequest(null);
        }
    }

}