eu.aniketos.securebpmn.validation.ValidateAslanRunnable.java Source code

Java tutorial

Introduction

Here is the source code for eu.aniketos.securebpmn.validation.ValidateAslanRunnable.java

Source

/* Copyright 2012-2015 SAP SE
 *
 * 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 eu.aniketos.securebpmn.validation;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;

import org.activiti.designer.eclipse.common.ActivitiBPMNDiagramConstants;
import org.activiti.designer.eclipse.extension.export.ExportMarshaller;
import org.activiti.designer.eclipse.preferences.PreferencesUtil;
import org.activiti.designer.eclipse.util.ExtensionPointUtil;
import org.activiti.designer.util.preferences.Preferences;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.satmc.SatmcLexer;
import org.antlr.satmc.SatmcParser;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;

import eu.aniketos.securebpmn.satmc.SatmcMessage;
import eu.aniketos.securebpmn.util.DialogUtil;
import eu.aniketos.securebpmn.util.SecurityUtil;

import eu.avantssar.satmc.SATMCPortType;
import eu.avantssar.satmc.SATMCService;

/**
 * A Runnable that generates the ASLan file and analyzes it via SATMC for a
 * given Diagram.
 *
 *
 */
public class ValidateAslanRunnable implements IRunnableWithProgress {

    private Diagram diagram;
    private boolean localValidation;

    private SatmcMessage result;

    /**
     * Default constructor.
     *
     * @param diagram
     *            The diagram that should be validated.
     * @param result
     *            The variable where the result is saved to.
     * @param localValidation
     *            true if the local SATMC binary should be used, false for the
     *            SATMC web service.
     */
    public ValidateAslanRunnable(Diagram diagram, SatmcMessage result, boolean localValidation) {
        this.diagram = diagram;
        this.localValidation = localValidation;
        this.result = result;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core
     * .runtime.IProgressMonitor)
     */
    @Override
    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

        try {

            monitor.beginTask("Validating security properties", 10);

            // get uri
            URI uri = diagram.eResource().getURI();
            URI platformUri = uri.trimFragment();
            platformUri = platformUri.trimFileExtension();
            platformUri = platformUri.appendFileExtension("aslan");

            monitor.worked(1);

            // generate file
            monitor.subTask("Generating ASLan");

            final ExportMarshaller marshaller = ExtensionPointUtil
                    .getExportMarshaller(ActivitiBPMNDiagramConstants.ASLAN_MARSHALLER_NAME);
            if (marshaller == null) {
                throw new IllegalArgumentException("Unable to invoke ExportMarshaller with name "
                        + ActivitiBPMNDiagramConstants.ASLAN_MARSHALLER_NAME);
            }
            final IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 2);
            try {
                marshaller.marshallDiagram(diagram, subMonitor);
            } finally {
                subMonitor.done();
            }

            // check for problem markers
            final IWorkspace workspace = ResourcesPlugin.getWorkspace();

            final IFile diagramFile = workspace.getRoot()
                    .getFile(new Path(diagram.eResource().getURI().toPlatformString(true)));

            try {
                if (diagramFile.findMarkers(ExportMarshaller.MARKER_ID, true, 3).length > 0) {
                    Display.getDefault().syncExec(new Runnable() {
                        public void run() {
                            DialogUtil.openMessageDialog("Export problems present",
                                    "The diagram contains export problems! This might result in an outdated analysis result, you should fix the problems and run the analysis again.",
                                    DialogUtil.WARNING);
                        }
                    });
                }
            } catch (CoreException e1) {
                e1.printStackTrace();
            }

            // file validation
            String res = "";
            final String fileUri = getResource(platformUri).getLocation().toString();

            if (localValidation) {
                // call local binary and pass file path
                monitor.subTask("Executing local SATMC binary");
                try {
                    String pathToBinary = PreferencesUtil.getStringPreference(Preferences.PATH_TO_SATMC_BINARY);
                    File workingDir = null;
                    if (pathToBinary.length() == 0) {
                        pathToBinary = "satmc";
                    } else {
                        int lastIndex = pathToBinary.lastIndexOf(System.getProperty("file.separator"));

                        if (lastIndex > 0) {
                            workingDir = new File(pathToBinary.substring(0, lastIndex));
                        }
                    }
                    String[] cmd = { pathToBinary, fileUri, "--max=80", "--mutex=0" };
                    res = cmdExec(cmd, workingDir);
                } catch (IOException e) {
                    Display.getDefault().syncExec(new Runnable() {
                        public void run() {
                            DialogUtil.openMessageDialog("SATMC Execution Error",
                                    "Could not run SATMC. Try providing the full path to the executable file in the Activiti preferences.",
                                    DialogUtil.ERROR);
                        }
                    });
                    e.printStackTrace();
                    monitor.worked(7);
                    monitor.done();
                    return;
                }
            } else {
                // read file as string and call web service
                monitor.subTask("Calling SATMC web service");
                try {
                    final SATMCService service = new SATMCService();
                    final SATMCPortType port = service.getSATMCSOAPPort();

                    res = port.validate(SecurityUtil.readFileAsString(fileUri), 80, false, true, false, "aslan",
                            "");
                } catch (Exception e) {
                    Display.getDefault().syncExec(new Runnable() {
                        public void run() {
                            DialogUtil.openMessageDialog("SATMC Execution Error",
                                    "Could not reach SATMC web service. Check your internet connection and, if you are behind a firewall, try setting the proxy in Eclipse to \"manual\".",
                                    DialogUtil.ERROR);
                        }
                    });
                    e.printStackTrace();
                    monitor.worked(7);
                    monitor.done();
                    return;
                }
            }

            monitor.worked(4);

            // save result to file
            monitor.subTask("Saving results");

            InputStream content = new ByteArrayInputStream(res.getBytes());

            URI platformResultUri = uri.trimFragment();
            platformResultUri = platformResultUri.trimFileExtension();
            platformResultUri = platformResultUri.appendFileExtension("result");

            final IFile newfile = workspace.getRoot().getFile(new Path(platformResultUri.toPlatformString(true)));

            try {
                if (newfile.exists()) {
                    newfile.setContents(content, true, true, new NullProgressMonitor());
                } else {
                    newfile.create(content, true, new NullProgressMonitor());
                }
                newfile.refreshLocal(IResource.DEPTH_INFINITE, null);
            } catch (CoreException e) {
                e.printStackTrace();
            }

            monitor.worked(1);

            // parse results
            monitor.subTask("Parsing results");

            try {
                SatmcLexer lex = new SatmcLexer(new ANTLRStringStream(res));
                CommonTokenStream tokens = new CommonTokenStream(lex);

                SatmcParser parser = new SatmcParser(tokens);
                SatmcMessage parserResult = parser.output();

                // copy result to result variable
                result.summary = parserResult.summary;
                result.goal = parserResult.goal;
                result.trace = parserResult.trace;
                result.cfs = parserResult.cfs;

            } catch (RecognitionException e) {
                e.printStackTrace();
            }

            monitor.worked(2);
        } finally {
            monitor.done();
        }

    }

    /**
     * Retrieves the Resource for a given URI.
     *
     * @param resourceURI
     *            The URI for the Resource.
     * @return The found Resource.
     */
    private IResource getResource(URI resourceURI) {

        final IResource fileResource = ResourcesPlugin.getWorkspace().getRoot()
                .findMember(resourceURI.toPlatformString(true));

        IResource result = null;
        if (fileResource != null && fileResource.exists()) {
            result = ResourcesPlugin.getWorkspace().getRoot().findMember(resourceURI.toPlatformString(true));
        }
        return result;
    }

    /**
     * Executes a command on the local machine.
     *
     * @param cmdLine
     *            The command that should be executed.
     * @param dir
     *            The working directory in which the command should be executed.
     * @return The standard output of the command.
     * @throws IOException
     *             Errors that occur during the execution.
     */
    private String cmdExec(String[] cmdLine, File dir) throws IOException {
        String line;
        String output = "";

        Process p = Runtime.getRuntime().exec(cmdLine, null, dir);
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
        while ((line = input.readLine()) != null) {
            output += (line + '\n');
        }
        input.close();

        return output;
    }

}