eu.scape_project.tool.toolwrapper.component_uploader.ComponentUploader.java Source code

Java tutorial

Introduction

Here is the source code for eu.scape_project.tool.toolwrapper.component_uploader.ComponentUploader.java

Source

/**
 ################################################################################
 #                  Copyright 2012 The SCAPE Project Consortium
 #
 #   This software is copyrighted by the SCAPE Project Consortium. 
 #   The SCAPE project is co-funded by the European Union under
 #   FP7 ICT-2009.4.1 (Grant Agreement number 270137).
 #
 #   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.scape_project.tool.toolwrapper.component_uploader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.JAXBException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.glassfish.jersey.client.filter.HttpBasicAuthFilter;
import org.xml.sax.SAXException;

import eu.scape_project.tool.toolwrapper.core.configuration.Constants;
import eu.scape_project.tool.toolwrapper.core.exceptions.ErrorParsingCmdArgsException;
import eu.scape_project.tool.toolwrapper.data.components_spec.Component;
import eu.scape_project.tool.toolwrapper.data.components_spec.Components;
import eu.scape_project.tool.toolwrapper.data.tool_spec.Operation;
import eu.scape_project.tool.toolwrapper.data.tool_spec.Tool;

/** Class that uploads a Component (Taverna workflow) to the myExperiment site */
public class ComponentUploader {

    private static Logger logger = Logger.getLogger(ComponentUploader.class);

    private static final String MY_EXPERIMENT_COMPONENT_URI = "http://www.myexperiment.org/component.xml";
    private static final String DEFAULT_DESCRIPTION = "TBA";
    private static final String DEFAULT_LICENSE = "by-sa";
    private static final String COMPONENT_PUBLIC_VIEW_DOWNLOAD_PERMISSIONS = "<permissions><permission><category>public</category><privilege type=\"view\"/><privilege type=\"download\"/></permission></permissions>";
    private static final String COMPONENT_GROUP_VIEW_DOWNLOAD_PERMISSIONS_TEMPLATE = "<permissions><permission><category>group</category><id>%s</id><privilege type=\"view\"/><privilege type=\"download\"/></permission></permissions>";
    private static final String COMPONENT_UPLOAD_TEMPLATE = "<workflow>" + "<title>%s</title>"
            + "<description>%s</description>"
            + "<component-family>http://www.myexperiment.org/packs/%s</component-family>"
            + "<license-type>%s</license-type>" + "<content-type>application/vnd.taverna.t2flow+xml</content-type>"
            + "<content>%s</content>" + "%s" + "</workflow>";

    private Client restClient;
    private Options options;

    /** Empty constructor */
    public ComponentUploader() {

        // REST client instantiation and configuration
        restClient = ClientBuilder.newClient();

        Option opt;
        this.options = new Options();

        opt = new Option("u", "username", true, "myExperiment username");
        opt.setRequired(true);
        getOptions().addOption(opt);

        opt = new Option("p", "password", true, "myExperiment password");
        opt.setRequired(true);
        getOptions().addOption(opt);

        opt = new Option("i", "family", true, "component family id");
        opt.setRequired(true);
        getOptions().addOption(opt);

        opt = new Option("t", "toolspec", true, "toolspec file location");
        opt.setRequired(true);
        options.addOption(opt);

        opt = new Option("s", "componentspec", true, "component spec file location");
        opt.setRequired(true);
        getOptions().addOption(opt);

        opt = new Option("c", "component", true, "component file location (Taverna workflow)");
        opt.setRequired(true);
        getOptions().addOption(opt);

        opt = new Option("l", "license", true,
                "component license (as myExperiment license set doesn't match the Toolwrapper one)");
        opt.setRequired(false);
        getOptions().addOption(opt);

        opt = new Option("d", "description", true, "component description");
        opt.setRequired(false);
        getOptions().addOption(opt);

        opt = new Option("e", "permissions", true,
                "component permissions (default to private, '--permissions public' for public view/download and '--permissions GROUP_ID' for group GROUP_ID view/download permissions");
        opt.setRequired(false);
        getOptions().addOption(opt);

    }

    public Options getOptions() {
        return options;
    }

    public void setOptions(Options options) {
        this.options = options;
    }

    /**
     * Uploads the component file to the myExperiment site
     * 
     * @param username
     *            myExperiment username
     * @param password
     *            myExperiment password
     * @param familyId
     *            component family ID (the number part of the URI)
     * @param componentSpecFilePath
     *            the path to the component spec file
     * @param componentFilePath
     *            the path to the component file (Taverna workflow)
     * @param license
     *            myExperiment license (myExperiment accepted license set
     *            doesn't match with Component license set). if no license is
     *            provided, by default this will be set to
     *            {@link ComponentUploader#DEFAULT_LICENSE}
     * @param description
     *            if no description is provided, by default this will be set to
     *            {@link ComponentUploader#DEFAULT_DESCRIPTION}
     * 
     * @return true if the upload was successful, false otherwise
     * 
     * */
    public boolean uploadComponentToMyExperiment(String username, String password, String familyId,
            String toolSpecFilePath, String componentSpecFilePath, String componentFilePath, String license,
            String description, String permissions) throws IOException, JAXBException, SAXException {
        boolean res = true;
        String descriptionValue = null;

        Tool tool = eu.scape_project.tool.toolwrapper.data.tool_spec.utils.Utils.createTool(toolSpecFilePath);

        Components components = eu.scape_project.tool.toolwrapper.data.components_spec.utils.Utils
                .createComponents(componentSpecFilePath);

        if (components != null) {

            for (Component component : components.getComponent()) {

                File componentFile = new File(componentFilePath);

                // we only want the Component object of the workflow provided
                // (workflows generated by the toolwrapper are automatically
                // named OPERATION_NAME.t2flow (see
                // /tool/operations/operation/@name), where OPERATION NAME must
                // match the Component name (see /components/component/@name))
                if (componentFile.getName().startsWith(component.getName())) {

                    for (Operation operation : tool.getOperations().getOperation()) {
                        if (operation.getName().equals(component.getName())) {
                            descriptionValue = operation.getDescription();
                            break;
                        }
                    }

                    String permissionsInfo = "";
                    if (StringUtils.isNotBlank(permissions)) {
                        if ("public".equalsIgnoreCase(permissions)) {
                            permissionsInfo = COMPONENT_PUBLIC_VIEW_DOWNLOAD_PERMISSIONS;
                        } else {
                            permissionsInfo = String.format(COMPONENT_GROUP_VIEW_DOWNLOAD_PERMISSIONS_TEMPLATE,
                                    permissions);
                        }
                    }

                    String title = component.getName();
                    if (descriptionValue == null || descriptionValue.trim().length() == 0) {
                        descriptionValue = (description == null ? DEFAULT_DESCRIPTION : description);
                    }
                    // NOTE: myExperiment accepted license set doesn't match
                    // with Component license set
                    String licenseValue = license == null ? DEFAULT_LICENSE : license;

                    final FileInputStream input = new FileInputStream(componentFilePath);
                    byte[] encodedBytes = null;
                    try {
                        encodedBytes = Base64.encodeBase64(IOUtils.toByteArray(input));
                    } finally {
                        input.close();
                    }
                    String base64 = new String(encodedBytes, Charset.defaultCharset());

                    String postData = String.format(COMPONENT_UPLOAD_TEMPLATE, title, descriptionValue, familyId,
                            licenseValue, base64, permissionsInfo);

                    logger.debug(postData);

                    // set basic authentication
                    HttpBasicAuthFilter httpBasicAuthFilter = new HttpBasicAuthFilter(username, password);
                    restClient.register(httpBasicAuthFilter);

                    // HTTP POST request
                    WebTarget uploadRequest = restClient.target(MY_EXPERIMENT_COMPONENT_URI);

                    Response uploadResponse = uploadRequest.request()
                            .post(Entity.entity(postData, MediaType.APPLICATION_XML));

                    logger.debug("status:" + uploadResponse.getStatus());

                    if (uploadResponse.getStatus() == Status.OK.getStatusCode()) {
                        logger.info("Component \"" + component.getName() + "\" uploaded with success!");

                    } else {
                        logger.error("Error uploading component \"" + component.getName() + "\"!\n"
                                + uploadResponse.readEntity(String.class));
                    }
                }
            }
        }
        return res;
    }

    /**
     * Method used to print command-line syntax (usage) using
     * {@link HelpFormatter}
     */
    private void printUsage() {
        HelpFormatter helpFormatter = new HelpFormatter();

        PrintWriter systemErrPrintWriter = new PrintWriter(
                new OutputStreamWriter(System.err, Charset.defaultCharset()), true);
        helpFormatter.printHelp(systemErrPrintWriter, HelpFormatter.DEFAULT_WIDTH,
                "\"" + getClass().getSimpleName() + ".jar\"", null, options, HelpFormatter.DEFAULT_LEFT_PAD,
                HelpFormatter.DEFAULT_DESC_PAD, Constants.SCAPE_COPYRIGHT_STATEMENT, true);
    }

    private CommandLine parseArguments(String[] args) throws ErrorParsingCmdArgsException {
        CommandLineParser parser = new PosixParser();
        CommandLine commandLine = null;
        try {
            commandLine = parser.parse(options, args);
        } catch (org.apache.commons.cli.ParseException e) {
            throw new ErrorParsingCmdArgsException(e);
        }
        return commandLine;
    }

    public static void main(String[] args) throws IOException, JAXBException, SAXException {

        int exitCode = 0;

        ComponentUploader componentUploader = new ComponentUploader();

        try {

            CommandLine parseArguments = componentUploader.parseArguments(args);

            logger.debug("<" + parseArguments.getOptionValue("u") + ">\n" + "<" + parseArguments.getOptionValue("p")
                    + ">\n" + "<" + parseArguments.getOptionValue("i") + ">\n" + "<"
                    + parseArguments.getOptionValue("s") + ">\n" + "<" + parseArguments.getOptionValue("t") + ">\n"
                    + "<" + parseArguments.getOptionValue("c") + ">\n" + "<" + parseArguments.getOptionValue("l")
                    + ">\n" + "<" + parseArguments.getOptionValue("d") + ">\n");

            if (!componentUploader.uploadComponentToMyExperiment(parseArguments.getOptionValue("u"),
                    parseArguments.getOptionValue("p"), parseArguments.getOptionValue("i"),
                    parseArguments.getOptionValue("t"), parseArguments.getOptionValue("s"),
                    parseArguments.getOptionValue("c"), parseArguments.getOptionValue("l"),
                    parseArguments.getOptionValue("d"), parseArguments.getOptionValue("e"))) {
                exitCode = 1;
            }
        } catch (ErrorParsingCmdArgsException e) {
            logger.error("[ERROR] " + e.getMessage());
            componentUploader.printUsage();
            exitCode = 2;
        }

        System.exit(exitCode);
    }
}