xbdd.webapp.resource.feature.PrintPDF.java Source code

Java tutorial

Introduction

Here is the source code for xbdd.webapp.resource.feature.PrintPDF.java

Source

/**
 * Copyright (C) 2015 Orion Health (Orchestral Development Ltd)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package xbdd.webapp.resource.feature;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.StreamingOutput;

import org.apache.commons.io.IOUtils;

import xbdd.webapp.util.Coordinates;

@Path("/rest/pdfreports")
public class PrintPDF {

    private static final String XBDD_PHANTOMJS_HOME_INIT_PARAMETER = "xbdd.phantomjs.home";
    private static final String XBDD_PHANTOMJS_USERNAME_INIT_PARAMETER = "xbdd.phantomjs.username";
    private static final String XBDD_PHANTOMJS_PASSWORD_INIT_PARAMETER = "xbdd.phantomjs.password";

    @GET
    @Path("/{product}/{major}.{minor}.{servicePack}/{build}/")
    public Response viewPDF(@BeanParam final Coordinates coord, @Context final HttpServletRequest request,
            @Context final ServletContext context, @QueryParam("view") final String view)
            throws URISyntaxException {

        final String urlcontext = request.getScheme() + "://" + request.getServerName() + ":"
                + request.getServerPort() + request.getContextPath();
        final String previousPage = request.getHeader("Referer");

        final String productString = "/" + coord.getProduct() + "/" + coord.getVersionString() + "/"
                + coord.getBuild();
        final String urlstring = urlcontext + "/print/" + productString;

        // Getting the location of PHANTOMJS_HOME environment variable
        final String phantomjsloc = Objects.toString(context.getInitParameter(XBDD_PHANTOMJS_HOME_INIT_PARAMETER),
                System.getProperty("PHANTOMJS_HOME"));
        if (phantomjsloc == null) {
            final URI location = new URI(previousPage + "&phantom=no");
            return Response.temporaryRedirect(location).build();
        } else {
            final String username = Objects.toString(
                    context.getInitParameter(XBDD_PHANTOMJS_USERNAME_INIT_PARAMETER),
                    System.getProperty("PHANTOMJS_USER"));
            final String password = Objects.toString(
                    context.getInitParameter(XBDD_PHANTOMJS_PASSWORD_INIT_PARAMETER),
                    System.getProperty("PHANTOMJS_PASSWORD"));
            final StreamingOutput stream = createPDFStream(urlstring, phantomjsloc,
                    context.getRealPath("/WEB-INF/rasterize.js"), username, password);

            String viewType = "inline";
            // View in browser or download as attachment
            if (view != null) {
                viewType = view;
            }

            final ResponseBuilder response = Response.ok(stream);
            response.type("application/pdf");
            response.status(200);
            response.header("Content-Disposition", viewType + "; filename=\"" + coord.getProduct() + " Version="
                    + coord.getVersionString() + ", Build=" + coord.getBuild() + ".pdf\"");
            return response.build();
        }
    }

    public StreamingOutput createPDFStream(final String urlstring, final String phantomjsloc,
            final String rasterJsPath, final String username, final String password) {
        final StreamingOutput stream = new StreamingOutput() {
            @Override
            public void write(final OutputStream os) throws IOException, WebApplicationException {

                final File tmpFile = File.createTempFile("report", ".pdf");
                final List<String> commands = new ArrayList<String>();
                final String osName = System.getProperty("os.name").toLowerCase();
                if (osName.indexOf("win") >= 0) {// It's windows
                    commands.add("CMD");
                    commands.add("/c");
                    commands.add(phantomjsloc + "\\phantomjs");
                    commands.add("--ignore-ssl-errors=yes");
                    commands.add(rasterJsPath);
                    commands.add("\"" + urlstring + "\"");
                } else {// Assume it's linux
                    commands.add(phantomjsloc + "/phantomjs");
                    commands.add("--ignore-ssl-errors=yes");
                    commands.add(rasterJsPath);
                    commands.add(urlstring);
                }
                commands.add(tmpFile.getAbsolutePath());
                commands.add(username);
                commands.add(password);

                generatePDF(commands);
                makeStream(tmpFile, os);
                tmpFile.delete();
            }
        };

        return stream;
    }

    public static int randInt(final int min, final int max) {

        final Random rand = new Random();

        // nextInt is normally exclusive of the top value,
        // so add 1 to make it inclusive
        final int randomNum = rand.nextInt((max - min) + 1) + min;

        return randomNum;
    }

    public void generatePDF(final List<String> commands) throws IOException {
        final ProcessBuilder probuilder = new ProcessBuilder(commands);
        probuilder.redirectError();
        probuilder.redirectOutput();
        probuilder.redirectInput();
        final Process process = probuilder.start();
        try {
            process.waitFor();
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
        process.destroy();
    }

    public void makeStream(final File tmpFile, final OutputStream os) throws IOException {
        try (InputStream inputStream = new FileInputStream(tmpFile);
                BufferedOutputStream fos1 = new BufferedOutputStream(os)) {
            final byte[] bytes = IOUtils.toByteArray(inputStream);
            fos1.write(bytes);
            fos1.flush();
        }
    }
}