org.shaf.server.controller.ActionProcessController.java Source code

Java tutorial

Introduction

Here is the source code for org.shaf.server.controller.ActionProcessController.java

Source

/**
 * Copyright 2014-2015 SHAF-WORK
 * 
 * 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 org.shaf.server.controller;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;

import org.shaf.core.util.Log;
import org.shaf.core.util.TextMatrix;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

/**
 * The controller for the "Process" dashboard.
 * 
 * @author Mykola Galushka
 */
@Controller
@Secured("ROLE_USER")
@RequestMapping("/proc/action")
public class ActionProcessController extends GenericActionController {

    /**
     * Defines a logger.
     */
    private static final Log LOG = Log.forClass(ActionProcessController.class);

    /**
     * Shows a list of all available process for the specified application.
     * 
     * @param app
     *            the application name.
     * @return the view model.
     * @throws Exception
     *             is the view constructing has failed.
     */
    @RequestMapping(value = "/list/{app}", method = RequestMethod.GET)
    public ModelAndView onList(@PathVariable String app) throws Exception {
        LOG.debug("CALL: /proc/action/list/{" + app + "}");

        TextMatrix procs = OPER.getProcesses(app);

        return ViewProcess.getListView()
                .header("app",
                        "The list of processes for "
                                + ("all".equals(app) ? "all applications." : "the '" + app + "' application."))
                .addProcessList(procs).addProcessFilter(OPER.getProcessFilter())
                .info(super.getListDescription(procs, "process"));
    }

    /**
     * Shows information about process.
     * 
     * @param cmd
     *            the command which invokes a process.
     * @return the view model.
     * @throws Exception
     *             is the view constructing has failed.
     */
    @RequestMapping(value = "/info/{cmd}", method = RequestMethod.GET)
    public ModelAndView onProc(@PathVariable String cmd) throws Exception {
        LOG.debug("CALL: /proc/action/info/{" + cmd + "}");

        return ViewProcess.getInfoView().header("proc", "Process: " + cmd).addProcessRef(cmd)
                .addProcessDescr(OPER.getProcessDescr(cmd))
                .info("For configuring this process press button 'Config'.");
    }

    /**
     * Configures process by the wizard.
     * 
     * @param cmd
     *            the command which invokes a process.
     * @return the view model.
     * @throws Exception
     *             is the view constructing has failed.
     */
    @RequestMapping(value = "/wiz/{cmd}", method = RequestMethod.GET)
    public ModelAndView onConfigWizard(@PathVariable String cmd) throws Exception {
        LOG.debug("CALL: /proc/action/wiz/{" + cmd + "}");

        return ViewProcess.getWizView().header("proc", "Process: " + cmd).addProcessRef(cmd)
                .addProcessDescr(OPER.getProcessDescr(cmd))
                .info("For launching this process press the button 'Launch'.");
    }

    /**
     * Configures process by the command line.
     * 
     * @param cmd
     *            the command which invokes a process.
     * @return the view model.
     * @throws Exception
     *             is the view constructing has failed.
     */
    @RequestMapping(value = "/cmd/{cmd}", method = RequestMethod.GET)
    public ModelAndView onConfigCommandLine(@PathVariable String cmd) throws Exception {
        LOG.debug("CALL: /proc/action/cmd/{" + cmd + "}");

        return ViewProcess.getCmdView().header("proc", "Process: " + cmd).addProcessRef(cmd)
                .addProcessUsage(OPER.getProcessUsage(cmd))
                .info("For launching this process press the button 'Launch'.");
    }

    /**
     * Launches the process execution,
     * 
     * @param cmd
     *            the command which launches a process.
     * @return the view model.
     * @throws Exception
     *             is the view constructing has failed.
     */
    @RequestMapping(value = "/launch/{cmd}", method = RequestMethod.POST)
    public ModelAndView onLaunch(@PathVariable String cmd) throws Exception {
        LOG.debug("CALL: /proc/action/launch/{" + cmd + "}");

        // Launching parameters extraction.
        BiMap<String, String> params = HashBiMap.create();
        Enumeration<String> names = REQUEST.getParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = REQUEST.getParameter(name);
            LOG.debug("PARAMS: " + name + "=" + value);

            if (name.startsWith("radio")) {
                String group = name.substring(0, name.indexOf('-'));
                String quantifier = name.substring(name.indexOf('-') + 1);

                if (quantifier.equals("opt")) {
                    // This is a selected radio button option.
                    if (params.containsKey(name)) {
                        params.inverse().put(params.get(name), value);
                    } else {
                        params.put(value, group + "-arg");
                    }
                } else {
                    // This is a selected radio button argument.
                    if (params.inverse().containsKey(name)) {
                        params.put(params.inverse().get(name), value);
                    } else {
                        params.inverse().put(value, group + "-opt");
                    }
                }
            } else {
                params.put(name, value);
            }
        }

        // Launching parameters cleanup.
        Iterator<String> keys = params.keySet().iterator();
        while (keys.hasNext()) {
            String key = keys.next();
            if (key.startsWith("radio")) {
                keys.remove();
            } else {

                String value = params.get(key);
                if (value == null) {
                    params.put(key, "");
                } else {
                    if (value.startsWith("radio")) {
                        params.put(key, "");
                    }
                }
            }

        }

        StringBuilder args = new StringBuilder();
        if (params.containsKey("command-line")) {
            args.append(params.get("command-line"));
        } else {
            for (Map.Entry<String, String> param : params.entrySet()) {
                if (args.length() > 0) {
                    args.append(' ');
                }
                args.append('-');
                args.append(param.getKey());
                if (!param.getValue().isEmpty()) {
                    args.append(' ');
                    if (param.getValue().contains(" ")) {
                        args.append('\"' + param.getValue() + '\"');
                    } else {
                        args.append(param.getValue());
                    }
                }
            }
        }

        String id = OPER.launchProcess(cmd, args.toString());

        return ViewJob.getInfoView().header("job", "Job: " + id).addJobId(id).addJobActiveStatus(true)
                .addJobFailedStatus(false).addJobOutcome(OPER.getJobOutcome(id))
                .info("The job execution in progress.");
    }
}