Java tutorial
/******************************************************************************* * 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() { } }