edu.harvard.med.screensaver.io.screens.StudyCreator.java Source code

Java tutorial

Introduction

Here is the source code for edu.harvard.med.screensaver.io.screens.StudyCreator.java

Source

// $HeadURL$
// $Id$
//
// Copyright  2008, 2010, 2011, 2012 by the President and Fellows of Harvard College.
//
// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.

package edu.harvard.med.screensaver.io.screens;

import java.io.File;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.cli.OptionBuilder;
import org.apache.log4j.Logger;

import edu.harvard.med.screensaver.db.DAOTransaction;
import edu.harvard.med.screensaver.db.DAOTransactionRollbackException;
import edu.harvard.med.screensaver.db.GenericEntityDAO;
import edu.harvard.med.screensaver.db.ScreenDAO;
import edu.harvard.med.screensaver.db.UsersDAO;
import edu.harvard.med.screensaver.io.CommandLineApplication;
import edu.harvard.med.screensaver.io.screens.StudyAnnotationParser.KEY_COLUMN;
import edu.harvard.med.screensaver.io.workbook2.Workbook;
import edu.harvard.med.screensaver.model.DuplicateEntityException;
import edu.harvard.med.screensaver.model.screens.ProjectPhase;
import edu.harvard.med.screensaver.model.screens.Screen;
import edu.harvard.med.screensaver.model.screens.ScreenDataSharingLevel;
import edu.harvard.med.screensaver.model.screens.ScreenType;
import edu.harvard.med.screensaver.model.screens.StudyType;
import edu.harvard.med.screensaver.model.users.LabAffiliation;
import edu.harvard.med.screensaver.model.users.LabHead;
import edu.harvard.med.screensaver.model.users.ScreeningRoomUser;
import edu.harvard.med.screensaver.util.StringUtils;

/**
 * Command-line application that creates a new study in the database.
 * 
 * @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a>
 */
public class StudyCreator {
    private static Logger log = Logger.getLogger(StudyCreator.class);

    @SuppressWarnings("static-access")
    public static void main(String[] args) {
        final CommandLineApplication app = new CommandLineApplication(args);

        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("first name")
                .withLongOpt("lead-screener-first-name").create("lf"));
        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("last name")
                .withLongOpt("lead-screener-last-name").create("ll"));
        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("email")
                .withLongOpt("lead-screener-email").create("le"));

        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("first name")
                .withLongOpt("lab-head-first-name").create("hf"));
        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("last name")
                .withLongOpt("lab-head-last-name").create("hl"));
        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("email")
                .withLongOpt("lab-head-email").create("he"));

        List<String> desc = new ArrayList<String>();
        for (ScreenType t : EnumSet.allOf(ScreenType.class))
            desc.add(t.name());
        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("screen type")
                .withLongOpt("screen-type").withDescription(StringUtils.makeListString(desc, ", ")).create("y"));
        desc.clear();
        for (StudyType t : EnumSet.allOf(StudyType.class))
            desc.add(t.name());
        app.addCommandLineOption(OptionBuilder.hasArg().isRequired().withArgName("study type")
                .withLongOpt("study-type").withDescription(StringUtils.makeListString(desc, ", ")).create("yy"));
        app.addCommandLineOption(
                OptionBuilder.hasArg().isRequired().withArgName("summary").withLongOpt("summary").create("s"));
        app.addCommandLineOption(
                OptionBuilder.hasArg().isRequired().withArgName("title").withLongOpt("title").create("t"));
        app.addCommandLineOption(
                OptionBuilder.hasArg().withArgName("protocol").withLongOpt("protocol").create("p"));
        app.addCommandLineOption(
                OptionBuilder.hasArg().isRequired().withArgName("#").withLongOpt("facilityId").create("i"));
        app.addCommandLineOption(OptionBuilder.hasArg(false).withLongOpt("replace")
                .withDescription("replace an existing Screen with the same facilityId").create("r"));

        app.addCommandLineOption(OptionBuilder.withLongOpt("key-input-by-wellkey")
                .withDescription("default value is to key by reagent vendor id").create("keyByWellId"));
        app.addCommandLineOption(OptionBuilder.withLongOpt("key-input-by-facility-id")
                .withDescription("default value is to key by reagent vendor id").create("keyByFacilityId"));
        app.addCommandLineOption(OptionBuilder.withLongOpt("key-input-by-compound-name")
                .withDescription("default value is to key by reagent vendor id").create("keyByCompoundName"));
        app.addCommandLineOption(OptionBuilder.withDescription(
                "optional: pivot the input col/rows so that the AT names are in Col1, and the AT well_id/rvi's are in Row1")
                .withLongOpt("annotation-names-in-col1").create("annotationNamesInCol1"));
        app.addCommandLineOption(OptionBuilder.hasArg().withArgName("file").withLongOpt("data-file").create("f"));

        app.addCommandLineOption(OptionBuilder.withArgName("parseLincsSpecificFacilityID")
                .withLongOpt("parseLincsSpecificFacilityID").create("parseLincsSpecificFacilityID"));
        app.processOptions(/* acceptDatabaseOptions= */true, /* acceptAdminUserOptions= */true);
        execute(app);
    }

    private static void execute(final CommandLineApplication app) {
        final GenericEntityDAO dao = (GenericEntityDAO) app.getSpringBean("genericEntityDao");
        final UsersDAO usersDAO = (UsersDAO) app.getSpringBean("usersDao");
        final String facilityId = app.getCommandLineOptionValue("i");
        dao.doInTransaction(new DAOTransaction() {
            @Override
            public void runTransaction() {
                try {
                    String lsfn = app.getCommandLineOptionValue("lf");
                    String lsln = app.getCommandLineOptionValue("ll");
                    String lse = app.getCommandLineOptionValue("le");
                    String lhfn = app.getCommandLineOptionValue("hf");
                    String lhln = app.getCommandLineOptionValue("hl");
                    String lhe = app.getCommandLineOptionValue("he");
                    StudyType studyType = app.getCommandLineOptionEnumValue("yy", StudyType.class);
                    ScreenType screenType = app.getCommandLineOptionEnumValue("y", ScreenType.class);

                    LabHead labHead = usersDAO.findSRU(LabHead.class, lhfn, lhln, lhe);
                    if (labHead == null) {
                        throw new RuntimeException(
                                "could not find existing user for " + lhfn + " " + lhln + ", " + lhe);
                    }
                    ScreeningRoomUser leadScreener = usersDAO.findSRU(ScreeningRoomUser.class, lsfn, lsln, lse);
                    if (leadScreener == null) {
                        throw new RuntimeException(
                                "could not find existing user for " + lsfn + " " + lsln + ", " + lse);
                    }
                    if (leadScreener.getLab().getLabHead() == null) {
                        leadScreener.setLab(labHead.getLab());
                        log.info("set lab head for lead screener");
                    }
                    boolean replace = app.isCommandLineFlagSet("r");
                    Screen screen = dao.findEntityByProperty(Screen.class, "facilityId", facilityId);
                    if (screen != null) {
                        if (!replace) {
                            log.error("study " + facilityId
                                    + " already exists (use --replace flag to delete existing screen first)");
                            return;
                        }
                        log.info("study " + facilityId + " exists, deleting...");
                        ((ScreenDAO) app.getSpringBean("screenDao")).deleteStudy(screen);
                        log.error("deleted existing study " + facilityId);
                    }

                    screen = new Screen(app.findAdministratorUser(), facilityId, leadScreener, labHead, screenType,
                            studyType, ProjectPhase.ANNOTATION, app.getCommandLineOptionValue("t"));
                    screen.setDataSharingLevel(ScreenDataSharingLevel.SHARED);
                    screen.setSummary(app.getCommandLineOptionValue("s"));
                    if (app.isCommandLineFlagSet("p")) {
                        screen.setPublishableProtocol(app.getCommandLineOptionValue("p"));
                    }
                    dao.persistEntity(screen);

                    boolean parseLincsSpecificFacilityID = app.isCommandLineFlagSet("parseLincsSpecificFacilityID");

                    // import

                    StudyAnnotationParser.KEY_COLUMN keyColumn = StudyAnnotationParser.KEY_COLUMN.RVI; // keyByReagentVendorId is the default
                    if (app.isCommandLineFlagSet("keyByWellId"))
                        keyColumn = KEY_COLUMN.WELL_ID;
                    if (app.isCommandLineFlagSet("keyByFacilityId"))
                        keyColumn = KEY_COLUMN.FACILITY_ID;
                    if (app.isCommandLineFlagSet("keyByCompoundName"))
                        keyColumn = KEY_COLUMN.COMPOUND_NAME;

                    boolean annotationNamesInCol1 = app.isCommandLineFlagSet("annotationNamesInCol1");
                    File screenResultFile = null;
                    if (app.isCommandLineFlagSet("f")) {
                        screenResultFile = app.getCommandLineOptionValue("f", File.class);
                        if (!screenResultFile.exists())
                            throw new IllegalArgumentException(
                                    "File does not exist: " + screenResultFile.getAbsolutePath());
                        StudyAnnotationParser parser = (StudyAnnotationParser) app
                                .getSpringBean("studyAnnotationParser");
                        log.info("call parser");
                        parser.parse(screen, new Workbook(screenResultFile), keyColumn, annotationNamesInCol1,
                                parseLincsSpecificFacilityID);
                        //            dao.persistEntity(screen);
                    } else {
                        log.info("no file specified for import");
                        screenResultFile = null;
                    }
                } catch (Exception e) {
                    throw new DAOTransactionRollbackException(e);
                }
            }
        });
        log.info("study created");
    }

    /**
     * @deprecated use findSRU instead; put the burden of creating the users if they do not exist, on the client code.
     */
    public static ScreeningRoomUser findOrCreateScreeningRoomUser(final GenericEntityDAO dao,
            final String firstName, final String lastName, final String email, final boolean isLabHead,
            final LabAffiliation labAffiliation) {
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("firstName", firstName);
        props.put("lastName", lastName);
        props.put("email", email);
        List<ScreeningRoomUser> users = dao.findEntitiesByProperties(ScreeningRoomUser.class, props);
        if (users.size() > 1) {
            throw new DuplicateEntityException(users.get(0));
        }
        if (users.size() == 1) {
            log.info("found existing user " + users.get(0) + " for " + firstName + " " + lastName + " (" + email
                    + ")");
            return users.get(0);
        }

        final ScreeningRoomUser[] _value = new ScreeningRoomUser[1];
        dao.doInTransaction(new DAOTransaction() {
            public void runTransaction() {
                try {
                    ScreeningRoomUser newUser;
                    if (isLabHead) {
                        newUser = new LabHead(firstName, lastName, labAffiliation);
                        newUser.setEmail(email);
                    } else {
                        newUser = new ScreeningRoomUser(firstName, lastName);
                    }
                    dao.persistEntity(newUser);
                    log.info("created new user " + newUser + " for " + firstName + " " + lastName + " (" + email
                            + ")");
                    _value[0] = newUser;
                } catch (Exception e) {
                    throw new DAOTransactionRollbackException(e);
                }
            }
        });
        return _value[0];
    }

}