Package eu.planets_project.tb.gui.backing.exp

Source Code of eu.planets_project.tb.gui.backing.exp.ExpTypeExecutablePP$ExecutablePPResultsForDO

/*******************************************************************************
* Copyright (c) 2007, 2010 The Planets Project Partners.
*
* 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.tb.gui.backing.exp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.xml.bind.JAXBException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.planets_project.ifr.core.storage.api.DataRegistry;
import eu.planets_project.ifr.core.storage.api.DataRegistryFactory;
import eu.planets_project.ifr.core.storage.api.DigitalObjectManager.DigitalObjectNotFoundException;
import eu.planets_project.ifr.core.wee.api.utils.WorkflowConfigUtil;
import eu.planets_project.ifr.core.wee.api.workflow.WorkflowTemplate;
import eu.planets_project.ifr.core.wee.api.workflow.generated.WorkflowConf;
import eu.planets_project.ifr.core.wee.api.workflow.generated.WorkflowConf.Services;
import eu.planets_project.ifr.core.wee.api.workflow.generated.WorkflowConf.Template;
import eu.planets_project.ifr.core.wee.api.workflow.generated.WorkflowConf.Services.Service;
import eu.planets_project.ifr.core.wee.api.workflow.generated.WorkflowConf.Services.Service.Parameters;
import eu.planets_project.ifr.core.wee.api.workflow.generated.WorkflowConf.Services.Service.Parameters.Param;
import eu.planets_project.ifr.core.wee.api.wsinterface.WftRegistryService;
import eu.planets_project.services.datatypes.DigitalObject;
import eu.planets_project.services.datatypes.Parameter;
import eu.planets_project.services.datatypes.ServiceDescription;
import eu.planets_project.services.migrate.Migrate;
import eu.planets_project.tb.api.data.util.DataHandler;
import eu.planets_project.tb.api.data.util.DigitalObjectRefBean;
import eu.planets_project.tb.api.model.ExperimentExecutable;
import eu.planets_project.tb.api.system.batch.BatchProcessor;
import eu.planets_project.tb.gui.backing.ExperimentBean;
import eu.planets_project.tb.gui.backing.exp.utils.ExpTypeWeeBean;
import eu.planets_project.tb.gui.util.JSFUtil;
import eu.planets_project.tb.impl.AdminManagerImpl;
import eu.planets_project.tb.impl.data.util.DataHandlerImpl;
import eu.planets_project.tb.impl.model.exec.ExecutionRecordImpl;
import eu.planets_project.tb.impl.model.measure.MeasurementImpl;
import eu.planets_project.tb.impl.services.util.wee.WeeRemoteUtil;

/**
*
* A session-scope bean that's backing the executable preservation plan experiment type
*
* @author <a href="mailto:Andrew.Lindley@ait.ac.at">Andrew Lindley</a>
*
*/
public class ExpTypeExecutablePP extends ExpTypeBackingBean implements Serializable,ExpTypeWeeBean{

  /**
   *
   */
  private static final long serialVersionUID = -3669443792175630629L;
  private Log log = LogFactory.getLog(ExpTypeExecutablePP.class);
  private HashMap<String, String> serviceTypes;
  private ArrayList<ServiceBean> serviceBeans;
  //mapping of service IDs in the workflow XML to ServiceBeans
  private HashMap<String, ServiceBean> serviceLookup;
  // This hash maps service endpoints to service names
  private HashMap<String, String> serviceNameMap;
  private WorkflowConfigUtil wfConfigUtil;
  private WorkflowConf wfConf;
  private boolean bValidXMLConfig,bXMLConfigUploaded,bWfTemplateAvailableInRegistry;
    private String xmlConfigFileRef;
    private String wfDescription;
    //for caching purposes when exposing the current xml configuration
    private int currXMLConfigHashCode;
    private String currXMLConfigTempFileURI;
  //Current experiment ID for checking if the reinit must be called.
  //private String currExpId="";
    public static final String EXP_TYPE_SESSION_MAP = "exp_type_executable_pp_sessionMap";
   
 
  public ExpTypeExecutablePP(){
    initBean();
  }
 
  private void initBean(){
    wfConf = null;
    serviceBeans = new ArrayList<ServiceBean>();
    serviceLookup = new HashMap<String, ServiceBean>();
    serviceNameMap = new HashMap<String, String>();
    // build service types map
    serviceTypes = new HashMap<String, String>();
    serviceTypes.put("Characterise",
        "eu.planets_project.services.characterise.Characterise");
    serviceTypes.put("Compare",
        "eu.planets_project.services.compare.Compare");
    serviceTypes.put("Identify",
        "eu.planets_project.services.identify.Identify");
    serviceTypes.put("Migrate",
        "eu.planets_project.services.migrate.Migrate");
    serviceTypes.put("Validate",
        "eu.planets_project.services.validate.Validate");
    serviceTypes.put("Modify", "eu.planets_project.services.modify.Modify");
    serviceTypes.put("CreateView",
        "eu.planets_project.services.view.CreateView");
    serviceTypes.put("ViewAction",
        "eu.planets_project.services.view.ViewAction");
    wfConfigUtil = new WorkflowConfigUtil();
    bValidXMLConfig = false;
    bXMLConfigUploaded = false;
    xmlConfigFileRef = null;
      wfDescription = null;
      bWfTemplateAvailableInRegistry = false;
      currXMLConfigHashCode=0;
      currXMLConfigTempFileURI = null;
  }
 
  /**
   * This method is used to initialize this bean from a given experiment
   * (i.e. WorkflowConf object as it is persisted in the db.)
   * @param wfConf
   */
  @Override
  public void initExpTypeBeanForExistingExperiment(){
   
    //check and try to load from session
    boolean b = initFromCurrentSessionData();
    if(b){
      //we've inited from the session
      return;
    }else{
      //try to load from experiment
      initFromPersistedExperimentData();
   
  }
 
 
  private boolean initFromCurrentSessionData(){
    ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
    if(expBean.getApproved()){
      //if approved we don't init from current session data
      return false;
    }
    long expID = expBean.getID();
    FacesContext ctx = FacesContext.getCurrentInstance();
    HashMap<String,ExpTypeExecutablePP> expTypeSessMap;
        Object o = ctx.getExternalContext().getSessionMap().get(ExpTypeExecutablePP.EXP_TYPE_SESSION_MAP);
        if(o!=null){
          expTypeSessMap = (HashMap<String,ExpTypeExecutablePP>)o;
          ExpTypeExecutablePP sessBean = expTypeSessMap.get(expID+"");
          if(sessBean!=null){
            //now exchange the session variable with the one we've stored
            ctx.getExternalContext().getSessionMap().put("ExpTypeExecutablePP",sessBean);
            return true;
          }
          else
            return false;
        }
        return false;
  }
 
 
  private void initFromPersistedExperimentData(){
    //1) reinit the bean
    initBean();
   
    //fetch the data to populate from
    ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
    if(expBean.getExperiment()==null){
      //this is the case when the 'new experiment' hasn't been persisted
      return;
    }
    WorkflowConf storedConf = expBean.getExperiment().getExperimentExecutable().getWEEWorkflowConfig();
 
    //2) possibly populate bean from stored information
    if(storedConf!=null){ 
      this.setWeeXMLConfig(storedConf);
      //and call the populate from wfConfig method
          populateServiceInformationFromWorkflowConfig();
          this.setXMLConfigFileProvided(true);
          //fill additional required gui information
          this.setWeeXMLConfigFileRef("empty");
          this.setXMLConfigFileProvided(true);
          this.setXMLConfigValid(true);
         
          //check if the template is still available on the wee system
          WftRegistryService wftRegistryService = WeeRemoteUtil.getInstance().getWeeRegistryService();
      if (wftRegistryService.getAllSupportedQNames().contains(storedConf.getTemplate().getClazz())){
        this.setTemplateAvailableInWftRegistry(true);
      }else{
        this.setTemplateAvailableInWftRegistry(false);
      }
    }
  }
 
  /**
   * Takes the bean's information and persist it into the testbed's db model
   * i.e. the experiment's executable.setWorkflowConfig method
   */
  @Override
  public void saveExpTypeBean_Step2_WorkflowConfiguration_ToDBModel(){
    ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
        //store information in the db entities
    ExperimentExecutable expExecutable = expBean.getExperiment().getExperimentExecutable();
        expExecutable.setWEEWorkflowConfig(this.buildWorkflowConfFromCurrentConfiguration());
        //specify which batch processing system WEE or TB/Local we want to use for this experiment
        expExecutable.setBatchSystemIdentifier(BatchProcessor.BATCH_QUEUE_TESTBED_WEE_LOCAL);
        expBean.updateExperiment();
  }
 
 
  /*
   * TODO AL: version 1.0 uses this structure to check for a valid workflow (exp-type specific) configuration.
   * (non-Javadoc)
   * @see eu.planets_project.tb.gui.backing.exp.ExpTypeBackingBean#checkExpTypeBean_Step2_WorkflowConfigurationOK()
   */
  @Override
  public void checkExpTypeBean_Step2_WorkflowConfigurationOK() throws Exception{
   
    //1. check valid configuration file provided
    if(!this.isValidXMLConfig()){
      throw new Exception("The provided workflow configuration file is not valid");
   
    //2 check workflow available on system
    if(!isTemplateAvailableInWftRegistry()){
      throw new Exception("The selected workflow is not available on the execution engine - please contact Testbed helpdesk");
    }
    //3 check all selected services available
    if(!helperCheckAllSelectedServicesAvailable()){
      throw new Exception("One or more selected services are not available within the Testbed - please contact Testbed helpdesk");
    }
  }
 
 
  /**
   * Checks if all specified/selected services are registered within the
   * service registry.
   * @return
   */
  private boolean helperCheckAllSelectedServicesAvailable(){
    boolean bOK = true;
    for(ServiceBean sb : this.getAllCurrentlyUsedServices()){
      if(!sb.isServiceAvailable()){
        bOK = false;
      }
    }
    return bOK;
  }
 
  /**
   * Returns a List of ServiceBean objects containing information for
   * all services that are currently used within the worfklow configuration
   * @return
   */
  public List<ServiceBean> getAllCurrentlyUsedServices(){
    return this.serviceBeans;
  }
 
  /**
   * reinits the bean for the step where an template gets uploaded
   */
  public void reInitBeanForWFXMLConfigUploaded(){
    this.initBean();
  }
 
 
  HashMap<String,List<MeasurementImpl>> manualObsCache;
    long cacheExperimentID;
  /* (non-Javadoc)
   * @see eu.planets_project.tb.gui.backing.exp.ExpTypeBackingBean#getManualObservables()
   */
  @Override
  public HashMap<String, List<MeasurementImpl>> getManualObservables() {
    ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
      if(manualObsCache==null||(cacheExperimentID != expBean.getExperiment().getEntityID())){
        cacheExperimentID = expBean.getExperiment().getEntityID();
       
          //query for properties that have been added from the Ontology
          HashMap<String,Vector<String>> ontoPropIDs = new HashMap<String, Vector<String>>();
          for(ExperimentStageBean stage : expBean.getStages()){
            ontoPropIDs.put(stage.getName(),expBean.getExperiment().getExperimentExecutable().getManualProperties(stage.getName()));
          }
         
          //this is the static list of manual properties - normally empty
          HashMap<String,List<MeasurementImpl>> staticWFobs = getWorkflow(AdminManagerImpl.EXECUTABLEPP).getManualObservables();
         
          //FIXME AL: staticWFobs returns wrong items - where are they added - exclude staticWFobs for now
          //manualObsCache = mergeManualObservables(staticWFobs, ontoPropIDs);
          manualObsCache = mergeManualObservables(null, ontoPropIDs);
      }
      return manualObsCache;
  }

  /* (non-Javadoc)
   * @see eu.planets_project.tb.gui.backing.exp.ExpTypeBackingBean#getObservables()
   */
  @Override
  public HashMap<String, List<MeasurementImpl>> getObservables() {
    return getWorkflow(AdminManagerImpl.EXECUTABLEPP).getObservables();
  }

  /* (non-Javadoc)
   * @see eu.planets_project.tb.gui.backing.exp.ExpTypeBackingBean#getStageBeans()
   */
  @Override
  public List<ExperimentStageBean> getStageBeans() {
     return getWorkflow(AdminManagerImpl.EXECUTABLEPP).getStages();
  }
 
  // ---------- INFORMATION FOR STAGE2 --------------
  public boolean isValidXMLConfig(){
    return bValidXMLConfig;
  }
 
  public void setXMLConfigValid(boolean valid){
    this.bValidXMLConfig = valid;
  }
   
  public boolean isXMLConfigFileProvided(){
    return bXMLConfigUploaded;
  }
 
  public void setXMLConfigFileProvided(boolean provided){
    this.bXMLConfigUploaded = provided;
  }
 
    /**
     * A pointer to the uploaded xml config file that was submitted to the system
     * @param fileRef
     */
    public void setWeeXMLConfigFileRef(String fileRef){
      this.xmlConfigFileRef = fileRef;
    }
   
    public String getWeeXMLConfigFileRef(){
      if(xmlConfigFileRef == null)
        return "";
      return xmlConfigFileRef;
    }
   
    public void setWeeXMLConfig(WorkflowConf wfConfig){
      this.wfConf = wfConfig;
    }
   
    /**
     * The original xmlConfig file that was submitted by the user - it does not contain any changes made during
     * step2 editParameters
     * @return
     */
    public WorkflowConf getWeeXMLConfig(){
      return wfConf;
    }
   
   
    public void checkAndParseWorkflowConfigObject(String fileRef) throws Exception{
      try {
        String xmlConfigContent = helperReadDigoToString(fileRef);
          //check validity against schema
          wfConfigUtil.checkValidXMLConfig(xmlConfigContent);
          //unmarshall the object with JAXB
          WorkflowConf config = WorkflowConfigUtil.unmarshalWorkflowConfig(xmlConfigContent);
         
          //fill the with information
          this.setWeeXMLConfigFileRef(fileRef);
          this.setXMLConfigFileProvided(true);
          this.setWeeXMLConfig(config);
          this.setXMLConfigValid(true);
          log.debug("Workflow XML config file valid and properly parsed - configuration written to bean for workflow: "+config.getTemplate().getClazz());
   
    } catch (DigitalObjectNotFoundException e) {
      this.setXMLConfigFileProvided(false);
      throw e;
    } catch (URISyntaxException e) {
      this.setXMLConfigFileProvided(false);
      throw e;
    } catch (IOException e) {
      this.setXMLConfigFileProvided(false);
      throw e;
    } catch (JAXBException e) {
      this.setXMLConfigValid(false);
      throw e;
    }
    }
   
    /**
     * A helper to read the content of a xmlConfigFile from a given ref location into a String
     * @param fileRef
     * @return
     * @throws IOException
     * @throws DigitalObjectNotFoundException
     * @throws URISyntaxException
     */
    private String helperReadDigoToString(String fileRef) throws IOException, DigitalObjectNotFoundException, URISyntaxException{
      DataRegistry digoManager = DataRegistryFactory.getDataRegistry();
      URI uriRef = new URI(fileRef);
      this.log.info("Retrieving Digital Object at " + uriRef);
    DigitalObject xmlTemplateDigo = digoManager.retrieve(new URI(fileRef));
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(xmlTemplateDigo.getContent().getInputStream()));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;

        while ((line = bufferedReader.readLine()) != null) {
        stringBuilder.append(line + "\n");
        }
        bufferedReader.close();
        return stringBuilder.toString();
    }
   
    /**
     * Takes the current configuration (which may consist of
     * a) an uploaded xml configuration,
     * b) the altered parameter and service selection in step2 and
     * marshalls all this into an WorkflowConf object
     * wich may be offered to the client for downloading (by serealizing it to XML) or for submitting it to the wee (WorkflowFactory).
     * @return
     */
    public WorkflowConf buildWorkflowConfFromCurrentConfiguration(){
      String wfConfigXML = this.buildXMLConfigFromCurrentConfiguration();
      try {
      return WorkflowConfigUtil.unmarshalWorkflowConfig(wfConfigXML);
    } catch (JAXBException e) {
      log.debug("Unable to retrieve the WorkflowConfiguration",e);
      return null;
    }
    }
   
    /**
     * Is the same as buildWorkflowConfFromCurrentConfiguration but returns the xml representation
     * instead of the WorkflowConf object. This may be offered for downloading.
     * @see buildWorkflowConfFromCurrentConfiguration
     * @return
     */
    public String buildXMLConfigFromCurrentConfiguration(){
      WorkflowConf conf = new WorkflowConf();
     
      //1.add the template retrieved from the uploaded wfconfig
      Template serTempl = this.getWeeXMLConfig().getTemplate();
     
      Services services = new Services();
      //2.browse through the servicebeans and build the Services object
      for(ServiceBean sb : this.getServiceBeans()){
        Service service = new Service();
        service.setId(sb.getServiceId());
        service.setEndpoint(sb.getServiceEndpoint());
       
        Parameters parameters = new Parameters();
        //3. iterate over all parameters that have been created/altered
        for(ServiceParameter param : sb.getServiceParameters()){
          Param parameter = new Param();
          parameter.setName(param.getName());
          parameter.setValue(param.getValue());
          parameters.getParam().add(parameter);
        }
        if(parameters.getParam().size()>0){
          //there needs to be a Parameter element only if there's a param for being xsd compliant
          service.setParameters(parameters);
        }
       
        services.getService().add(service);
      }
     
      conf.setServices(services);
      conf.setTemplate(serTempl);
     
      try {
      return wfConfigUtil.marshalWorkflowConfigToXMLTemplate(conf);
    } catch (Exception e) {
      log.debug("Unable to retrieve the XMLWorkflowConfiguration",e);
      return null;
    }
    }
   
    /**
     * Builds the currentXMLConfig from the given service/param configuration
     * and writes it to a temporary file that's accessible via an external url ref.
     * This can be used within the browser to download the currentXMLConfig
     * @return
     */
    public String getTempFileDownloadLinkForCurrentXMLConfig(){
    DataHandler dh = new DataHandlerImpl();
    String currXMLConfig = buildXMLConfigFromCurrentConfiguration();
    if(currXMLConfig==null){
      return null;
    }
    //save it's hashcode - for caching purposes
    if((this.currXMLConfigHashCode!=-1)&&(this.currXMLConfigHashCode!=currXMLConfig.hashCode())){
      this.currXMLConfigHashCode =  currXMLConfig.hashCode();
     
      try {
        //get a temporary file
        File f = dh.createTempFileInExternallyAccessableDir();
        Writer out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(f), "UTF-8" ) );
        out.write(currXMLConfig);
        out.close();
        currXMLConfigTempFileURI = ""+dh.getHttpFileRef(f);
        return currXMLConfigTempFileURI;
      } catch (Exception e) {
        log.debug("Error getting TempFileDownloadLinkForCurrentXMLConfig "+e);
        return null;
      }
    }
    else{
      //FIXME: still missing to check if this temp file ref still exists
      //returned the cached object
      return this.currXMLConfigTempFileURI;
    }
   
    }
  
   
    public boolean isTemplateAvailableInWftRegistry(){
      return bWfTemplateAvailableInRegistry;
    }
   
    public void setTemplateAvailableInWftRegistry(boolean available){
      bWfTemplateAvailableInRegistry = available;
    }
   
    public void setWFDescription(String description){
      wfDescription = description;
    }
   
    public String getWFDescription(){
      return this.wfDescription;
    }
   
    /**
     * Looks for the "public String describe()" method, creates a substring until the next appearance of "}"
     * and finally runs a regexp to remove special chars.
     * @param javafile
     * @return
     */
    public String helperParseDescription(String content){
      String token1 = "public String describe() {";
      String token2 = "}";
      String regexp = "[a-z A-Z 0-9 () . \\\\s]+";
     
      int itoken1 = content.indexOf(token1);
      if(content.indexOf(token1)!=-1){
        int itoken2 = content.indexOf(token2,itoken1);
        if(itoken2!=-1){
          String text = content.substring(itoken1+token1.length(), itoken2);
          Pattern urlpattern = Pattern.compile(regexp);
          Matcher m = urlpattern.matcher(text);
          StringBuffer buff = new StringBuffer();
          buff = m.appendTail(buff);
          return buff.toString();
        }
      }
      return null;
    }
   
   
    /**
     * Extracts Service Endpoint and Parameter information from a given xml configuration
     * and queries the service registry to retrieve Service type, etc. and checks if it's registered
     */
    public void populateServiceInformationFromWorkflowConfig(){
      WorkflowConf wfConfig = this.getWeeXMLConfig();
      Services services = wfConfig.getServices();
      if(services==null)
        return;
      List<Service> lServices = services.getService();
      //now iterate over all declared services from the config
      for(Service service : lServices){
        if(service.getId()!=null){
          ServiceBean sb = new ServiceBean(service.getId());
          //check if we've got a valid endpoint
          if(service.getEndpoint()!=null){
            sb.setServiceEndpoint(service.getEndpoint());
            //now query the service registry for this endpoint..
            try {
              //fetch the metadata from the service registry - but no default params
              helperGetMetadataFromSerRegistry(sb,service.getEndpoint(),false);
             
            } catch (Exception ex) {
              log.debug("Unable to lookup service endpoint: "+ service.getEndpoint()+ex);
            }
          }
          else{
            //no service endpoint was provided
            log.debug("Found a service element with no endpoint: ");
          }
          //now Iterate over all params that were passed along
          if(service.getParameters()!=null){
            for(Param param : service.getParameters().getParam()){
              String pName = param.getName();
              String pValue = param.getValue();
              if((pName!=null)&&(pValue!=null)){
                //add them to the WfServiceBean
                ServiceParameter sp = new ServiceParameter(
                  pName, pValue);
               
                sb.addParameter(sp);
              }
            }
          }
          serviceBeans.add(sb);
        serviceLookup.put(service.getId(), sb);
       
        else{
          log.debug("Found a service element with no Id");
        }
      }
    }
   
    /**
     * Retrieves all available metadata (service description, name, type, etc.) from the service registry
     * and updates this information on the given ServiceBean.
     * invokes getServiceDescirptionFromServiceRegistry()
     * @param sb
     * @param sEndpoint
     * @param addDefaultParams allows to trigger if the default parameters shall be added to the service bean as standard parameters
     * @return
     * @throws Exception
     * @throws MalformedURLException
     */
    private ServiceDescription helperGetMetadataFromSerRegistry(ServiceBean sb, String sEndpoint, boolean addDefaultParamsAsStandardParams) throws Exception{
      try{
        ServiceDescription sdesc = getServiceDescirptionFromServiceRegistry(sEndpoint);
        sb.setServiceName(sdesc.getName());
      String serType = sdesc.getType();
      sb.setServiceDescription(sdesc.getDescription());
      sb.setServiceType(serType.substring(serType
          .lastIndexOf('.') + 1));
     
      //get default parameters for Service
      List<Parameter> pList = sdesc.getParameters();
      if (pList != null) {
        Iterator<Parameter> it = pList.iterator();
        while (it.hasNext()) {
          Parameter par = it.next();
          ServiceParameter spar = new ServiceParameter(par
              .getName(), par.getValue());
          //decide if the default params are added as standard params
          if(addDefaultParamsAsStandardParams){
            sb.addParameter(spar);
          }
          //add the default params to the bean
          sb.addDefaultParameter(spar);
        }
      } else {
        log.info("Service: " + sdesc.getName() +" has no default parameters.");
      }

      //FIXME: dirty solution. Offer the migrate_from and migrate_to parameters for type 'Migrate' service
      //TODO offer a pull down list for mime-types
      if(serType.endsWith(Migrate.NAME)){
        if((!sb.getDefaultServiceParameters().contains(WorkflowTemplate.SER_PARAM_MIGRATE_FROM))){
          ServiceParameter spar = new ServiceParameter(WorkflowTemplate.SER_PARAM_MIGRATE_FROM,"planets:fmt/ext/png");
          sb.addDefaultParameter(spar);
        }
        if((addDefaultParamsAsStandardParams)&&(!sb.getServiceParameters().contains(WorkflowTemplate.SER_PARAM_MIGRATE_FROM))){
          ServiceParameter spar = new ServiceParameter(WorkflowTemplate.SER_PARAM_MIGRATE_FROM,"planets:fmt/ext/png");
          sb.addParameter(spar);
        }
        if((!sb.getDefaultServiceParameters().contains(WorkflowTemplate.SER_PARAM_MIGRATE_TO))){
          ServiceParameter spar = new ServiceParameter(WorkflowTemplate.SER_PARAM_MIGRATE_TO,"planets:fmt/ext/png");
          sb.addDefaultParameter(spar);
        }
        if((addDefaultParamsAsStandardParams)&&(!sb.getServiceParameters().contains(WorkflowTemplate.SER_PARAM_MIGRATE_TO))){
          ServiceParameter spar = new ServiceParameter(WorkflowTemplate.SER_PARAM_MIGRATE_TO,"planets:fmt/ext/png");
          sb.addParameter(spar);
        }
      }
     
      sb.setServiceAvailable(true);
      return sdesc;
      }catch(Exception e){
      sb.setServiceAvailable(false);
      sb.setRequestedServiceEndpoint(sEndpoint);
      throw e;
      }
    }
   
    /**
     * retrieves a service description from the service registry if there's only exact one endpoint matching the query
     * @param sEndpoint
     * @return
     * @throws Exception
     */
    private ServiceDescription getServiceDescirptionFromServiceRegistry(String sEndpoint) throws Exception{
      URL sendsURL = new URL(sEndpoint);
    List<ServiceDescription> regSer = registry
        .query(new ServiceDescription.Builder(null,
            null).endpoint(sendsURL).build());
    if ((regSer.size() < 1)||(regSer.size() > 1)) {
      String err = "Unable to find service corresponding to endpoint or uniquly identifying it: "+ sendsURL;
      log.debug(err);
      throw new Exception(err);
    }
    else{
      ServiceDescription sdesc = regSer.get(0);
      return sdesc;
    }
    }

   
    public void serviceSelectionChanged(ValueChangeEvent event) {
      //HtmlInplaceSelect sel = (HtmlInplaceSelect) event.getComponent();
      HtmlSelectOneMenu sel = (HtmlSelectOneMenu) event.getComponent();
      String selServiceEndpoint = (String)event.getNewValue();
     
      FacesContext context = FacesContext.getCurrentInstance();
    Object o1 = context.getExternalContext().getRequestParameterMap().get("selServiceID");
    String sForServiceID;
    if(o1!=null){
      sForServiceID = (String)o1;
    }
    else{return;}
    ServiceBean serviceBean = serviceLookup.get(sForServiceID);
    if (serviceBean == null) {
      log.debug("Unable to lookup service bean with ID: "+ sForServiceID);
      return;
    }
    if (selServiceEndpoint.equals("None")) {
      serviceBean.setServiceName("None");
      serviceBean.setServiceEndpoint("");
      serviceBean.setServiceDescription("");
      serviceBean.clearParameters();
      return;
    }
    String selServiceName = serviceNameMap.get(selServiceEndpoint);
    if (selServiceName == null) {
      log.debug("Unable to lookup service name for endpoint: "+ selServiceEndpoint);
      return;
    }
    serviceBean.clearParameters();
    try {
      //query the registry and update the serviceBean with all the information found
      this.helperGetMetadataFromSerRegistry(serviceBean,selServiceEndpoint,true);
     
    }catch(Exception e){
      log.debug("Unable to lookup service with endpoint: "+selServiceEndpoint);
    }

    serviceBean.setServiceName(selServiceName);
    serviceBean.setServiceEndpoint(selServiceEndpoint);
    }
   
   
  public List<ServiceBean> getServiceBeans() {
    return serviceBeans;
  }    
 

  /**
   * A backing bean for handling services contained in the surrounding workflow
   *
   */
  public class ServiceBean implements Cloneable,Serializable{

    /**
     *
     */
    private static final long serialVersionUID = 5558546200237525470L;
    private String serviceId;
    private String serviceType;
    private String serviceName;
    private String serviceEndpoint;
    private String serviceDescription="";
    private ArrayList<ServiceParameter> serviceParameters;
    private ArrayList<SelectItem> serviceNames;
    private boolean bServiceAvailable = false;
    private ArrayList<ServiceParameter> defaultParameters;

    public ServiceBean() {
      this.serviceName = "None";
      this.serviceParameters = new ArrayList<ServiceParameter>();
      this.defaultParameters = new ArrayList<ServiceParameter>();
    }

    public ServiceBean(String id) {
      this.serviceId = id;
      this.serviceName = "None";
      this.serviceParameters = new ArrayList<ServiceParameter>();
      this.defaultParameters = new ArrayList<ServiceParameter>();
    }
   
    public boolean isServiceAvailable(){
      return bServiceAvailable;
    }

    /**
     * Indicates if a service is available to the system the wftemplate is triggered from
     * i.e. from the local service registry
     * @param available
     */
    public void setServiceAvailable(boolean available){
      bServiceAvailable = available;
   
   
    private String sRequestedServiceEndpoint="";
    /**
     * Even if a endpoint is not registered in the service registry we're storing
     * it here to tell a user to register if for using it within this workflow
     * @return
     */
    public String getRequestedServiceEndpoint(){
      return sRequestedServiceEndpoint;
    }
   
    public void setRequestedServiceEndpoint(String s){
      if(s!=null){
        sRequestedServiceEndpoint = s;
      }
    }

    public String getServiceId() {
      return serviceId;
    }

    public String getServiceType() {
      return serviceType;
    }

    public String getServiceName() {
      return serviceName;
    }
   
    public String getServiceDescription(){
      return serviceDescription;
    }
   
    public void setServiceDescription(String s){
      if(s!=null){
        serviceDescription =s;
      }
    }

    public String getServiceEndpoint() {
      return serviceEndpoint;
    }

    public List<ServiceParameter> getServiceParameters() {
      return serviceParameters;
    }
   
    /**
     * Checks if a given ServiceParameterName is already contained in the list
     * off added ServiceParameters
     * @param paramName
     * @return
     */
    private ServiceParameter getServiceParamContained(String paramName){
      for(ServiceParameter sp : this.getServiceParameters()){
        if(sp.getName().equals(paramName)){
          return sp;
        }
      }
      return null;
    }

    public void setServiceId(String id) {
      this.serviceId = id;
    }

    public void setServiceType(String type) {
      this.serviceType = type;
      serviceNames = new ArrayList<SelectItem>();
      serviceNames.add(new SelectItem("None", "Select an Endpoint..."));
      serviceNames.add(new SelectItem("None", "None"));
      if (serviceType != null) {
        String serviceClass = serviceTypes.get(serviceType);
        List<ServiceDescription> services = registry
            .query(new ServiceDescription.Builder(null,
                serviceClass).build());
        Iterator<ServiceDescription> it = services.iterator();
        while (it.hasNext()) {
          ServiceDescription sd = it.next();
          serviceNames.add(new SelectItem(
              sd.getEndpoint().toString(), sd.getName()));
          serviceNameMap.put(sd.getEndpoint().toString(), sd
              .getName());
        }
      }
    }

    public void setServiceName(String name) {
      this.serviceName = name;
    }

    public void setServiceEndpoint(String endpoint) {
      this.serviceEndpoint = endpoint;
    }

    public void addParameter(ServiceParameter par) {
      //ServiceParameters names need to be used uniquely - decide update or new
      ServiceParameter spUpdate = this.getServiceParamContained(par.getName());
      if(spUpdate!=null){
        //delete
        this.removeParameter(spUpdate);
      }
      //finally add add
      this.serviceParameters.add(par);
    }

    public void removeParameter(ServiceParameter par) {
      this.serviceParameters.remove(par);
    }

    public List<SelectItem> getEndpointOptions() {
      if (serviceNames == null) {
        serviceNames = new ArrayList<SelectItem>();
        serviceNames
            .add(new SelectItem("None", "Select an Endpoint..."));
        serviceNames.add(new SelectItem("None", "None"));
      }
      return serviceNames;
    }

    public void clearParameters() {
      this.serviceParameters.clear();
      this.defaultParameters.clear();
    }
   
    public void addDefaultParameter(ServiceParameter param){
      this.getDefaultServiceParameters().add(param);
    }
   
    /**
     * Contains the default parameters as provided through the service registry
     * This field may not be populated for every item
     * @return
     */
    public List<ServiceParameter> getDefaultServiceParameters() {
      return this.defaultParameters;
    }
   
   
   
    /*
     * clone the object and create a deep copy for the serviceParameter to decouple them from the original object
     * this allows its usage on the edit Screen
     */
    public ServiceBean clone(){
      try{
        ServiceBean clonedSB = (ServiceBean)super.clone();
        clonedSB.serviceParameters = new ArrayList<ServiceParameter>();
       
        for(ServiceParameter param : this.getServiceParameters()){
          clonedSB.serviceParameters.add(param.clone());
        }
        return clonedSB;
      }catch(Exception e){
        log.error("Clone ServiceBean not supported"+e);
        return null;
      }
    }
  }

  public class ServiceParameter implements Cloneable,Serializable{
    /**
     *
     */
    private static final long serialVersionUID = -2362976530899676720L;
    private String name;
    private String value;

    public ServiceParameter() {
    }

    public ServiceParameter(String n, String v) {
      this.name = n;
      this.value = v;
    }

    public String getName() {
      return this.name;
    }

    public String getValue() {
      return this.value;
    }

    public void setName(String n) {
      this.name = n;
    }

    public void setValue(String v) {
      this.value = v;
    }
   
    public ServiceParameter clone(){
      try {
        return (ServiceParameter) super.clone();
      } catch (CloneNotSupportedException e) {
        log.error("Clone not supported for ServiceParameter "+e);
        return null;
      }
    }
  }
 
    /* ------------------------------------------- */
   
    /**
     * A Bean to hold the results on each digital object.
     */
    public class ExecutablePPResultsForDO  extends ResultsForDigitalObjectBean implements Serializable{

    /**
     *
     */
    private static final long serialVersionUID = 8115319442858925163L;

    public ExecutablePPResultsForDO(String input) {
      super(input);
    }
   
    public List<ExecutablePPResultBean> getMigrations() {
            List<ExecutablePPResultBean> migs = new Vector<ExecutablePPResultBean>();
            int i = 1;
            for( ExecutionRecordImpl exerec : this.getExecutionRecords() ) {
                migs.add(new ExecutablePPResultBean( i, exerec ) );
                i++;
            }
            return migs;
        }
    }
   
    public class ExecutablePPResultBean implements Serializable{

        /**
     *
     */
    private static final long serialVersionUID = -9171518810708157936L;
    private int batchId;
        @SuppressWarnings("unused")
    private ExecutionRecordImpl exerec;
        private Properties props;

        /**
         * @param exerec
         */
        public ExecutablePPResultBean(int batchId, ExecutionRecordImpl exerec) {
            this.batchId = batchId;
            this.exerec = exerec;
            try {
        props =  exerec.getPropertiesListResult();
      } catch (IOException e) {
        log.debug("No Properties recorded for the batch: "+batchId);
        props = new Properties();
      }
        }
       
       
        /**
         * get the DigoResult object if there's one
         * @return
         */
        public String getDigitalObjectResult() {
      Object tbDigoURI = props.get(ExecutionRecordImpl.RESULT_PROPERTY_URI);
            String summary = "Run "+batchId+": ";
            if( tbDigoURI != null ) {
                DataHandler dh = new DataHandlerImpl();
                DigitalObjectRefBean dobr;
                try {
                    dobr = dh.get((String)tbDigoURI);
                } catch (FileNotFoundException e) {
                    log.error("Could not find file. "+e);
                    return "";
                }
                summary += dobr.getName();
                long size = dobr.getSize();
                if( size >= 0 ) {
                    summary += " ("+size+" bytes)";
                }
                return summary;
            }
            summary += "No Result.";
            return summary;
        }
       
        /**
         * Gets a String represenation of all information that was logged for the workflow
         * except pointers to migration_results or migration_interim_results
         * @return
         */
        public List<String> getResultProperties() {
      List<String> ret = new ArrayList<String>();
      Enumeration<?> enumeration = props.keys();
      while(enumeration.hasMoreElements()){
        String key = (String)enumeration.nextElement();
        String value = props.getProperty(key);
        if(!key.startsWith(ExecutionRecordImpl.RESULT_PROPERTY_URI)){
          ret.add("["+key+"= "+value+"]");
        }
      }
      // Sort list in Case-insensitive sort
            Collections.sort(ret, String.CASE_INSENSITIVE_ORDER);
      return ret; 
        }
       
        /**
         * If any migration took place: link the interim digos in the GUI
         * @return
         */
        public List<ResultsForDigitalObjectBean> getInterimResults() {
          //List<String> ret = new ArrayList<String>();
          List<ResultsForDigitalObjectBean> ret = new ArrayList<ResultsForDigitalObjectBean>();
      Enumeration<?> enumeration = props.keys();
      while(enumeration.hasMoreElements()){
        String key = (String)enumeration.nextElement();
        props.getProperty(key);
        //keys start with the
        if(key.startsWith(ExecutionRecordImpl.RESULT_PROPERTY_INTERIM_RESULT_URI)){
          ResultsForDigitalObjectBean r = new ResultsForDigitalObjectBean(props.getProperty(key));
          ret.add(r);
        }
      }
      // Sort list in Case-insensitive sort
            //Collections.sort(ret, String.CASE_INSENSITIVE_ORDER);
      return ret; 
        }
       
        /**
         * @return
         */
        public String getDigitalObjectDownloadURL() {
          Object tbDigoURI = props.get(ExecutionRecordImpl.RESULT_PROPERTY_URI);
          return getDigitalObjectDownloadURL(tbDigoURI);
        }
       
        public String getDigitalObjectURI() {
          Object tbDigoURI = props.get(ExecutionRecordImpl.RESULT_PROPERTY_URI);
          if(tbDigoURI!=null){
            return (String)tbDigoURI;
          }
          return null;
        }
       
        /**
         * Creates an external http:// object ref for any TB datamanager ref.
         * e.g. https://localhost:8443/testbed/reader/download.jsp?fid=file%253A%252FD%253A%252FImplementation%252Fifr_server%252Fplanets-ftp%252Fusa_bundesstaaten_png.png
         * @return
         */
        private String getDigitalObjectDownloadURL(Object tbDigoURI) {
            if( tbDigoURI != null ) {
                DataHandler dh = new DataHandlerImpl();
                try {
                    DigitalObjectRefBean dobr = dh.get((String)tbDigoURI);
                    return dobr.getDownloadUri().toString();
                } catch (FileNotFoundException e) {
                    log.error("Failed to generate download URL. " + e);
                    return "";
                }
            }
            return "";
        }
       
    }
   
   
    /**
     * @return
     */
    public List<ExecutablePPResultsForDO> getExecutablePPResults() {
        ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
        List<ExecutablePPResultsForDO> results = new Vector<ExecutablePPResultsForDO>();
        // Populate using the results:
        for( String file : expBean.getExperimentInputData().values() ) {
          ExecutablePPResultsForDO res = new ExecutablePPResultsForDO(file);
            results.add(res);
        }

        // Now return the results:
        return results;
    }

  /* (non-Javadoc)
   * @see eu.planets_project.tb.gui.backing.exp.ExpTypeBackingBean#isExperimentBeanType()
   */
  @Override
  public boolean isExperimentBeanType() {
    ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
        if( expBean == null ) return false;
    if( AdminManagerImpl.EXECUTABLEPP.equals(expBean.getEtype()) ) return true;
    return false;
  }

  /** {@inheritDoc}
   * This is the callback method for the edit-param bean for passing out existing parameter values
   * */
  @Override
  public Map<String, List<Parameter>> getWorkflowParameters() {
    Map<String, List<Parameter>> ret = new HashMap<String, List<Parameter>>();
    // populate the data for the add/edit params (a separate managed bean)
    for(ServiceBean sb : this.getServiceBeans()){
      List<Parameter> lParam = new ArrayList<Parameter>();
        String serID = sb.getServiceId();
       
        //3. iterate over all parameters that have been created/altered
        for(ServiceParameter param : sb.getServiceParameters()){
          Parameter parameter = new Parameter(param.getName(),param.getValue());
          lParam.add(parameter);
        }
        ret.put(serID, lParam);
      }
    return ret;
  }

  /** {@inheritDoc}
   * This is the callback method for the edit-param bean for writing back modified parameter values
   * */
  @Override
  public void setWorkflowParameters(Map<String,List<Parameter>> params) {
    //adapted when moving to the add/edit params in a separate managed bean
    if(params!=null){
      for(String serviceID : params.keySet()){
        ServiceBean sb = serviceLookup.get(serviceID);
       
        //store old migrate_to and migrate_from and use if they were deleted
        ServiceParameter pFromOld = sb.getServiceParamContained(WorkflowTemplate.SER_PARAM_MIGRATE_FROM);
        ServiceParameter pToOld = sb.getServiceParamContained(WorkflowTemplate.SER_PARAM_MIGRATE_TO);
       
        //clear old parameters and add the ones that are handed over here
        sb.clearParameters();
        for(Parameter p : params.get(serviceID)){
          sb.addParameter(new ServiceParameter(p.getName(),p.getValue()));
        }
       
        //check if we haven't lost the migrate_to and _from parameters
        if(sb.getServiceParamContained(WorkflowTemplate.SER_PARAM_MIGRATE_FROM)==null){
          sb.addDefaultParameter(pFromOld);
        }
        if(sb.getServiceParamContained(WorkflowTemplate.SER_PARAM_MIGRATE_TO)==null){
          sb.addDefaultParameter(pToOld);
        }
      }
    }
  }
 

  /** {@inheritDoc} */
  public WorkflowConf getWeeWorkflowConf() {
    ExperimentBean expBean = (ExperimentBean)JSFUtil.getManagedObject("ExperimentBean");
   
    if(!expBean.getApproved()){
      //that's the one used when building this in 'design experiment'
      return this.buildWorkflowConfFromCurrentConfiguration();
        }
    if(expBean.getApproved()){
      //that's the one after 'design experiment' has been saved
      ExperimentExecutable expExecutable = expBean.getExperiment().getExperimentExecutable();
      return expExecutable.getWEEWorkflowConfig();
        }
    return null;
  }

  /** {@inheritDoc} */
  public boolean isValidCurrentConfiguration() {
    return isValidXMLConfig();
  }
 

}
TOP

Related Classes of eu.planets_project.tb.gui.backing.exp.ExpTypeExecutablePP$ExecutablePPResultsForDO

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.