eu.planets_project.tb.gui.backing.wf.EditWorkflowParameterInspector.java Source code

Java tutorial

Introduction

Here is the source code for eu.planets_project.tb.gui.backing.wf.EditWorkflowParameterInspector.java

Source

/*******************************************************************************
 * 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.wf;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.component.html.HtmlDataTable;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

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

import eu.planets_project.services.datatypes.Parameter;
import eu.planets_project.tb.gui.backing.ExperimentBean;
import eu.planets_project.tb.gui.backing.exp.ExpTypeBackingBean;
import eu.planets_project.tb.gui.backing.exp.ExperimentInspector;
import eu.planets_project.tb.gui.backing.exp.NewExpWizardController;

/**
 * The backing bean for the request based add/edit workflow parameter GUI used in
 * step: 'design experiment' allows to edit/add service parameters for ONE service at a time
 * 
 * Please note: all the checks for if(this.sessBean==null) are requires, as this page is
 * called as modal panel in stage 'design experiment' therefore is already loaded when stage2 renders
 * and only gets active when also and forServiceURL is provided
 * 
 * please note: as the redirect causes the oncomplete="Richfaces.showModalPanel('configEditParamsPanel'); not 
 * to take place, we need to provide the forServiceURL within the SessionMap and not as Managed-Property
 * @author <a href="mailto:andrew.lindley@ait.ac.at">Andrew Lindley</a>
 * @since 15.01.2010
 *
 */
public class EditWorkflowParameterInspector {

    private Log log = LogFactory.getLog(EditWorkflowParameterInspector.class);
    //the service this information belongs to
    private String forServiceURL;
    private String forServiceID;
    //the experiment this information belongs to
    private String experimentId;
    private EditWorkflowParameterSessionBean sessBean = null;

    public static final String EDIT_WORKFLOW_PARAM_SERURL_MAP = "edit_param_serurl_map";
    public static final String EDIT_WORKFLOW_PARAM_SERID_MAP = "edit_param_serid_map";
    private static final String EDIT_WORKFLOW_PARAM_SESSION_BEAN_MAP = "edit_wf_param_sess_beans_map";

    /**
     * This constructor is called on every request for the request scoped
     * managed bean
     */
    public EditWorkflowParameterInspector() {
    }

    //<------------- start of filled by managed bean's property --------------- >
    /**
     * The experiment id in which the edit/add param gui is taking place
     * @return
     */
    public String getExperimentId() {
        return experimentId;
    }

    /**
     * The experiment id in which the edit/add param gui is taking place
     * This element is filled as a managed-bean's property 
     * @param experimentId
     */
    public void setExperimentId(String experimentId) {
        this.experimentId = experimentId;

        //set the service URL the parameters are about
        this.setForServiceURL(this.getServiceURLFromSessionMap(experimentId));
        this.setForServiceID(this.getServiceIDFromSessionMap(experimentId));

        //finally init this bean
        initBean(this.experimentId, this.forServiceURL);
    }

    /**
     * The service's ID we're adding parameters for
     * @return
     */
    public String getForServiceURL() {
        return forServiceURL;
    }

    /**
     * The service's Endpoint we're adding parameters for
     * This element is filled as a managed-bean's proeprty
     * @param forServiceID
     */
    public void setForServiceURL(String forServiceURL) {
        this.forServiceURL = forServiceURL;
        //initBean(this.experimentId,this.forServiceURL);
    }

    /**
     * The service's ID we're adding parameters for
     * e.g. migrate1
     * @param serviceID
     */
    public void setForServiceID(String serviceID) {
        this.forServiceID = serviceID;
    }

    public String getForServiceID() {
        return this.forServiceID;
    }

    //<------------- end of filled by managed bean's property --------------- >

    /**
     * The service's name we're adding parameters for
     * @return
     */
    public String getSerName() {
        if ((this.sessBean != null) && (this.sessBean.serviceDescr != null)) {
            return this.sessBean.serviceDescr.getName();
        }
        return "";
    }

    //I NEED TO HAND OVER ALL components that are bound by reference!
    HtmlDataTable tempTableBinding;

    //removed reference binding for component as this causes problems when 
    //syncing with the session scoped var
    /*public HtmlDataTable getParameterTable() {
       if(this.sessBean==null){
     return tempTableBinding;
       }
       else{
     return sessBean.parameterTable;
       }
    }
        
    public void setParameterTable(HtmlDataTable parameterTable) {
       if(this.sessBean==null){
     this.tempTableBinding = parameterTable;
     return;
       }
       this.sessBean.parameterTable = parameterTable;
    }*/

    public List<ServiceParameter> getServiceParametersToEdit() {
        if (this.sessBean != null) {
            return this.sessBean.serviceParams;
        } else {
            return new ArrayList<ServiceParameter>();
        }
    }

    /**
     * The NEW value for the parameter that's currently being edited.
     * @return
     */
    public String getNewValue() {
        if (this.sessBean == null) {
            return "";
        }
        return sessBean.newValue;
    }

    /**
     * The NEW value for the parameter that's currently being edited.
     * @param value
     */
    public void setNewValue(String value) {
        if (this.sessBean == null)
            return;
        this.sessBean.newValue = value;
    }

    /**
     * The name of the parameter that's currently being edited.
     * @return
     */
    public String getParameterName() {
        if (this.sessBean == null) {
            return "";
        }
        return this.sessBean.parameterName;
    }

    /**
     * The existing value for the parameter that's currently being edited.
     * @return
     */
    public String getParameterValue() {
        if (this.sessBean == null) {
            return "";
        }
        return this.sessBean.parameterValue;
    }

    /**
     * The name of the parameter that's currently being edited.
     * @param name
     */
    public void setParameterName(String name) {
        if (this.sessBean == null)
            return;
        this.sessBean.parameterName = name;
    }

    /**
     * The existing value for the parameter that's currently being edited.
     * @param value
     */
    public void setParameterValue(String value) {
        if (this.sessBean == null)
            return;
        this.sessBean.parameterValue = value;
    }

    /**
     * GUI command that's called to update the value which have been already submitted to
     * 'newValue' for the one selected Parameter that's being edited
     */
    public void updateParameter(ActionEvent e) {
        if (sessBean.newValue == null) {
            //TODO AL: add errorMessage for GUI component?
            log.debug("New value is null - cannot update!");
            return;
        }
        if (sessBean.newValue.equals("")) {
            //TODO AL: add errorMessage for GUI component?
            log.debug("Invalid new value - cannot update!");
            return;
        }
        FacesContext context = FacesContext.getCurrentInstance();
        Object o1 = context.getExternalContext().getRequestParameterMap().get("rowKey");
        if (o1 == null) {
            return;
        }
        int dataRow = Integer.valueOf((String) o1);
        String pn = sessBean.serviceParams.get(dataRow).getName();
        sessBean.serviceParams.remove(dataRow);
        sessBean.serviceParams.add(dataRow, new ServiceParameter(pn, sessBean.newValue));
    }

    /**
     * GUI command that's called to remove the currently selected parameter
     * 'newValue' for the one selected Parameter that's being edited
     */
    public void removeParameter(ActionEvent e) {
        FacesContext context = FacesContext.getCurrentInstance();
        Object o1 = context.getExternalContext().getRequestParameterMap().get("rowKey");
        if (o1 == null) {
            return;
        }
        int dataRow = Integer.valueOf((String) o1);
        sessBean.serviceParams.remove(dataRow);
    }

    public void clearParameters() {
        this.sessBean.defaultParams.clear();
        this.sessBean.serviceParams.clear();
    }

    /**
     * Contains the default parameters as provided through the service registry
     * This field may not be populated for every item
     * @return
     */
    public List<ServiceParameter> getDefaultServiceParameters() {
        if (this.sessBean == null) {
            return new ArrayList<ServiceParameter>();
        }
        return this.sessBean.getDefaultServiceParameters();
    }

    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.sessBean.serviceParams.add(par);
    }

    public void addParameter(ActionEvent event) {
        if (sessBean.parameterName.equals("")) {
            //TODO AL: create ErrorMessage for GUI Component
            log.debug("Unable to create new parameter: name undefined!");
            return;
        }
        if (sessBean.parameterValue.equals("")) {
            //TODO AL: create ErrorMessage for GUI Component
            log.debug("Unable to create new parameter: value undefined!");
            return;
        }
        this.addParameter(new ServiceParameter(sessBean.parameterName, sessBean.parameterValue));
        this.sessBean.parameterName = "";
        this.sessBean.parameterValue = "";
    }

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

    /**
     * Triggers the update parameter information process from the edit service parameters screen to update
     * the underlying experiment type specific backing bean with the new values.
     */
    public void commandUpdateServiceBeanFromEditParamScreen(ActionEvent evt) {
        //writes values back - finishes this bean
        this.commandUpdateWorkflowParameters();
        this.removeEditWFParamBeanInSession();
        //finally redirect to exp_stage2?eid without the serURL param - rerenders the entire page
        NewExpWizardController.redirectToExpStage(Long.parseLong(this.getExperimentId()), 2);
    }

    /**
      * Provides information for the auto-complete form on the param screen.
      * @param query
      * @return
     */
    public List<ServiceParameter> suggestMatchingDefaultParamsByName(Object query) {
        if (query == null)
            return null;
        // look for matching default params
        String q = (String) query;
        // Filter this into a list of matching parameters:
        ArrayList<ServiceParameter> matches = new ArrayList<ServiceParameter>();
        for (ServiceParameter sp : this.getDefaultServiceParameters()) {
            if (sp.getName().startsWith(q) || sp.getName().contains(q)) {
                matches.add(sp);
            }
        }
        return matches;
    }

    /**
     * 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.sessBean.serviceParams) {
            if (sp.getName().equals(paramName)) {
                return sp;
            }
        }
        return null;
    }

    /**
     * Fetches the requested experiment and pulls out the already existing
     * service parameters for the specified serviceID from the underlying
     * experiment type specific backing bean
     * @param experimentID
     */
    private void initBean(String experimentID, String serviceID) {
        if ((experimentID != null) && (!experimentID.equals("")) && (serviceID != null)
                && (!serviceID.equals(""))) {

            //check if this was called the first time
            if (this.getEditWFParamBeanInSession() == null) {
                EditWorkflowParameterSessionBean editParamSessBean = new EditWorkflowParameterSessionBean(this);
                this.updateEditWFParamBeanInSession(editParamSessBean);
                this.sessBean = editParamSessBean;
            }
            //or if the editParam is already in progress
            else {
                this.sessBean = this.getEditWFParamBeanInSession();
            }
        }
        //else: not all required parameters have been passed along yet
    }

    /**
     * stores/updates the corresponding session bean
     * @param editParamSessBean
     */
    private void updateEditWFParamBeanInSession(EditWorkflowParameterSessionBean editParamSessBean) {
        getWFParamBeansSessionMap().put(this.generateSessionBeanKey(), editParamSessBean);
    }

    /**
     * removes the corresponding session bean
     */
    public void removeEditWFParamBeanInSession() {
        //removes the backing bean
        getWFParamBeansSessionMap().remove(this.generateSessionBeanKey());
        //removes the reference to the serviceURL we're using
        this.removeServiceInformationFromSessionMap();
    }

    /**
     * Fetches the corresponding session bean 
     * @return
     */
    private EditWorkflowParameterSessionBean getEditWFParamBeanInSession() {
        return getWFParamBeansSessionMap().get(this.generateSessionBeanKey());
    }

    /**
     * Fetches the map that stores all EditWorkflowParametersSessionBeans from the session
     * and create one if it does not already exist.
     * @return
     */
    private HashMap<String, EditWorkflowParameterSessionBean> getWFParamBeansSessionMap() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        Object o = ctx.getExternalContext().getSessionMap().get(EDIT_WORKFLOW_PARAM_SESSION_BEAN_MAP);
        HashMap<String, EditWorkflowParameterSessionBean> editWFSessionBeanMap;

        if (o == null) {
            // no map available in the session
            editWFSessionBeanMap = new HashMap<String, EditWorkflowParameterSessionBean>();
            ctx.getExternalContext().getSessionMap().put(EDIT_WORKFLOW_PARAM_SESSION_BEAN_MAP,
                    editWFSessionBeanMap);
        } else {
            editWFSessionBeanMap = (HashMap<String, EditWorkflowParameterSessionBean>) o;
        }
        return editWFSessionBeanMap;
    }

    /**
     * the bean's input parameter that's passed within the SessionMap
     * @param expID
     * @return
     */
    private String getServiceURLFromSessionMap(String expID) {
        //fetch the serviceURL - due to the modal panel we can't use a managed-property and irect
        FacesContext ctx = FacesContext.getCurrentInstance();
        Object o = ctx.getExternalContext().getSessionMap().get(EDIT_WORKFLOW_PARAM_SERURL_MAP);
        if (o != null) {
            HashMap<String, String> editParamSerURLMap = (HashMap<String, String>) o;
            return editParamSerURLMap.get(experimentId);
        } else {
            return null;
        }
    }

    /**
     * the bean's input parameter that's passed within the SessionMap
     * @param expID
     * @return
     */
    private String getServiceIDFromSessionMap(String expID) {
        //fetch the serviceURL - due to the modal panel we can't use a managed-property and irect
        FacesContext ctx = FacesContext.getCurrentInstance();
        Object o = ctx.getExternalContext().getSessionMap().get(EDIT_WORKFLOW_PARAM_SERID_MAP);
        if (o != null) {
            HashMap<String, String> editParamSerIDMap = (HashMap<String, String>) o;
            return editParamSerIDMap.get(experimentId);
        } else {
            return null;
        }
    }

    private void removeServiceInformationFromSessionMap() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        Object o = ctx.getExternalContext().getSessionMap().get(EDIT_WORKFLOW_PARAM_SERURL_MAP);
        if (o != null) {
            HashMap<String, String> editParamSerURLMap = (HashMap<String, String>) o;
            editParamSerURLMap.remove(this.experimentId);
        }
        Object o2 = ctx.getExternalContext().getSessionMap().get(EDIT_WORKFLOW_PARAM_SERID_MAP);
        if (o2 != null) {
            HashMap<String, String> editParamSerIDMap = (HashMap<String, String>) o;
            editParamSerIDMap.remove(this.experimentId);
        }
    }

    /**
     * A key for identifying this information in the map of EditWorkflowParameterSessionBeans
     * @return
     */
    private String generateSessionBeanKey() {
        //key is assembled with expID and serviceURL
        return "expID:" + this.getExperimentId() + "servURL:" + this.getForServiceURL() + "servID:"
                + this.forServiceID;
    }

    /**
     * calls the update parameter method for the underlying experiment type specific bean
     */
    public void commandUpdateWorkflowParameters() {
        ExperimentInspector expInspector = new ExperimentInspector();
        expInspector.setExperimentId(this.getExperimentId());
        ExperimentBean expBean = expInspector.getExperimentBean();
        ExpTypeBackingBean exptypeBean = ExpTypeBackingBean.getExpTypeBean(expBean.getEtype());

        Map<String, List<Parameter>> ret = new HashMap<String, List<Parameter>>();
        if (this.forServiceID != null) {
            //using a different serviceID than the service's url
            ret.put(this.forServiceID, sessBean.convertServiceParameterList(this.sessBean.serviceParams));
        } else {
            //just using the serviceURL as identifier
            ret.put(this.forServiceURL, sessBean.convertServiceParameterList(this.sessBean.serviceParams));
        }

        exptypeBean.setWorkflowParameters(ret);
    }

    public class ServiceParameter implements Cloneable {
        private String name;
        private String value;
        private String description;

        public ServiceParameter() {
        }

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

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

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

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

        public String getDescription() {
            return this.description;
        }

        public void setDescription(String d) {
            this.description = d;
        }

        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;
            }
        }
    }

}