qdbtools.main.QuserdbtoolsUI.java Source code

Java tutorial

Introduction

Here is the source code for qdbtools.main.QuserdbtoolsUI.java

Source

/*******************************************************************************
 * QBiC User DB Tools enables users to add people and affiliations to our mysql user database.
 * 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 qdbtools.main;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.annotation.WebServlet;

import ldap.LDAPConfig;
import life.qbic.openbis.openbisclient.IOpenBisClient;
import life.qbic.openbis.openbisclient.OpenBisClient;
import life.qbic.openbis.openbisclient.OpenBisClientMock;
import life.qbic.portal.liferayandvaadinhelpers.main.LiferayAndVaadinUtils;
import logging.Log4j2Logger;
import model.Affiliation;
import model.CollaboratorWithResponsibility;
import model.Person;
import model.ProjectInfo;
import model.Styles;
import model.Styles.NotificationType;
import model.Tuple;
import views.AffiliationInput;
import views.AffiliationVIPTab;
import views.MultiAffiliationTab;
import views.PersonInput;
import views.ProjectView;
import views.SearchView;

import com.liferay.portal.model.User;
import com.liferay.portal.model.UserGroup;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
import config.ConfigurationManagerFactory;
import db.Config;
import db.DBManager;

@SuppressWarnings("serial")
@Theme("quserdbtools")
public class QuserdbtoolsUI extends UI {

    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = QuserdbtoolsUI.class, widgetset = "qdbtools.main.widgetset.QuserdbtoolsWidgetset")
    public static class Servlet extends VaadinServlet {
    }

    private logging.Logger logger = new Log4j2Logger(QuserdbtoolsUI.class);
    private DBManager dbControl;
    private Map<String, Integer> affiMap;
    private Map<String, Integer> personMap;

    private TabSheet options;

    private Config config;
    public static String tmpFolder;

    private IOpenBisClient openbis;
    private boolean testMode = false;

    @Override
    protected void init(VaadinRequest request) {
        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);

        options = new TabSheet();

        this.config = readConfig();
        tmpFolder = config.getTmpFolder();
        LDAPConfig ldapConfig = readLdapConfig();// TODO

        // establish connection to the OpenBIS API
        if (!isDevelopment() || !testMode) {
            try {
                this.openbis = new OpenBisClient(config.getOpenbisUser(), config.getOpenbisPass(),
                        config.getOpenbisURL());
                this.openbis.login();
            } catch (Exception e) {
                // success = false;
                // logger.error(
                // "User \"" + userID + "\" could not connect to openBIS and has been informed of this.");
                // layout.addComponent(new Label(
                // "Data Management System could not be reached. Please try again later or contact us."));
            }
        }
        if (isDevelopment() && testMode) {
            logger.error("No connection to openBIS. Trying mock version for testing.");
            this.openbis = new OpenBisClientMock("", "", "");
            layout.addComponent(new Label(
                    "openBIS could not be reached. Resuming with mock version. Some options might be non-functional. Reload to retry."));
        }

        dbControl = new DBManager(config);

        initTabs();

        layout.addComponent(options);
    }

    private void initTabs() {
        boolean admin = isAdmin();
        options.removeAllComponents();
        if (!admin && !isDevelopment() && !canUsePortlet()) {
            VerticalLayout rightsMissingTab = new VerticalLayout();
            rightsMissingTab.setCaption("User Database Input");
            Label info = new Label(
                    "Your account does not have the necessary rights to add new people to our database.\n"
                            + "If you think you should be able to do so, please contact us.",
                    ContentMode.PREFORMATTED);
            rightsMissingTab.addComponent(info);
            options.addTab(rightsMissingTab, "Information");
            options.setSelectedTab(rightsMissingTab);
            options.setEnabled(false);

        } else {

            affiMap = dbControl.getAffiliationMap();
            personMap = dbControl.getPersonMap();
            Set<String> instituteNames = dbControl.getInstituteNames();
            List<String> facultyEnums = dbControl.getPossibleEnumsForColumnsInTable("organizations", "faculty");
            List<String> affiliationRoles = dbControl.getPossibleEnumsForColumnsInTable("persons_organizations",
                    "occupation");

            PersonInput addUserTab = new PersonInput(
                    dbControl.getPossibleEnumsForColumnsInTable("persons", "title"), affiMap, affiliationRoles,
                    new AffiliationInput(instituteNames, facultyEnums, personMap));
            options.addTab(addUserTab, "New Person");

            AffiliationInput addAffilTab = new AffiliationInput(instituteNames, facultyEnums, personMap);
            options.addTab(addAffilTab, "New Affiliation");

            SearchView searchView = new SearchView();
            options.addTab(searchView, "Search Entries");

            List<Affiliation> affiTable = dbControl.getAffiliationTable();
            Map<Integer, Tuple> affiPeople = new HashMap<Integer, Tuple>();
            for (Affiliation a : affiTable) {
                int id = a.getID();
                affiPeople.put(id, new Tuple(a.getContactPerson(), a.getHeadName()));
            }

            AffiliationVIPTab vipTab = new AffiliationVIPTab(personMap, affiMap, affiPeople);
            options.addTab(vipTab, "Edit Affiliation VIPs");

            MultiAffiliationTab multiAffilTab = new MultiAffiliationTab(personMap, affiMap, affiliationRoles);
            options.addTab(multiAffilTab, "Additional Person-Affiliations");
            if (!admin) {
                options.getTab(3).setEnabled(false);
                options.getTab(4).setEnabled(false);
            }

            String userID = "";
            if (LiferayAndVaadinUtils.isLiferayPortlet()) {
                logger.info("DB Tools running on Liferay, fetching user ID.");
                userID = LiferayAndVaadinUtils.getUser().getScreenName();
            } else {
                if (isDevelopment()) {
                    logger.warn("Checks for local dev version successful. User is granted admin status.");
                    userID = "admin";
                }
            }
            Map<String, ProjectInfo> userProjects = new HashMap<String, ProjectInfo>();

            List<Project> openbisProjects = new ArrayList<Project>();
            if (testMode) {
                openbisProjects = openbis.listProjects();
            } else {
                openbisProjects = openbis.getOpenbisInfoService()
                        .listProjectsOnBehalfOfUser(openbis.getSessionToken(), userID);
            }
            Map<String, ProjectInfo> allProjects = dbControl.getProjectMap();
            for (Project p : openbisProjects) {
                String projectID = p.getIdentifier();
                String code = p.getCode();
                if (allProjects.get(projectID) == null)
                    userProjects.put(projectID, new ProjectInfo(p.getSpaceCode(), code, "", -1));
                else
                    userProjects.put(projectID, allProjects.get(projectID));
            }

            ProjectView projectView = new ProjectView(userProjects.values(), openbis, personMap);
            options.addTab(projectView, "Projects");
            options.getTab(5).setEnabled(!userProjects.isEmpty());

            initPortletToDBFunctionality(addAffilTab, addUserTab, multiAffilTab, vipTab, searchView, projectView);
        }
    }

    boolean isDevelopment() {
        boolean devEnv = false;
        try {
            // TODO tests if this is somehow a local development environment
            // in which case user is granted admin rights. Change so it works for you.
            // Be careful that this is never true on production or better yet that logged out users can
            // not see the portlet page.
            String path = new File(".").getCanonicalPath();
            devEnv = path.toLowerCase().contains("eclipse");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return devEnv;
    }

    private boolean canUsePortlet() {
        try {
            User user = LiferayAndVaadinUtils.getUser();
            for (UserGroup grp : user.getUserGroups()) {
                String group = grp.getName();
                if (config.getUserGrps().contains(group)) {
                    logger.info(
                            "User " + user.getScreenName() + " can use portlet because they are part of " + group);
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Could not fetch user groups. User won't be able to use portlet.");
        }
        return false;
    }

    private boolean isAdmin() {
        if (isDevelopment())
            return true;
        else {
            try {
                User user = LiferayAndVaadinUtils.getUser();
                for (UserGroup grp : user.getUserGroups()) {
                    String group = grp.getName();
                    if (config.getAdminGrps().contains(group)) {
                        logger.info("User " + user.getScreenName() + " has full rights because they are part of "
                                + group);
                        return true;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Could not fetch user groups. User won't be able to use portlet.");
            }
            return false;
        }
    }

    private void initPortletToDBFunctionality(final AffiliationInput addAffilTab, final PersonInput addUserTab,
            final MultiAffiliationTab multiAffilTab, final AffiliationVIPTab vipTab, final SearchView search,
            final ProjectView projects) {

        projects.getProjectTable().addValueChangeListener(new ValueChangeListener() {

            private Map<String, String> expTypeCodeTranslation = new HashMap<String, String>() {
                {
                    put("Q_EXPERIMENTAL_DESIGN", "Patients/Sources");
                    put("Q_SAMPLE_EXTRACTION", "Sample Extracts");
                    put("Q_SAMPLE_PREPARATION", "Sample Preparations");
                    put("Q_MS_MEASUREMENT", "Mass Spectrometry");
                    put("Q_NGS_MEASUREMENT", "NGS Sequencing");
                };
            };

            @Override
            public void valueChange(ValueChangeEvent event) {
                Object item = projects.getProjectTable().getValue();
                if (item != null) {
                    String project = item.toString();
                    // get collaborators associated to openbis experiments
                    List<CollaboratorWithResponsibility> collaborators = dbControl
                            .getCollaboratorsOfProject(project);
                    // get openbis experiments and type
                    Map<String, String> existingExps = new HashMap<String, String>();
                    for (Experiment e : openbis.getExperimentsForProject2(project)) {
                        String type = expTypeCodeTranslation.get(e.getExperimentTypeCode());
                        String id = e.getIdentifier();
                        if (type != null)
                            existingExps.put(id, type);
                    }
                    // add types for experiments with existing collaborators
                    for (CollaboratorWithResponsibility c : collaborators) {
                        String identifier = c.getOpenbisIdentifier();
                        c.setType(existingExps.get(identifier));
                        existingExps.remove(identifier);
                    }
                    // add empty entries and type for applicable experiments without collaborators
                    for (String expID : existingExps.keySet()) {
                        String code = expID.split("/")[3];
                        CollaboratorWithResponsibility c = new CollaboratorWithResponsibility(-1, "", expID, code,
                                "Contact");
                        c.setType(existingExps.get(expID));
                        collaborators.add(c);
                    }
                    projects.setCollaboratorsOfProject(collaborators);
                }
            }
        });

        projects.getInfoCommitButton().addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                ProjectInfo info = projects.getEditedInfo();
                if (info != null) {
                    String code = info.getProjectCode();
                    int id = info.getProjectID();
                    if (id < 1)
                        id = dbControl.addProjectToDB("/" + info.getSpace() + "/" + code, info.getProjectName());
                    else
                        dbControl.addOrChangeSecondaryNameForProject(id, info.getProjectName());
                    if (info.getInvestigator() == null || info.getInvestigator().isEmpty())
                        dbControl.removePersonFromProject(id, "PI");
                    else
                        dbControl.addOrUpdatePersonToProject(id, personMap.get(info.getInvestigator()), "PI");
                    if (info.getContact() == null || info.getContact().isEmpty())
                        dbControl.removePersonFromProject(id, "Contact");
                    else
                        dbControl.addOrUpdatePersonToProject(id, personMap.get(info.getContact()), "Contact");
                    if (info.getManager() == null || info.getManager().isEmpty())
                        dbControl.removePersonFromProject(id, "Manager");
                    else
                        dbControl.addOrUpdatePersonToProject(id, personMap.get(info.getManager()), "Manager");
                    projects.updateChangedInfo(info);
                }
            }
        });
        ;
        projects.getPeopleCommitButton().addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                List<CollaboratorWithResponsibility> links = projects.getNewResponsibilities();
                for (CollaboratorWithResponsibility c : links) {
                    int experimentID = c.getExperimentID();
                    if (experimentID < 1)
                        experimentID = dbControl.addExperimentToDB(c.getOpenbisIdentifier());
                    String name = c.getPerson();
                    int personID = -1;
                    if (personMap.get(name) != null)
                        personID = personMap.get(name);
                    if (personID < 1)
                        dbControl.removePersonFromExperiment(experimentID);
                    else
                        dbControl.addOrUpdatePersonToExperiment(experimentID, personID, "Contact");
                }
            }
        });
        ;

        search.getSearchAffiliationButton().addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                String affi = search.getAffiliationSearchField().getValue();
                if (affi != null && !affi.isEmpty()) {
                    search.setAffiliations(dbControl.getAffiliationsContaining(affi));
                } else
                    search.setAffiliations(new ArrayList<Affiliation>());
            }
        });

        search.getSearchPersonButton().addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                String person = search.getPersonSearchField().getValue();
                if (person != null && !person.isEmpty()) {
                    search.setPersons(dbControl.getPersonsContaining(person));
                } else
                    search.setPersons(new ArrayList<Person>());
            }
        });

        addAffilTab.getCommitButton().addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                if (addAffilTab.isValid()) {
                    if (dbControl.addNewAffiliation(addAffilTab.getAffiliation()) > -1)
                        successfulCommit();
                    else
                        commitError("There has been an error.");
                } else
                    inputError();
            }
        });

        vipTab.getSetHeadAndContactButton().addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                int affi = vipTab.getSelectedAffiTabID();
                int contact = vipTab.getNewContactID();
                int head = vipTab.getNewHeadID();
                if (affi > 0) {
                    if (head > 0)
                        dbControl.setAffiliationVIP(affi, head, "head");
                    if (contact > 0)
                        dbControl.setAffiliationVIP(affi, contact, "main_contact");
                    vipTab.updateVIPs();
                    successfulCommit();
                }
            }
        });

        addAffilTab.getInstituteField().addValueChangeListener(new ValueChangeListener() {

            @Override
            public void valueChange(ValueChangeEvent event) {
                Object val = addAffilTab.getInstituteField().getValue();
                if (val != null) {
                    Affiliation orgInfo = dbControl.getOrganizationInfosFromInstitute(val.toString());
                    if (orgInfo != null)
                        addAffilTab.autoComplete(orgInfo);
                }
            }
        });

        addUserTab.getCommitButton().addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                if (addUserTab.isValid()) {
                    Person p = addUserTab.getPerson();
                    if (addUserTab.hasNewAffiliation()) {
                        int affiID = dbControl.addNewAffiliation(addUserTab.getNewAffiliation());
                        if (affiID > -1)
                            successfulCommit();
                        else
                            commitError("There has been an error while adding the new affiliation.");
                        p.setAffiliationID(affiID);
                    }
                    if (dbControl.userNameExists(p.getUsername())) {
                        Styles.notification("Person already registered",
                                "A person with the Username you selected is already registered in our database!",
                                NotificationType.ERROR);
                    } else {
                        if (dbControl.addNewPerson(p))
                            successfulCommit();
                        else
                            commitError("There has been an error while adding a new person.");
                    }
                } else
                    inputError();
            }
        });

        multiAffilTab.getCommitButton().addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                if (multiAffilTab.isValid()) {
                    if (dbControl.addOrUpdatePersonAffiliationConnections(
                            personMap.get(multiAffilTab.getPersonBox().getValue()),
                            multiAffilTab.getChangedAndNewConnections()))
                        successfulCommit();
                    else
                        commitError("There has been an error.");
                } else
                    inputError();
            }
        });

        multiAffilTab.getAddButton().addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                String personName = multiAffilTab.getPersonBox().getValue().toString();
                Person p = dbControl.getPerson(personMap.get(personName));

                String affiName = multiAffilTab.getOrganizationBox().getValue().toString();
                Person newP = new Person(p.getUsername(), p.getTitle(), p.getFirst(), p.getLast(), p.geteMail(),
                        p.getPhone(), affiMap.get(affiName), affiName, "");
                multiAffilTab.addDataToTable(new ArrayList<Person>(Arrays.asList(newP)));
                multiAffilTab.getAddButton().setEnabled(false);
            }
        });

        ValueChangeListener multiAffiPersonListener = new ValueChangeListener() {

            @Override
            public void valueChange(ValueChangeEvent event) {
                if (multiAffilTab.getPersonBox().getValue() != null) {
                    String personName = multiAffilTab.getPersonBox().getValue().toString();
                    multiAffilTab
                            .reactToPersonSelection(dbControl.getPersonWithAffiliations(personMap.get(personName)));
                    multiAffilTab.getAddButton().setEnabled(multiAffilTab.newAffiliationPossible());
                }
            }
        };
        multiAffilTab.getPersonBox().addValueChangeListener(multiAffiPersonListener);

        ValueChangeListener multiAffiListener = new ValueChangeListener() {

            @Override
            public void valueChange(ValueChangeEvent event) {
                if (multiAffilTab.getPersonBox().getValue() != null) {
                    multiAffilTab.getAddButton().setEnabled(multiAffilTab.newAffiliationPossible());
                }
            }
        };
        multiAffilTab.getOrganizationBox().addValueChangeListener(multiAffiListener);
    }

    private void successfulCommit() {
        Styles.notification("Data added", "Data has been successfully added to the database!",
                NotificationType.SUCCESS);
        // wait a bit and reload tabs
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        initTabs();
    }

    private void inputError() {
        Styles.notification("Data Incomplete", "Please fill in all required fields correctly.",
                NotificationType.DEFAULT);
    }

    private void commitError(String reason) {
        Styles.notification("There has been an error.", reason, NotificationType.ERROR);
    }

    private Config readConfig() {
        config.ConfigurationManager c = ConfigurationManagerFactory.getInstance();

        return new Config(c.getMysqlHost(), c.getMysqlPort(), c.getMysqlDB(), c.getMysqlUser(), c.getMysqlPass(),
                c.getDBInputUserGrps(), c.getDBInputAdminGrps(), c.getDataSourceUrl(), c.getDataSourceUser(),
                c.getDataSourcePassword(), c.getTmpFolder());
    }

    private LDAPConfig readLdapConfig() {
        config.ConfigurationManager c = ConfigurationManagerFactory.getInstance();

        return new LDAPConfig(c.getLdapHost(), c.getLdapBase(), c.getLdapUser(), c.getLdapPass());
    }
}