acoli.controller.Controller.java Source code

Java tutorial

Introduction

Here is the source code for acoli.controller.Controller.java

Source

/**
 * *****************************************************************************
 * Copyright (c) 2005-2017 Niko Schenk Goethe-Universitt Frankfurt am Main All
 * rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors: Niko Schenk - initial implementation.
 * *****************************************************************************
 */
package acoli.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.io.FileUtils;

/**
 * Servlet implementation class
 *
 * @author niko
 */
public class Controller extends HttpServlet {

    private static final long serialVersionUID = 1L;

    private static String UPLOAD_JSP = "/upload.jsp";
    private static String RUN_JSP = "/run.jsp";
    private static String GRAMMAR_JSP = "/grammar.jsp";
    private static String ADMIN_JSP = "/admin.jsp";

    TreeMap<String, String> portToGrammarFolderMappings = new TreeMap<>();

    /**
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     * @throws FileNotFoundException
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, FileNotFoundException {

        // Get servlet context.
        ServletContext servletContext = this.getServletConfig().getServletContext();
        String path = servletContext.getRealPath("/");
        //System.out.println(path);
        // Previously used way to obtain servlet context doesn't work.
        //ServletContext context = request.getServletContext();
        //String path = context.getRealPath("/");
        //System.out.println("ServletContext.getRealPath():" + path + "<--");

        String forward = "";
        // Get a map of the request parameters
        @SuppressWarnings("unchecked")
        Map parameters = request.getParameterMap();

        if (parameters.containsKey("grammar")) {
            HttpSession session = request.getSession(false);
            String absoluteUnzippedGrammarDir = (String) session.getAttribute("absoluteUnzippedGrammarDir");
            //System.out.println("Uploaded file to analyze: " + absoluteUnzippedGrammarDir);

            // User-selected port.
            String javaport = (String) request.getParameter("javaport");

            System.out.println("User selected port: " + javaport);
            String traleport = String.valueOf((Integer.parseInt(javaport) - 1000));

            // Check if these ports are already in use
            // if so, kill the grammar in the corresponding directory and start a new one.
            if (portAvailable(Integer.parseInt(javaport)) && portAvailable(Integer.parseInt(traleport))) {
                System.out.println("Both javaport/traleport: " + javaport + "/" + traleport + " available!");
            } else {
                // Java port not free.
                if (!portAvailable(Integer.parseInt(javaport))) {
                    System.out.println("Port: " + javaport + " not available!");
                    // Get the grammar directory that is running on this port and kill it.
                    if (portToGrammarFolderMappings.containsKey(javaport)) {
                        String grammarDirToKill = portToGrammarFolderMappings.get(javaport);
                        // Stop grammar.
                        runBashScript(path, "./single_grammar_stop.sh", grammarDirToKill, "");

                    } else {
                        killProcessID(path, "./free_java_port.sh", javaport);
                    }
                }
                // Trale port not free.
                if (!portAvailable(Integer.parseInt(traleport))) {
                    killProcessID(path, "./free_sicstus_port.sh", traleport);
                }
            }
            // Generate port-specific files
            // which will be redirected by the script later.
            PrintWriter w = new PrintWriter(new File(absoluteUnzippedGrammarDir + "/" + "javaserverport.txt"));
            w.write(javaport);
            w.flush();
            w.close();

            w = new PrintWriter(new File(absoluteUnzippedGrammarDir + "/" + "traleserverstart.pl"));
            w.write("trale_server_start(" + traleport + ").\n"); // 1000 port ids less than the java id.
            w.flush();
            w.close();

            // Copy wtx.pl and tokenization.pl into the grammar directory.
            File tokenizationFile = new File(path + "/resources/servertrale_files/tokenization.pl");
            File wtxFile = new File(path + "/resources/servertrale_files/wtx.pl");

            //System.out.println("tokenizationFile: " + tokenizationFile.getAbsolutePath());
            //System.out.println("wtxFile: " + wtxFile.getAbsolutePath());
            File destinationDir = new File(absoluteUnzippedGrammarDir + "/");
            //System.out.println("destinationDir: " + absoluteUnzippedGrammarDir);
            FileUtils.copyFileToDirectory(tokenizationFile, destinationDir);
            FileUtils.copyFileToDirectory(wtxFile, destinationDir);

            // Start grammar.
            // Check webtrale version from user selection.
            String labelVersion = (String) request.getParameter("webtraleVersion");
            System.out.println("User selected label version: " + labelVersion);

            switch (labelVersion) {
            case "webtralePS94":
                runBashScript(path, "./single_grammar_start.sh", absoluteUnzippedGrammarDir,
                        "webtrale_green_labels.jar");
                break;
            case "webtraleAprilLabels":
                // April labels.
                runBashScript(path, "./single_grammar_start.sh", absoluteUnzippedGrammarDir,
                        "webtrale_green_aprillabels.jar");
                break;
            case "webtraleMayLabels":
                // May labels.
                runBashScript(path, "./single_grammar_start.sh", absoluteUnzippedGrammarDir,
                        "webtrale_green_maylabels.jar");
                break;
            case "webtraleJuneLabels":
                // June labels.
                runBashScript(path, "./single_grammar_start.sh", absoluteUnzippedGrammarDir,
                        "webtrale_green_junelabels.jar");
                break;
            default:
                // Standard labels.
                runBashScript(path, "./single_grammar_start.sh", absoluteUnzippedGrammarDir,
                        "webtrale_green_nolabels.jar");
                break;
            }

            portToGrammarFolderMappings.put(javaport, absoluteUnzippedGrammarDir);
            session.setAttribute("javaport", javaport);
            System.out.println("Used ports and grammar directories: " + portToGrammarFolderMappings + "\n");

            forward = GRAMMAR_JSP;
        } else if (parameters.containsKey("run")) {
            forward = RUN_JSP;
        } else if (parameters.containsKey("admin")) {
            System.out.println("Accessing grammar admin.");
            // Check which ports are still non-available.
            TreeMap<String, String> tmpMap = new TreeMap<>();
            for (String aJavaPort : portToGrammarFolderMappings.keySet()) {
                if (!portAvailable(Integer.parseInt(aJavaPort))) {
                    tmpMap.put(aJavaPort, portToGrammarFolderMappings.get(aJavaPort));
                }
            }

            portToGrammarFolderMappings.clear();
            portToGrammarFolderMappings = tmpMap;
            System.out
                    .println("Used ports and grammar directories in admin: " + portToGrammarFolderMappings + "\n");

            // only testing.
            //portToGrammarFolderMappings.put("7001", "/var/lib/tomcat7/webapps/servertrale/resources/uploads/BEBFECC89/posval");
            //portToGrammarFolderMappings.put("7002", "/var/lib/tomcat7/webapps/servertrale/resources/uploads/B02CA6BAA/4_Semantics_Raising");

            // Save all used ports and directories in this session attribute.
            HttpSession session = request.getSession(false);
            String portToGrammarFolderMappingsString = portToGrammarFolderMappings.toString().substring(1,
                    portToGrammarFolderMappings.toString().length() - 1);
            session.setAttribute("runningGrammars", portToGrammarFolderMappingsString.split("\\, "));

            forward = ADMIN_JSP;

        } // Upload (START PAGE)
        else {

            //            HttpSession session = request.getSession(false);
            //            String absoluteUnzippedGrammarDir = (String) session.getAttribute("absoluteUnzippedGrammarDir");
            //            if (absoluteUnzippedGrammarDir != null) {
            //                // Stop grammar.
            //                runBashScript(path, "./single_grammar_stop.sh", absoluteUnzippedGrammarDir);
            //                // Remove this java port from the list of occupied ports.
            //                TreeMap<String, String> tmpMap = new TreeMap<>();
            //                for(String aJavaPort : portToGrammarFolderMappings.keySet()) {
            //                    String aGrammarDir = portToGrammarFolderMappings.get(aJavaPort);
            //                    if(aGrammarDir.equals(absoluteUnzippedGrammarDir)) {
            //                        // Java port should be removed. So ignore it.
            //                    }
            //                    else {
            //                        tmpMap.put(aJavaPort, absoluteUnzippedGrammarDir);
            //                    }
            //                }
            //                portToGrammarFolderMappings.clear();
            //                portToGrammarFolderMappings = tmpMap;
            //                System.out.println("Used ports and grammar directories: " + portToGrammarFolderMappings + "\n\n");
            //                
            //            } else {
            //                System.out.println("No grammar to kill.");
            //            }
            forward = UPLOAD_JSP;
        }

        RequestDispatcher view = request.getRequestDispatcher(forward);
        view.forward(request, response);
    }

    private static BufferedReader getOutput(Process p) {
        return new BufferedReader(new InputStreamReader(p.getInputStream()));
    }

    private static BufferedReader getError(Process p) {
        return new BufferedReader(new InputStreamReader(p.getErrorStream()));
    }

    private void runBashScript(String path, String scriptCommand, String aScriptParam, String anotherScriptParam)
            throws IOException {
        // Run bash .sh script here.
        ProcessBuilder pb = null;
        // Call the startup script on the uploaded and unzipped grammar directory.
        pb = new ProcessBuilder(scriptCommand, aScriptParam, anotherScriptParam);
        if (pb != null) {
            //System.out.println("Running bash script....");
            // Point to where the script is located.
            pb.directory(new File(path + "/resources/uploads/"));
            Process p = pb.start();

            BufferedReader output = getOutput(p);
            BufferedReader error = getError(p);
            String line = "";
            while ((line = output.readLine()) != null) {
                System.out.println("out: " + line);
            }
            while ((line = error.readLine()) != null) {
                System.out.println("err: " + line);
            }
        }
    }

    private void killProcessID(String path, String scriptCommand, String aScriptParam) throws IOException {
        // Run bash .sh script here.
        ProcessBuilder pb = null;
        // Call the startup script on the uploaded and unzipped grammar directory.
        pb = new ProcessBuilder(scriptCommand, aScriptParam);
        if (pb != null) {
            //System.out.println("Running bash script....");
            // Point to where the script is located.
            pb.directory(new File(path + "/resources/uploads/"));
            Process p = pb.start();

            BufferedReader output = getOutput(p);
            BufferedReader error = getError(p);
            String line = "";
            while ((line = output.readLine()) != null) {
                System.out.println("out: " + line);
            }
            while ((line = error.readLine()) != null) {
                System.out.println("err: " + line);
            }
        }
    }

    /**
     * http://stackoverflow.com/questions/434718/sockets-discover-port-availability-using-java
     * Checks to see if a specific port is available.
     *
     * @param port the port to check for availability
     */
    public static boolean portAvailable(int port) {
        int MIN_PORT_NUMBER = 1000;
        int MAX_PORT_NUMBER = 9999;
        if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
            throw new IllegalArgumentException("Invalid start port: " + port);
        }

        ServerSocket ss = null;
        DatagramSocket ds = null;
        try {
            ss = new ServerSocket(port);
            ss.setReuseAddress(true);
            ds = new DatagramSocket(port);
            ds.setReuseAddress(true);
            return true;
        } catch (IOException e) {
        } finally {
            if (ds != null) {
                ds.close();
            }

            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    /* should not be thrown */
                }
            }
        }
        return false;
    }
}