eu.planets_project.pp.plato.action.workflow.CreateExecutablePlanAction.java Source code

Java tutorial

Introduction

Here is the source code for eu.planets_project.pp.plato.action.workflow.CreateExecutablePlanAction.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 Vienna University of Technology, 
 * Department of Software Technology and Interactive Systems
 *
 * All rights reserved. This program and the accompanying
 * materials are made available under the terms of the
 * Apache License, Version 2.0 which accompanies
 * this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0 
 *******************************************************************************/

package eu.planets_project.pp.plato.action.workflow;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Scanner;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.application.FacesMessage;
import javax.xml.rpc.ServiceException;

import org.apache.commons.logging.Log;
import org.jaxen.JaxenException;
import org.jaxen.jdom.JDOMXPath;
import org.jboss.annotation.ejb.cache.Cache;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import eu.planets_project.pp.plato.action.interfaces.ICreateExecutablePlan;
import eu.planets_project.pp.plato.action.interfaces.IDefinePlan;
import eu.planets_project.pp.plato.action.interfaces.IWorkflowStep;
import eu.planets_project.pp.plato.bean.BooleanCapsule;
import eu.planets_project.pp.plato.model.Alternative;
import eu.planets_project.pp.plato.model.PlanState;
import eu.planets_project.pp.plato.services.action.IPreservationActionRegistry;
import eu.planets_project.pp.plato.services.action.PreservationActionRegistryDefinition;
import eu.planets_project.pp.plato.services.action.PreservationActionRegistryFactory;
import eu.planets_project.pp.plato.services.action.minimee.MiniMeeServiceRegistry;
import eu.planets_project.pp.plato.util.Downloader;
import eu.planets_project.pp.plato.util.PlatoLogger;

@Stateful
@Scope(ScopeType.SESSION)
@Name("createExecutablePlan")
@Cache(org.jboss.ejb3.cache.NoPassivationCache.class)
public class CreateExecutablePlanAction extends AbstractWorkflowStep implements ICreateExecutablePlan {

    /**
     * 
     */
    private static final long serialVersionUID = -5536874272738085658L;

    private static final Log log = PlatoLogger.getLogger(CreateExecutablePlanAction.class);

    @In(create = true)
    IDefinePlan definePlan;

    @Out
    private BooleanCapsule executablePlanPossible = new BooleanCapsule(false);

    @Out
    private BooleanCapsule eprintsExecutablePlanPossible = new BooleanCapsule(false);

    public CreateExecutablePlanAction() {
        requiredPlanState = new Integer(PlanState.ANALYSED);
    }

    protected String getWorkflowstepName() {
        return "createExecutablePlan";
    }

    protected IWorkflowStep getSuccessor() {
        return definePlan;
    }

    /**
     * Is Plato able to create an executable plan? At the moment this 
     * is only possible if the recommended action is a Planets service.
     * 
     * @return true/false if Plato can create an executable plan
     * 
     * @return
     */
    private boolean isExecutablePreservationPlanPossible() {

        Alternative recommendedAlternative = selectedPlan.getRecommendation().getAlternative();

        // does the recommended alternative exist and does it have an "action". if not we can't
        // create an executable preservation plan
        if (recommendedAlternative == null || recommendedAlternative.getAction() == null) {
            return false;
        }

        // if the recommended action is not a Planets action, we cannot create an executable
        // preservation plan
        if (!"Planets-local".equals(recommendedAlternative.getAction().getActionIdentifier())) {
            return false;
        }

        return true;
    }

    public boolean isEprintsPlanPossible() {

        IPreservationActionRegistry registry = getMiniMeeRegistry();

        if (registry == null) {
            return false;
        }

        Alternative recommendedAlternative = selectedPlan.getRecommendation().getAlternative();

        if (recommendedAlternative.getAction() == null) {
            return false;
        }

        if ("MiniMEE-migration".equals(recommendedAlternative.getAction().getActionIdentifier())) {

            String toolIdentifier = getToolIdentifier(registry);

            if (toolIdentifier != null && !"".equals(toolIdentifier)) {
                return true;
            }
        }

        return false;
    }

    private String getToolIdentifier(IPreservationActionRegistry registry) {

        Alternative recommendedAlternative = selectedPlan.getRecommendation().getAlternative();

        String toolIdentifier = registry.getToolIdentifier(recommendedAlternative.getAction().getUrl());

        return toolIdentifier;
    }

    private IPreservationActionRegistry getMiniMeeRegistry() {

        IPreservationActionRegistry registry = null;

        List<PreservationActionRegistryDefinition> list = PreservationActionRegistryFactory
                .getAvailableRegistries();

        PreservationActionRegistryDefinition minimee = null;
        for (PreservationActionRegistryDefinition par : list) {
            if (par.getType().equalsIgnoreCase(MiniMeeServiceRegistry.class.getName())) {
                minimee = par;
                break;
            }
        }

        Alternative recommendedAlternative = selectedPlan.getRecommendation().getAlternative();

        if (minimee != null) {
            registry = PreservationActionRegistryFactory.getInstance(minimee);
        }

        if (registry != null) {
            try {
                registry.connect("");
            } catch (MalformedURLException e) {
            } catch (ServiceException e) {
            }
        }

        return registry;
    }

    public void downloadExecutablePlan() {

        if (selectedPlan.getRecommendation().getAlternative() == null
                || selectedPlan.getRecommendation().getAlternative().getAction() == null) {
            return;
        }

        byte[] plan;
        try {
            plan = selectedPlan.getExecutablePlanDefinition().getExecutablePlan().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Unsupported encoding. " + e.getMessage());
            return;
        }

        if (plan != null) {
            Downloader.instance().download(plan, "executable-preservation-plan.xml", "text/xml");
        }
    }

    public void downloadEprintsExecutablePlan() {

        if (selectedPlan.getRecommendation().getAlternative() == null
                || selectedPlan.getRecommendation().getAlternative().getAction() == null) {
            return;
        }

        byte[] plan;
        try {
            plan = selectedPlan.getExecutablePlanDefinition().getEprintsExecutablePlan().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Unsupported encoding. " + e.getMessage());
            return;
        }

        if (plan != null) {
            Downloader.instance().download(plan, "executable-preservation-plan.xml", "text/xml");
        }
    }

    private void generateExecutablePlan() {

        // this is the recommended action
        String wsdlLocation = selectedPlan.getRecommendation().getAlternative().getAction().getUrl();

        // and this is the target format we want to migrate to
        String targetFormat = selectedPlan.getRecommendation().getAlternative().getAction().getTargetFormat();

        String workflowFile = "data/plans/executables/ExecutablePreservationPlan.xml";
        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(workflowFile);

        // we load the workflow template and fill out the migrate1 service

        SAXBuilder builder = new SAXBuilder();
        Document doc = null;

        try {
            doc = builder.build(in);
        } catch (JDOMException e) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Error in template.");
            log.error(e);
            return;
        } catch (IOException e) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Error in template.");
            log.error(e);
            return;
        }

        Element root = doc.getRootElement();

        try {
            JDOMXPath endpointXPath = new JDOMXPath("services/service[@id='migrate1']/endpoint");

            Element endpoint = (Element) endpointXPath.selectSingleNode(root);

            endpoint.setText(wsdlLocation);

            String settings = selectedPlan.getRecommendation().getAlternative().getExperiment().getSettings();

            if (settings == null) {
                settings = "";
            }

            Scanner scanner = new Scanner(settings);

            JDOMXPath migrateServiceXPath = new JDOMXPath("services/service[@id='migrate1']");

            Element migrateService = (Element) migrateServiceXPath.selectSingleNode(root);

            migrateService.setContent(endpoint);

            Element parameters = new Element("parameters");

            Element targetFormatParam = new Element("param");
            targetFormatParam
                    .addContent(new Element("name").setText("planets:service/migration/input/migrate_to_fmt"));
            targetFormatParam.addContent(new Element("value").setText(targetFormat));
            parameters.addContent(targetFormatParam);

            int index;
            while (scanner.hasNextLine()) {

                String line = scanner.nextLine();

                if ((index = line.indexOf('=')) > 0) {
                    String name = line.substring(0, index);
                    String value = line.substring(index + 1);

                    if (name.length() > 0 && value.length() > 0) {
                        Element param = new Element("param");
                        param.addContent(new Element("name").setText(name.trim()));
                        param.addContent(new Element("value").setText(value.trim()));
                        parameters.addContent(param);
                    }
                }
            }

            migrateService.addContent(parameters);

        } catch (JaxenException e) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Error in template.");
            log.error(e);
            return;
        }

        XMLOutputter outputter = new XMLOutputter();

        ByteArrayOutputStream byteArray = new ByteArrayOutputStream();

        try {
            outputter.output(doc, byteArray);
        } catch (IOException e) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR,
                    "Error writing the preservation plan workflow.");
            log.error(e);

            return;
        }

        selectedPlan.getExecutablePlanDefinition().setExecutablePlan(byteArray.toString());
    }

    private void generateEprintsExecutablePlan() {

        IPreservationActionRegistry registry = getMiniMeeRegistry();

        Alternative recommendedAlternative = selectedPlan.getRecommendation().getAlternative();

        Element eprintsPlan = new Element("eprintsPlan");

        Element tool = new Element("tool");

        eprintsPlan.addContent(tool);

        String id = getToolIdentifier(registry);

        Element toolIdentifier = new Element("toolIdentifier").setAttribute("uri", id);

        tool.addContent(toolIdentifier);

        String settings = selectedPlan.getRecommendation().getAlternative().getExperiment().getSettings();

        String toolParameters = registry.getToolParameters(recommendedAlternative.getAction().getUrl());

        if (settings != null) {
            toolParameters += (" " + settings);
        }

        // TODO: we shouldn't need that here, this should come from the registry
        //       at the moment we only have the OUTFILE which is not enough. we anticipate
        //       that the tool can work with the structure <params> <input file> <output file>
        // CB: from the minimee experience, you CANNOT always assume that!
        // e.g. -i IN -o OUT etc.! or even TOOL -param IN > OUT etc.
        toolParameters += (" " + "%INFILE% %OUTFILE%");

        Element parameters = new Element("parameters").setAttribute("toolParameters", toolParameters);
        tool.addContent(parameters);

        Element targetFormat = new Element("targetFormat")
                .setText(recommendedAlternative.getAction().getTargetFormat());
        tool.addContent(targetFormat);

        XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());

        ByteArrayOutputStream byteArray = new ByteArrayOutputStream();

        try {
            outputter.output(eprintsPlan, byteArray);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        selectedPlan.getExecutablePlanDefinition().setEprintsExecutablePlan(byteArray.toString());
    }

    public boolean validate(boolean showValidationErrors) {

        return true;
    }

    /**
     * Write both plan definition and project properties to database.
     * @see AbstractWorkflowStep#save()
     */
    @Override
    public String save() {

        /** user is set in save() */
        save(selectedPlan.getPlanProperties());
        save(selectedPlan.getExecutablePlanDefinition());
        changed = "";

        return null;
    }

    /**
     * 
     */
    public void init() {

        // If we don't have tool parameters, we copy them from the chosen alternative's config settings:
        if (selectedPlan.getExecutablePlanDefinition().getToolParameters() == null
                || "".equals(selectedPlan.getExecutablePlanDefinition().getToolParameters())) {

            selectedPlan.getExecutablePlanDefinition().setToolParameters(
                    selectedPlan.getRecommendation().getAlternative().getExperiment().getSettings());
        }

        executablePlanPossible.setBool(isExecutablePreservationPlanPossible());
        eprintsExecutablePlanPossible.setBool(isEprintsPlanPossible());

        if (executablePlanPossible.isBool() == true) {
            generateExecutablePlan();
            return;
        }

        if (eprintsExecutablePlanPossible.isBool() == true) {
            generateEprintsExecutablePlan();
            return;
        }

    }

    /**
     * Obligatory EJB destroy method.
     */
    @Destroy
    @Remove
    public void destroy() {
    }
}