control.WizardController.java Source code

Java tutorial

Introduction

Here is the source code for control.WizardController.java

Source

/*******************************************************************************
 * QBiC Project Wizard enables users to create hierarchical experimental designs including different
 * study conditions using factorial design. Copyright (C) "2016" Andreas Friedrich
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package control;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.xml.bind.JAXBException;

import logging.Log4j2Logger;
import main.SamplePreparator;
import main.SampleSummaryBean;
import model.TSVSampleBean;
import model.AOpenbisSample;
import model.AttachmentConfig;
import model.DesignType;
import model.ExperimentBean;
import model.ExperimentType;
import model.ISampleBean;
import model.MSExperimentModel;
import model.NewSampleModelBean;
import model.OpenbisExperiment;
import model.PersonType;
import model.RegistrationMode;
import model.TestSampleInformation;
import model.notes.Note;

import org.vaadin.teemu.wizards.Wizard;
import org.vaadin.teemu.wizards.WizardStep;
import org.vaadin.teemu.wizards.event.WizardCancelledEvent;
import org.vaadin.teemu.wizards.event.WizardCompletedEvent;
import org.vaadin.teemu.wizards.event.WizardProgressListener;
import org.vaadin.teemu.wizards.event.WizardStepActivationEvent;
import org.vaadin.teemu.wizards.event.WizardStepSetChangedEvent;

import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample;

import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.validator.CompositeValidator;
import com.vaadin.data.validator.RegexpValidator;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.StreamResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.themes.ValoTheme;

import steps.ConditionInstanceStep;
import steps.EntityStep;
import steps.ExtractionStep;
import io.DBManager;
import io.DBVocabularies;
import life.qbic.openbis.openbisclient.IOpenBisClient;
import steps.FinishStep;
import steps.MSAnalyteStep;
import steps.PoolingStep;
import steps.ProjectContextStep;
import steps.TailoringStep;
import steps.TestStep;
import steps.SummaryRegisterStep;
import uicomponents.ProjectInformationComponent;
import uicomponents.Styles;
import uicomponents.Styles.NotificationType;
import processes.RegisteredSamplesReadyRunnable;
import properties.Property;
import registration.OpenbisCreationController;

/**
 * Controller for the sample/experiment creation wizard
 * 
 * @author Andreas Friedrich
 * 
 */
public class WizardController implements IRegistrationController {

    private IOpenBisClient openbis;
    private OpenbisCreationController openbisCreator;
    private Wizard w;
    private Map<Steps, WizardStep> steps;
    private WizardDataAggregator dataAggregator;
    private boolean bioFactorInstancesSet = false;
    private boolean extractFactorInstancesSet = false;
    private boolean extractPoolsSet = false;
    private boolean testPoolsSet = false;
    private boolean copyMode = false;
    private DBVocabularies vocabularies;
    private DBManager dbm;
    private FileDownloader tsvDL;
    private List<Note> notes;
    SamplePreparator prep = new SamplePreparator();
    protected List<String> designExperimentTypes;

    logging.Logger logger = new Log4j2Logger(WizardController.class);

    private AttachmentConfig attachConfig;

    /**
     * 
     * @param openbis OpenBisClient API
     * @param dbm
     * @param taxMap Map containing the NCBI taxonomy (labels and ids) taken from openBIS
     * @param tissueMap Map containing the tissue
     * @param sampleTypes List containing the different sample (technology) types
     * @param spaces List of space names existing in openBIS
     * @param dataMoverFolder for attachment upload
     * @param uploadSize
     */
    public WizardController(IOpenBisClient openbis, DBManager dbm, DBVocabularies vocabularies,
            AttachmentConfig attachmentConfig) {
        this.openbis = openbis;
        this.dbm = dbm;
        this.openbisCreator = new OpenbisCreationController(openbis);// wont work if openbis is down
        this.vocabularies = vocabularies;
        this.attachConfig = attachmentConfig;
        this.designExperimentTypes = vocabularies.getExperimentTypes();
    }

    // Functions to add steps to the wizard depending on context
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    private void setRegStep() {
        w.addStep(steps.get(Steps.Registration)); // tsv upload and registration
    }

    private void setInheritEntities() {
        w.addStep(steps.get(Steps.Entity_Tailoring)); // entity negative selection
        w.addStep(steps.get(Steps.Extraction)); // extract first step
        setInheritExtracts();
    }

    private void setInheritExtracts() {
        w.addStep(steps.get(Steps.Extract_Tailoring)); // extracts negative selection
        w.addStep(steps.get(Steps.Test_Samples)); // test samples first step
        setRegStep();
    }

    private void setExtractsPooling() {
        w.addStep(steps.get(Steps.Extract_Pooling)); // pooling step
        setTestStep();
    }

    private void setTestStep() {
        w.addStep(steps.get(Steps.Test_Samples)); // test samples first step
        setRegStep();
    }

    private void setTestsPooling() {
        w.addStep(steps.get(Steps.Test_Sample_Pooling));
        setRegStep();
    }

    private void setTailoringStepsOnly() {
        w.addStep(steps.get(Steps.Entity_Tailoring));
        w.addStep(steps.get(Steps.Extract_Tailoring));
        w.addStep(steps.get(Steps.Test_Samples)); // test samples first step
        setRegStep();
    }

    private void setCreateEntities() {
        w.addStep(steps.get(Steps.Entities)); // entities first step
        setInheritEntities();
    }

    private void setEntityConditions() {
        w.addStep(steps.get(Steps.Entity_Conditions)); // entity conditions
        setInheritEntities();
    }

    private void setExtractConditions() {
        w.addStep(steps.get(Steps.Extract_Conditions)); // extract conditions
        setInheritExtracts();
    }

    private void resetNextSteps() {
        List<WizardStep> steps = w.getSteps();
        List<WizardStep> copy = new ArrayList<WizardStep>();
        copy.addAll(steps);
        boolean isNew = false;
        for (int i = 0; i < copy.size(); i++) {
            WizardStep cur = copy.get(i);
            if (isNew) {
                w.removeStep(cur);
            }
            if (w.isActive(cur))
                isNew = true;
        }
    }

    /**
     * Test is a project has biological entities registered. Used to know availability of context
     * options
     * 
     * @param spaceCode Code of the selected openBIS space
     * @param code Code of the project
     * @return
     */
    public boolean projectHasBioEntities(String spaceCode, String code) {
        if (!openbis.projectExists(spaceCode, code))
            return false;
        for (Experiment e : openbis.getExperimentsOfProjectByCode(code)) {
            if (e.getExperimentTypeCode().equals("Q_EXPERIMENTAL_DESIGN")) {
                if (openbis.getSamplesofExperiment(e.getIdentifier()).size() > 0)
                    return true;
            }
        }
        return false;
    }

    /**
     * Test is a project has biological extracts registered. Used to know availability of context
     * options
     * 
     * @param spaceCode Code of the selected openBIS space
     * @param code Code of the project
     * @return
     */
    public boolean projectHasExtracts(String spaceCode, String code) {
        if (!openbis.projectExists(spaceCode, code))
            return false;
        for (Experiment e : openbis.getExperimentsOfProjectByCode(code)) {
            if (e.getExperimentTypeCode().equals("Q_SAMPLE_EXTRACTION"))
                if (openbis.getSamplesofExperiment(e.getIdentifier()).size() > 0)
                    return true;
        }
        return false;
    }

    public Wizard getWizard() {
        return w;
    }

    private String generateProjectCode() {
        Random r = new Random();
        String res = "";
        while (res.length() < 5 || openbis.getProjectByCode(res) != null) {
            res = "Q";
            for (int i = 1; i < 5; i++) {
                char c = 'Y';
                while (c == 'Y' || c == 'Z')
                    c = (char) (r.nextInt(26) + 'A');
                res += c;
            }
        }
        return res;
    }

    public static enum Steps {
        Project_Context, Entities, Entity_Conditions, Entity_Tailoring, Extraction, Extract_Conditions, Extract_Tailoring, Extract_Pooling, Test_Samples, Test_Sample_Pooling, Registration, Finish, Protein_Fractionation, Protein_Fractionation_Pooling, Peptide_Fractionation, Peptide_Fractionation_Pooling;
    }

    /**
     * Initialize all possible steps in the wizard and the listeners used
     */
    public void init(final String user) {
        WizardController control = this;
        this.w = new Wizard();
        w.getFinishButton().setVisible(false);
        w.getFinishButton().setStyleName(ValoTheme.BUTTON_DANGER);
        w.getCancelButton().setStyleName(ValoTheme.BUTTON_DANGER);

        final ProjectInformationComponent projSelection = new ProjectInformationComponent(vocabularies.getSpaces(),
                vocabularies.getPeople().keySet());
        final ProjectContextStep contextStep = new ProjectContextStep(projSelection);
        final EntityStep entStep = new EntityStep(vocabularies.getTaxMap(), vocabularies.getPeople().keySet());
        final ConditionInstanceStep entCondInstStep = new ConditionInstanceStep(vocabularies.getTaxMap().keySet(),
                "Species", "Biol. Variables");
        final TailoringStep tailoringStep1 = new TailoringStep("Sample Sources", false);
        final ExtractionStep extrStep = new ExtractionStep(vocabularies.getTissueMap(),
                vocabularies.getCellLinesMap(), vocabularies.getPeople().keySet());
        final ConditionInstanceStep extrCondInstStep = new ConditionInstanceStep(
                vocabularies.getTissueMap().keySet(), "Tissues", "Extr. Variables");
        final TailoringStep tailoringStep2 = new TailoringStep("Sample Extracts", true);
        final TestStep techStep = new TestStep(w, vocabularies);
        final SummaryRegisterStep regStep = new SummaryRegisterStep();
        final PoolingStep poolStep1 = new PoolingStep(Steps.Extract_Pooling);
        final PoolingStep poolStep2 = new PoolingStep(Steps.Test_Sample_Pooling);
        final FinishStep finishStep = new FinishStep(w, attachConfig);

        final MSAnalyteStep protFracStep = new MSAnalyteStep(vocabularies, "PROTEINS");
        // final PoolingStep afterProtFracPooling = new
        // PoolingStep(Steps.Protein_Fractionation_Pooling);
        final MSAnalyteStep pepFracStep = new MSAnalyteStep(vocabularies, "PEPTIDES");
        // final PoolingStep afterPepFracPooling = new PoolingStep(Steps.Peptide_Fractionation_Pooling);

        steps = new HashMap<Steps, WizardStep>();
        steps.put(Steps.Project_Context, contextStep);
        steps.put(Steps.Entities, entStep);
        steps.put(Steps.Entity_Conditions, entCondInstStep);
        steps.put(Steps.Entity_Tailoring, tailoringStep1);
        steps.put(Steps.Extraction, extrStep);
        steps.put(Steps.Extract_Conditions, extrCondInstStep);
        steps.put(Steps.Extract_Tailoring, tailoringStep2);
        steps.put(Steps.Extract_Pooling, poolStep1);
        steps.put(Steps.Test_Samples, techStep);
        steps.put(Steps.Test_Sample_Pooling, poolStep2);
        steps.put(Steps.Protein_Fractionation, protFracStep);
        steps.put(Steps.Peptide_Fractionation, pepFracStep);
        // steps.put(Steps.Protein_Fractionation_Pooling, afterProtFracPooling);
        // steps.put(Steps.Peptide_Fractionation_Pooling, afterPepFracPooling);
        steps.put(Steps.Registration, regStep);
        steps.put(Steps.Finish, finishStep);

        this.dataAggregator = new WizardDataAggregator(steps, openbis, vocabularies.getTaxMap(),
                vocabularies.getTissueMap(), vocabularies.getPeople());
        // w.addStep(finishStep);
        w.addStep(contextStep);

        FocusListener fListener = new FocusListener() {
            private static final long serialVersionUID = 8721337946386845992L;

            @Override
            public void focus(FocusEvent event) {
                // new project selected...keep generating codes until one is valid
                TextField pr = projSelection.getProjectField();
                if (!pr.isValid() || pr.isEmpty()) {
                    projSelection.tryEnableCustomProject(generateProjectCode());
                    contextStep.enableEmptyProjectContextOption(true);
                    contextStep.enableNewContextOption(true);
                    contextStep.makeContextVisible();
                }
            }
        };
        projSelection.getProjectField().addFocusListener(fListener);

        Button.ClickListener projCL = new Button.ClickListener() {

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

            @Override
            public void buttonClick(ClickEvent event) {
                String existingProject = (String) projSelection.getProjectBox().getValue();
                if (existingProject == null || existingProject.isEmpty()) {
                    projSelection.tryEnableCustomProject(generateProjectCode());
                    contextStep.enableEmptyProjectContextOption(true);
                    contextStep.enableNewContextOption(true);
                    contextStep.makeContextVisible();
                }
            }
        };
        projSelection.getProjectReloadButton().addClickListener(projCL);

        Button.ClickListener peopleCL = new Button.ClickListener() {

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

            @Override
            public void buttonClick(ClickEvent event) {
                vocabularies.setPeople(dbm.fetchPeople());
                Set<String> people = vocabularies.getPeople().keySet();
                projSelection.updatePeople(people);
                entStep.updatePeople(people);
                extrStep.updatePeople(people);
                techStep.updatePeople(people);
            }
        };
        projSelection.getPeopleReloadButton().addClickListener(peopleCL);
        entStep.getPeopleReloadButton().addClickListener(peopleCL);
        extrStep.getPeopleReloadButton().addClickListener(peopleCL);

        Button.ClickListener cl = new Button.ClickListener() {
            /**
             * 
             */
            private static final long serialVersionUID = -8427457552926464653L;

            @Override
            public void buttonClick(ClickEvent event) {
                String src = event.getButton().getCaption();
                if (src.equals("Register Project")) {
                    String desc = contextStep.getDescription();
                    String altTitle = contextStep.getExpSecondaryName();
                    registerProjectOnly(desc, altTitle, user, regStep);
                    w.addStep(steps.get(Steps.Finish));
                }
                if (src.equals("Send Project to QBiC")) {
                    String tsv = dataAggregator.getTSVContent();
                    String space = contextStep.getSpaceCode();
                    String project = contextStep.getProjectCode();
                    String altTitle = contextStep.getExpSecondaryName();
                    List<Note> notes = new ArrayList<Note>();
                    boolean afterMS = w.getSteps().contains(steps.get(Steps.Protein_Fractionation));
                    if (afterMS) {
                        List<String> infos = new ArrayList<String>();
                        String protInfo = protFracStep.getAdditionalInfo();
                        if (protInfo != null && !protInfo.isEmpty()) {
                            infos.add(protInfo);
                        }
                        String pepInfo = pepFracStep.getAdditionalInfo();
                        if (pepInfo != null && !pepInfo.isEmpty()) {
                            infos.add(pepInfo);
                        }
                        if (!infos.isEmpty()) {
                            Date now = new Date();
                            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                            for (String comment : infos) {
                                Note note = new Note();
                                note.setComment(comment);
                                note.setUsername(user);
                                note.setTime(ft.format(now));
                                notes.add(note);
                            }
                        }
                    }
                    sendInquiry(space, project, altTitle, tsv, user, notes);
                    Styles.notification("Project inquiry sent.",
                            "Your Project inquiry was successfully sent to QBiC. We will contact you.",
                            NotificationType.SUCCESS);
                }
                if (src.equals("Register All Samples")) {
                    regStep.getRegisterButton().setEnabled(false);
                    ProjectContextStep contextStep = (ProjectContextStep) steps.get(Steps.Project_Context);
                    String desc = contextStep.getDescription();
                    String altTitle = contextStep.getExpSecondaryName();
                    boolean afterMS = w.getSteps().contains(steps.get(Steps.Protein_Fractionation));
                    // Additional information set in the protein and/or peptide step(s)
                    notes = new ArrayList<Note>();
                    if (afterMS) {
                        List<String> infos = new ArrayList<String>();
                        String protInfo = protFracStep.getAdditionalInfo();
                        if (protInfo != null && !protInfo.isEmpty()) {
                            infos.add(protInfo);
                        }
                        String pepInfo = pepFracStep.getAdditionalInfo();
                        if (pepInfo != null && !pepInfo.isEmpty()) {
                            infos.add(pepInfo);
                        }
                        if (!infos.isEmpty()) {
                            Date now = new Date();
                            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                            for (String comment : infos) {
                                Note note = new Note();
                                note.setComment(comment);
                                note.setUsername(user);
                                note.setTime(ft.format(now));
                                notes.add(note);
                            }
                        }
                    }
                    // TODO this needs work
                    List<List<ISampleBean>> samples = regStep.getSamples();
                    String space = contextStep.getSpaceCode();
                    String project = contextStep.getProjectCode();
                    String exp = project + "_INFO";
                    String code = project + "000";
                    String sampleType = "Q_ATTACHMENT_SAMPLE";
                    boolean pilot = contextStep.isPilot();
                    ISampleBean infoSample = new TSVSampleBean(code, exp, project, space, sampleType, "", "",
                            new HashMap<String, Object>());
                    samples.add(new ArrayList<ISampleBean>(Arrays.asList(infoSample)));
                    openbisCreator.registerProjectWithExperimentsAndSamplesBatchWise(samples, desc,
                            dataAggregator.getExperimentsWithMetadata(), regStep.getProgressBar(),
                            regStep.getProgressLabel(), new RegisteredSamplesReadyRunnable(regStep, control), user,
                            pilot);
                    w.addStep(steps.get(Steps.Finish));
                }
            }

            private void sendInquiry(String space, String project, String altTitle, String tsv, String user,
                    List<Note> notes) {
                Map<String, Object> parameters = new HashMap<String, Object>();
                parameters.put("project", project);
                parameters.put("space", space);
                parameters.put("user", user);
                parameters.put("project-tsv", tsv);

                String comments = "";
                for (Note n : notes)
                    comments += n.getComment() + "\n";
                parameters.put("alt-name", altTitle);
                parameters.put("notes", comments);// TODO do something with this

                openbis.triggerIngestionService("mail-project-inquiry", parameters);
            }

        };
        regStep.getRegisterButton().addClickListener(cl);

        /**
         * Space selection listener
         */
        ValueChangeListener spaceSelectListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                contextStep.resetProjects();
                String space = contextStep.getSpaceCode();
                if (space != null) {
                    List<String> projects = new ArrayList<String>();
                    for (Project p : openbis.getProjectsOfSpace(space)) {
                        String code = p.getCode();
                        String name = dbm.getProjectName("/" + space + "/" + code);
                        if (name != null && name.length() > 0) {
                            if (name.length() >= 80)
                                name = name.substring(0, 80) + "...";
                            code += " (" + name + ")";
                        }
                        projects.add(code);
                    }
                    contextStep.setProjectCodes(projects);
                    List<String> dontFilter = new ArrayList<String>(Arrays.asList("SPECIAL_METHOD"));
                    if (space.endsWith("PCT")) {
                        protFracStep.filterDictionariesByPrefix("PCT", dontFilter);
                        pepFracStep.filterDictionariesByPrefix("PCT", dontFilter);
                    } else if (space.endsWith("MPC")) {
                        protFracStep.filterDictionariesByPrefix("MPC", dontFilter);
                        pepFracStep.filterDictionariesByPrefix("MPC", dontFilter);
                    } else {
                        protFracStep.filterDictionariesByPrefix("", dontFilter);
                        pepFracStep.filterDictionariesByPrefix("", dontFilter);
                    }
                }
            }

        };
        contextStep.getSpaceBox().addValueChangeListener(spaceSelectListener);

        /**
         * Project selection listener
         */

        ValueChangeListener projectSelectListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                contextStep.resetExperiments();
                updateContextOptions(projSelection, contextStep);
            }

        };
        contextStep.getProjectBox().addValueChangeListener(projectSelectListener);

        /**
         * Experiment selection listener
         */

        ValueChangeListener expSelectListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                contextStep.resetSamples();
                contextStep.makePilotBoxVisible(false);
                OptionGroup projectContext = contextStep.getProjectContext();
                String context = (String) projectContext.getValue();
                List<String> contextOptions = contextStep.getContextOptions();
                ExperimentBean exp = contextStep.getExperiment();
                if (exp != null) {
                    if (exp.isPilot() && !contextOptions.get(4).equals(context)) {
                        contextStep.selectPilot();
                    }
                    List<NewSampleModelBean> beans = new ArrayList<NewSampleModelBean>();
                    for (Sample s : openbis.getSamplesofExperiment(exp.getID())) {
                        beans.add(new NewSampleModelBean(s.getCode(), s.getProperties().get("Q_SECONDARY_NAME"),
                                s.getSampleTypeCode()));
                    }
                    contextStep.setSamples(beans);
                }
            }

        };
        contextStep.getExperimentTable().addValueChangeListener(expSelectListener);

        /**
         * Project context (radio buttons) listener
         */

        ValueChangeListener projectContextListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                copyMode = false;
                if (contextStep.getProjectContext().getValue() != null) {
                    contextStep.makePilotBoxVisible(false);
                    resetNextSteps();
                    OptionGroup projectContext = contextStep.getProjectContext();
                    String context = (String) projectContext.getValue();
                    List<String> contextOptions = contextStep.getContextOptions();

                    List<ExperimentBean> experiments = contextStep.getExperiments();
                    List<ExperimentBean> beans = new ArrayList<ExperimentBean>();
                    // inherit from bio entities
                    if (contextOptions.get(1).equals(context)) {
                        for (ExperimentBean b : experiments) {
                            if (b.getExperiment_type().equals(ExperimentType.Q_EXPERIMENTAL_DESIGN.toString()))
                                beans.add(b);
                        }
                        setInheritEntities();
                        dataAggregator.setInheritEntities(true);
                        dataAggregator.setInheritExtracts(false);
                    }
                    // inherit from sample extraction
                    if (contextOptions.get(2).equals(context)) {
                        for (ExperimentBean b : experiments) {
                            if (b.getExperiment_type().equals(ExperimentType.Q_SAMPLE_EXTRACTION.toString()))
                                beans.add(b);
                        }
                        setInheritExtracts();
                        dataAggregator.setInheritEntities(false);
                        dataAggregator.setInheritExtracts(true);
                    }
                    // new context
                    if (contextOptions.get(0).equals(context)) {
                        contextStep.hideExperiments();
                        setCreateEntities();
                        contextStep.makePilotBoxVisible(true);
                        dataAggregator.setInheritEntities(false);
                        dataAggregator.setInheritExtracts(false);
                    }
                    regStep.setRegistrationMode(RegistrationMode.RegisterSamples);
                    if (contextOptions.get(3).equals(context)) {
                        setRegStep();
                        regStep.setRegistrationMode(RegistrationMode.RegisterEmptyProject);
                    }
                    // copy design context
                    if (contextOptions.get(5).equals(context)) {
                        for (ExperimentBean b : experiments) {
                            if (b.getExperiment_type().equals(ExperimentType.Q_EXPERIMENTAL_DESIGN.toString()))
                                beans.add(b);
                        }
                        copyMode = true;
                        setTailoringStepsOnly();
                        dataAggregator.setInheritEntities(true);
                        dataAggregator.setInheritExtracts(true);
                    }
                    // read only tsv creation
                    if (contextOptions.get(4).equals(context)) {
                        for (ExperimentBean b : experiments) {
                            if (b.getExperiment_type().equals(ExperimentType.Q_EXPERIMENTAL_DESIGN.toString()))
                                beans.add(b);
                        }
                        setRegStep();
                        regStep.setRegistrationMode(RegistrationMode.DownloadTSV);
                    }
                    if (beans.size() > 0)
                        contextStep.showExperiments(beans);
                }
            }
        };
        contextStep.getProjectContext().addValueChangeListener(projectContextListener);

        /**
         * Listeners for pooling samples
         */
        ValueChangeListener poolingListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                resetNextSteps();
                if (tailoringStep2.pool()) {
                    setExtractsPooling();
                } else {
                    setTestStep();
                }
            }
        };
        tailoringStep2.getPoolBox().addValueChangeListener(poolingListener);

        ValueChangeListener testPoolListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                resetNextSteps();
                if (techStep.hasPools()) {
                    setTestsPooling();
                } else {
                    setRegStep();
                }
            }
        };

        ValueChangeListener proteinListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                boolean containsProteins = false;
                for (TestSampleInformation i : techStep.getAnalyteInformation()) {
                    String tech = i.getTechnology();
                    containsProteins |= tech.equals("PROTEINS");
                }
                if (containsProteins) {
                    // TODO probably not needed
                    // dataAggregator.prepareTestSamples();
                    // techStep.setProteinPreps(dataAggregator.getTests());
                }
            }
        };

        techStep.initTestStep(testPoolListener, proteinListener, peopleCL, steps);

        ValueChangeListener noMeasureListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                techStep.changeTechPanel();
            }
        };
        techStep.getNotMeasured().addValueChangeListener(noMeasureListener);

        /**
         * Listeners for entity and extract conditions
         */
        ValueChangeListener entityConditionSetListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                resetNextSteps();
                if (entStep.isConditionsSet().getValue() != null) {
                    setEntityConditions();
                } else {
                    setInheritEntities();
                }
            }
        };
        entStep.isConditionsSet().addValueChangeListener(entityConditionSetListener);

        ValueChangeListener extractConditionSetListener = new ValueChangeListener() {

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

            @Override
            public void valueChange(ValueChangeEvent event) {
                resetNextSteps();
                if (extrStep.conditionsSet().getValue() != null) {
                    setExtractConditions();
                } else {
                    setInheritExtracts();
                }
            }
        };
        extrStep.conditionsSet().addValueChangeListener(extractConditionSetListener);

        TextField f = contextStep.getProjectCodeField();
        CompositeValidator vd = new CompositeValidator();
        RegexpValidator p = new RegexpValidator("Q[A-Xa-x0-9]{4}",
                "Project must have length of 5, start with Q and not contain Y or Z");
        vd.addValidator(p);
        vd.addValidator(new ProjectNameValidator(openbis));
        f.addValidator(vd);
        f.setImmediate(true);
        f.setValidationVisible(true);

        WizardProgressListener wl = new WizardProgressListener() {
            @Override
            public void wizardCompleted(WizardCompletedEvent event) {
            }

            @Override
            public void wizardCancelled(WizardCancelledEvent event) {
            }

            @Override
            public void stepSetChanged(WizardStepSetChangedEvent event) {
            }

            /**
             * Reactions to step changes in the wizard
             */
            @Override
            public void activeStepChanged(WizardStepActivationEvent event) {
                // Context Step
                if (event.getActivatedStep().equals(contextStep)) {
                    // contextStep.allowNext(false);
                    regStep.enableDownloads(false);
                }
                // Entity Setup Step
                if (event.getActivatedStep().equals(entStep)) {
                    bioFactorInstancesSet = false;
                }
                // Entity Condition Instances Step
                if (event.getActivatedStep().equals(entCondInstStep)) {
                    reloadConditionsPreviewTable(entCondInstStep, Integer.toString(entStep.getBioRepAmount()),
                            new ArrayList<AOpenbisSample>());
                    if (!bioFactorInstancesSet) {
                        if (entStep.speciesIsFactor())
                            entCondInstStep.initOptionsFactorComponent(entStep.getSpeciesAmount(),
                                    new HashSet<String>(), "N/A", "N/A", "N/A", "N/A");
                        entCondInstStep.initFactorFields(entStep.getFactors());
                        initConditionListener(entCondInstStep, Integer.toString(entStep.getBioRepAmount()),
                                new ArrayList<AOpenbisSample>());
                        bioFactorInstancesSet = true;
                    }
                }
                // Negative Selection of Entities
                if (event.getActivatedStep().equals(tailoringStep1)) {
                    try {
                        tailoringStep1.setSamples(
                                dataAggregator.prepareEntities(entCondInstStep.getPreSelection(), copyMode), null);
                    } catch (JAXBException e) {
                        e.printStackTrace();
                    }
                }
                // Extract Setup Step
                if (event.getActivatedStep().equals(extrStep)) {
                    dataAggregator.setEntities(tailoringStep1.getSamples());
                    extractFactorInstancesSet = false;
                }
                // Extract Factor Instances Step
                if (event.getActivatedStep().equals(extrCondInstStep)) {
                    reloadConditionsPreviewTable(extrCondInstStep, Integer.toString(extrStep.getExtractRepAmount()),
                            dataAggregator.getEntities());
                    if (!extractFactorInstancesSet) {
                        if (extrStep.isTissueFactor())// TODO mapping and keywords
                            extrCondInstStep.initOptionsFactorComponent(extrStep.getTissueAmount(),
                                    vocabularies.getCellLinesMap().keySet(), "Cell Line", "Other", "Cell Line",
                                    "Other");
                        extrCondInstStep.initFactorFields(extrStep.getFactors());
                        initConditionListener(extrCondInstStep, Integer.toString(extrStep.getExtractRepAmount()),
                                dataAggregator.getEntities());
                        extractFactorInstancesSet = true;
                    }
                }
                // Negative Selection of Extracts
                if (event.getActivatedStep().equals(tailoringStep2)) {
                    extractPoolsSet = false;
                    if (copyMode) {
                        // set entities if some were removed or changed in the last step
                        dataAggregator.setEntities(tailoringStep1.getSamples());

                    }
                    try {
                        tailoringStep2.setSamples(
                                dataAggregator.prepareExtracts(extrCondInstStep.getPreSelection(), copyMode),
                                extrStep.getLabelingMethod());
                    } catch (JAXBException e) {
                        e.printStackTrace();
                    }
                }
                // Extract Pool Step
                if (event.getActivatedStep().equals(poolStep1)) {
                    dataAggregator.resetExtracts();
                    if (!extractPoolsSet) {
                        poolStep1.setSamples(
                                new ArrayList<List<AOpenbisSample>>(Arrays.asList(tailoringStep2.getSamples())),
                                Steps.Extract_Pooling);
                        extractPoolsSet = true;
                    }
                }
                // Test Setup Step
                if (event.getActivatedStep().equals(techStep)) {
                    // dataAggregator.setHasFractionationExperiment(false);
                    testPoolsSet = false;// we have to reset this in the case someone goes back from pooling
                    List<AOpenbisSample> extracts = tailoringStep2.getSamples();
                    techStep.setTissueExtracts(extracts);
                    List<AOpenbisSample> all = new ArrayList<AOpenbisSample>();
                    all.addAll(extracts);
                    all.addAll(dataAggregator.createPoolingSamples(poolStep1.getPools()));
                    dataAggregator.setExtracts(all);
                    if (copyMode)
                        techStep.setAnalyteInputs(dataAggregator.getBaseAnalyteInformation());
                }
                // Test Pool Step
                if (event.getActivatedStep().equals(poolStep2)) {
                    if (!testPoolsSet) {// if we come from the analyte step the pools are reset, if we come
                                        // back from the next step they are not
                        poolStep2.setSamples(dataAggregator.prepareTestSamples(), Steps.Test_Sample_Pooling);
                        testPoolsSet = true;
                    }
                }
                // Protein Fractionation
                if (event.getActivatedStep().equals(protFracStep)) {
                    // List<AOpenbisSample> analytes = new ArrayList<AOpenbisSample>();

                    if (!testPoolsSet) {// if pools aren't set at this point then there was no pooling
                                        // selected before
                        dataAggregator.prepareTestSamples();// we reset the analyte samples in case we come from
                                                            // the next step and prepare them anew
                    }
                    // we forward testsamples and potential pools directly to the fractionation step to sort
                    // them out
                    // they don't get barcodes either for now, in case we need to recreate them
                    List<AOpenbisSample> proteins = filterForProperties(dataAggregator.getTests(), "Q_SAMPLE_TYPE",
                            "PROTEINS");
                    Map<String, List<AOpenbisSample>> pools = poolStep2.getPools();
                    for (String pool : pools.keySet()) {
                        List<AOpenbisSample> filtered = filterForProperties(pools.get(pool), "Q_SAMPLE_TYPE",
                                "PROTEINS");
                        if (filtered.isEmpty())
                            pools.remove(pool);
                        else
                            pools.put(pool, filtered);
                    }
                    protFracStep.setAnalyteSamples(proteins, pools);
                }
                // Peptide Fractionation
                if (event.getActivatedStep().equals(pepFracStep)) {
                    if (!protFracStep.hasRun()) {
                        protFracStep.createPreliminaryExperiments();
                    }
                    pepFracStep.setAnalyteSamplesAndExperiments(protFracStep.getResults());
                }
                // TSV and Registration Step
                if (event.getActivatedStep().equals(regStep)) {
                    regStep.enableDownloads(false);
                    // Test samples were filled out
                    if (w.getSteps().contains(steps.get(Steps.Test_Samples))) {
                        boolean afterMS = w.getSteps().contains(steps.get(Steps.Protein_Fractionation));
                        if (!testPoolsSet && !afterMS)
                            dataAggregator.prepareTestSamples();
                        if (techStep.hasMHCLigands())
                            dataAggregator.prepareMHCExtractSamplesAndExperiments();
                        List<AOpenbisSample> all = new ArrayList<AOpenbisSample>();
                        if (!afterMS) {
                            all.addAll(dataAggregator.getTests());
                            //              all.addAll(
                            dataAggregator.createPoolingSamples(poolStep2.getPools());
                            dataAggregator.setTests(all);
                        }
                        if (containsFractionation()) {
                            dataAggregator.setFractionationExperimentsProperties(
                                    getFractionationPropertiesFromLastStep());
                            dataAggregator.createFractionationSamplesAndExperiments();
                        }
                        createTSV();
                        try {
                            prep.processTSV(dataAggregator.getTSV(), DesignType.QBIC);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        armDownloadButtons(regStep.getDownloadButton());
                        List<SampleSummaryBean> summaries = prep.getSummary();
                        Map<String, String> taxMap = new HashMap<String, String>();
                        for (Map.Entry<String, String> entry : vocabularies.getTaxMap().entrySet())
                            taxMap.put(entry.getValue(), entry.getKey());
                        for (SampleSummaryBean s : summaries) {
                            List<String> translations = new ArrayList<String>();
                            for (String id : s.getSampleContent().split(", ")) {
                                String translation = taxMap.get(id);
                                if (translation != null)
                                    translations.add(translation);
                                else
                                    translations.add(id);
                            }
                            s.setSampleContent(String.join(", ", translations));
                        }
                        regStep.setSummary(summaries);
                        regStep.setProcessed(prep.getProcessed());
                    }
                    regStep.testRegEnabled();
                    // Write TSV mode
                    if (contextStep.fetchTSVModeSet()) {
                        try {
                            dataAggregator.parseAll();
                        } catch (JAXBException e1) {
                            e1.printStackTrace();
                        }
                        createTSV();
                        try {
                            prep.processTSV(dataAggregator.getTSV(), DesignType.QBIC);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        armDownloadButtons(regStep.getDownloadButton());
                        List<SampleSummaryBean> summaries = prep.getSummary();
                        Map<String, String> taxMap = new HashMap<String, String>();
                        for (Map.Entry<String, String> entry : vocabularies.getTaxMap().entrySet())
                            taxMap.put(entry.getValue(), entry.getKey());
                        for (SampleSummaryBean s : summaries) {
                            String translation = taxMap.get(s.getSampleContent());
                            if (translation != null)
                                s.setSampleContent(translation);
                        }
                        regStep.setSummary(summaries);
                    }
                }
                if (event.getActivatedStep().equals(finishStep)) {
                    ProjectContextStep context = (ProjectContextStep) steps.get(Steps.Project_Context);
                    String space = context.getSpaceCode();
                    String proj = context.getProjectCode();
                    int timeout = 20;
                    while (!openbis.projectExists(space, proj) && timeout > 0) {
                        logger.error(
                                "Project " + proj + "(" + space + ")" + "could not be found after registration.");
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    Project p = openbis.getProjectByIdentifier("/" + space + "/" + proj);
                    Map<String, List<Sample>> samplesByExperiment = new HashMap<String, List<Sample>>();
                    for (Sample s : openbis.getSamplesOfProject(p.getIdentifier())) {
                        String expID = s.getExperimentIdentifierOrNull();
                        String exp = expID.substring(expID.lastIndexOf("/") + 1);
                        if (samplesByExperiment.containsKey(exp)) {
                            List<Sample> lis = samplesByExperiment.get(exp);
                            lis.add(s);
                            samplesByExperiment.put(exp, lis);
                        } else {
                            List<Sample> lis = new ArrayList<Sample>(Arrays.asList(s));
                            samplesByExperiment.put(exp, lis);
                        }
                    }
                    finishStep.setExperimentInfos(space, proj, p.getDescription(), samplesByExperiment, openbis);
                }
            }

            private MSExperimentModel getFractionationPropertiesFromLastStep() {
                WizardStep lastInput = w.getSteps().get(w.getSteps().size() - 2);// last step is
                                                                                 // registration itself
                if (lastInput instanceof PoolingStep) {
                    return ((PoolingStep) lastInput).getPreliminarySamples();
                } else if (lastInput instanceof MSAnalyteStep) {
                    MSAnalyteStep last = (MSAnalyteStep) lastInput;
                    last.createPreliminaryExperiments();
                    return last.getResults();
                } else {
                    logger.error(
                            "Tried to fetch fractionation properties from wizard but the last step was neither of type Pooling or Fractionation. Step in question is: "
                                    + lastInput.toString());
                    logger.error("Wizard likely stopped working before registration. User was " + user);
                    Styles.notification("Error",
                            "Sorry, something went wrong. Please notify a QBiC contact person.",
                            NotificationType.ERROR);
                    return null;
                }
            }

            private boolean containsFractionation() {
                List<Steps> relevant = new ArrayList<Steps>(
                        Arrays.asList(Steps.Peptide_Fractionation, Steps.Peptide_Fractionation_Pooling,
                                Steps.Protein_Fractionation, Steps.Protein_Fractionation_Pooling));
                boolean res = false;
                for (Steps s : relevant) {
                    res |= w.getSteps().contains(steps.get(s));
                }
                return res;
            }
        };
        w.addListener(wl);
    }

    protected List<AOpenbisSample> filterForProperties(List<AOpenbisSample> samples, String property,
            String value) {
        List<AOpenbisSample> res = new ArrayList<AOpenbisSample>();
        for (AOpenbisSample sample : samples) {
            if (value.equals(sample.getValueMap().get(property)))
                res.add(sample);
        }
        return res;
    }

    protected void createTSV() {
        try {
            dataAggregator.createTSV();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    protected void initConditionListener(final ConditionInstanceStep step, final String amount,
            final List<AOpenbisSample> previousLevel) {

        ValueChangeListener listener = new ValueChangeListener() {
            /**
               * 
               */
            private static final long serialVersionUID = 7925081983580407077L;

            public void valueChange(ValueChangeEvent event) {
                reloadConditionsPreviewTable(step, amount, previousLevel);
            }
        };
        step.attachListener(listener);
    }

    protected void reloadConditionsPreviewTable(ConditionInstanceStep step, String amount,
            List<AOpenbisSample> previousLevel) {
        if (step.validInput()) {
            if (previousLevel.isEmpty())
                step.buildTable(preparePreviewPermutations(step.getFactors()), amount);
            else
                step.buildTable(preparePreviewPermutations(step.getFactors(), previousLevel), amount);
        } else {
            step.destroyTable();
        }

    }

    private void updateContextOptions(ProjectInformationComponent projSelection, ProjectContextStep contextStep) {
        // disable everything
        contextStep.disableContextOptions();

        // inputs to check
        String space = (String) contextStep.getSpaceBox().getValue();
        String existingProject = contextStep.getProjectCode();
        // String existingProject = (String) projSelection.getProjectBox().getValue();

        if (space != null && !space.isEmpty()) {
            // space is set
            if (existingProject != null && !existingProject.isEmpty()) {
                // known project selected, will deactivate generation
                projSelection.tryEnableCustomProject("");
                contextStep.enableNewContextOption(true);
                contextStep.makeContextVisible();
                boolean hasBioEntities = projectHasBioEntities(space, existingProject);
                boolean hasExtracts = projectHasExtracts(space, existingProject);
                contextStep.enableExtractContextOption(hasBioEntities);
                contextStep.enableMeasureContextOption(hasExtracts);
                contextStep.enableTSVWriteContextOption(hasBioEntities);
                contextStep.enableCopyContextOption(hasBioEntities);

                List<ExperimentBean> beans = new ArrayList<ExperimentBean>();
                for (Experiment e : openbis.getExperimentsOfProjectByCode(existingProject)) {
                    if (designExperimentTypes.contains(e.getExperimentTypeCode())) {
                        Date date = e.getRegistrationDetails().getRegistrationDate();
                        SimpleDateFormat dt1 = new SimpleDateFormat("yy-MM-dd");
                        String dt = "";
                        if (date != null)
                            dt = dt1.format(date);
                        boolean pilot = false;
                        if (e.getProperties().get("Q_IS_PILOT") != null)
                            pilot = Boolean.parseBoolean(e.getProperties().get("Q_IS_PILOT"));
                        int numOfSamples = openbis.getSamplesofExperiment(e.getIdentifier()).size();
                        beans.add(new ExperimentBean(e.getIdentifier(), e.getExperimentTypeCode(),
                                Integer.toString(numOfSamples), dt, pilot));
                    }
                }
                contextStep.setExperiments(beans);
            } else {
                // can create new project
                projSelection.getProjectField().setEnabled(true);
            }
        }
    }

    /**
     * Prepare all condition permutations for the user to set the amounts when conditions from a
     * previous tier are included
     * 
     * @param factorLists
     * @param previousTier Samples of the previous tier
     * @return
     */
    public List<String> preparePreviewPermutations(List<List<Property>> factorLists,
            List<AOpenbisSample> previousTier) {
        List<String> permutations = new ArrayList<String>();
        for (AOpenbisSample e : previousTier) {
            List<List<String>> res = new ArrayList<List<String>>();
            String secName = e.getQ_SECONDARY_NAME();
            if (secName == null)
                secName = "";
            String condKey = "(" + e.getCode().split("-")[1] + ") " + secName;
            res.add(new ArrayList<String>(Arrays.asList(condKey)));
            for (List<Property> instances : factorLists) {
                List<String> factorValues = new ArrayList<String>();
                for (Property f : instances) {
                    String name = f.getValue();
                    if (f.hasUnit())
                        name = name + " " + f.getUnit().getValue();
                    factorValues.add(name);
                }
                res.add(factorValues);
            }
            permutations.addAll(dataAggregator.generatePermutations(res));
        }
        return permutations;
    }

    /**
     * Prepare all condition permutations for the user to set the amounts
     * 
     * @param factorLists
     * @return
     */
    public List<String> preparePreviewPermutations(List<List<Property>> factorLists) {
        List<List<String>> res = new ArrayList<List<String>>();
        for (List<Property> instances : factorLists) {
            List<String> factorValues = new ArrayList<String>();
            for (Property f : instances) {
                String name = f.getValue();
                if (f.hasUnit())
                    name = name + " " + f.getUnit().getValue();
                factorValues.add(name);
            }
            res.add(factorValues);
        }
        List<String> permutations = dataAggregator.generatePermutations(res);
        return permutations;
    }

    protected void armDownloadButtons(Button tsv) {
        StreamResource tsvStream = getTSVStream(dataAggregator.getTSVContent(), dataAggregator.getTSVName());
        if (tsvDL == null) {
            tsvDL = new FileDownloader(tsvStream);
            tsvDL.extend(tsv);
        } else
            tsvDL.setFileDownloadResource(tsvStream);
    }

    public StreamResource getGraphStream(final String content, String name) {
        StreamResource resource = new StreamResource(new StreamResource.StreamSource() {
            @Override
            public InputStream getStream() {
                try {
                    InputStream is = new ByteArrayInputStream(content.getBytes());
                    return is;
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }, String.format("%s.graphml", name));
        return resource;
    }

    private void registerProjectOnly(String desc, String altTitle, String user, SummaryRegisterStep regStep) {
        ProjectContextStep context = (ProjectContextStep) steps.get(Steps.Project_Context);
        String space = context.getSpaceCode();
        String code = context.getProjectCode();
        boolean success = openbisCreator.registerProject(space, code, desc, user);
        // will register people to the db and send a success message
        boolean sqlDown = false;
        try {
            performPostRegistrationTasks(success);
        } catch (SQLException e) {
            sqlDown = true;
        }
        regStep.registrationDone(sqlDown, getRegistrationError());
        // Functions.notification("Success", "Project was registered!", NotificationType.SUCCESS);
    }

    @Override
    public String getRegistrationError() {
        return openbisCreator.getErrors();
    }

    public StreamResource getTSVStream(final String content, String name) {
        StreamResource resource = new StreamResource(new StreamResource.StreamSource() {
            @Override
            public InputStream getStream() {
                try {
                    InputStream is = new ByteArrayInputStream(content.getBytes());
                    return is;
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }, String.format("%s.tsv", name));
        return resource;
    }

    private void writeNoteToOpenbis(String id, Note note) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", id);
        params.put("user", note.getUsername());
        params.put("comment", note.getComment());
        params.put("time", note.getTime());
        openbis.ingest("DSS1", "add-to-xml-note", params);
    }

    @Override
    public void performPostRegistrationTasks(boolean success) throws SQLException {
        if (success) {
            ProjectContextStep contextStep = (ProjectContextStep) steps.get(Steps.Project_Context);
            String projectIdentifier = "/" + contextStep.getSpaceCode() + "/" + contextStep.getProjectCode();
            String projectName = contextStep.getExpSecondaryName();
            List<OpenbisExperiment> exps = dataAggregator.getExperiments();
            if (exps == null)
                exps = new ArrayList<OpenbisExperiment>();
            int investigatorID = -1;
            int contactID = -1;
            int managerID = -1;
            if (!contextStep.getPerson(PersonType.Investigator).equals(""))
                investigatorID = vocabularies.getPeople().get(contextStep.getPerson(PersonType.Investigator));
            if (!contextStep.getPerson(PersonType.Manager).equals(""))
                managerID = vocabularies.getPeople().get(contextStep.getPerson(PersonType.Manager));
            if (!contextStep.getPerson(PersonType.Contact).equals(""))
                contactID = vocabularies.getPeople().get(contextStep.getPerson(PersonType.Contact));

            logger.info("Registration complete!");
            for (OpenbisExperiment e : exps) {
                if (e.getType().equals(ExperimentType.Q_EXPERIMENTAL_DESIGN)) {
                    String id = projectIdentifier + "/" + e.getOpenbisName();
                    for (Note n : notes) {
                        writeNoteToOpenbis(id, n);
                    }
                }
            }
            int projectID = dbm.addProjectToDB(projectIdentifier, projectName);
            if (investigatorID != -1)
                dbm.addPersonToProject(projectID, investigatorID, "PI");
            if (contactID != -1)
                dbm.addPersonToProject(projectID, contactID, "Contact");
            if (managerID != -1)
                dbm.addPersonToProject(projectID, managerID, "Manager");
            for (OpenbisExperiment e : exps) {
                String identifier = projectIdentifier + "/" + e.getOpenbisName();
                int expID = dbm.addExperimentToDB(identifier);
                if (e.getPersonID() > -1) {
                    int person = e.getPersonID();
                    dbm.addPersonToExperiment(expID, person, "Contact");
                }
            }
        } else {
            // nothing for now
        }
    }
}