edu.harvard.med.screensaver.ui.screens.ScreenSearchResults.java Source code

Java tutorial

Introduction

Here is the source code for edu.harvard.med.screensaver.ui.screens.ScreenSearchResults.java

Source

// $HeadURL$
// $Id$

// Copyright  2006, 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.ui.screens;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import edu.harvard.med.lincs.screensaver.LincsScreensaverConstants;
import edu.harvard.med.screensaver.db.GenericEntityDAO;
import edu.harvard.med.screensaver.db.Criterion.Operator;
import edu.harvard.med.screensaver.db.datafetcher.DataFetcherUtil;
import edu.harvard.med.screensaver.db.datafetcher.EntityDataFetcher;
import edu.harvard.med.screensaver.db.hqlbuilder.HqlBuilder;
import edu.harvard.med.screensaver.model.Entity;
import edu.harvard.med.screensaver.model.meta.RelationshipPath;
import edu.harvard.med.screensaver.model.screenresults.ScreenResult;
import edu.harvard.med.screensaver.model.screens.AssayType;
import edu.harvard.med.screensaver.model.screens.CellLine;
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.ScreenStatus;
import edu.harvard.med.screensaver.model.screens.ScreenType;
import edu.harvard.med.screensaver.model.screens.Species;
import edu.harvard.med.screensaver.model.screens.StatusItem;
import edu.harvard.med.screensaver.model.users.LabHead;
import edu.harvard.med.screensaver.model.users.ScreeningRoomUser;
import edu.harvard.med.screensaver.model.users.ScreensaverUser;
import edu.harvard.med.screensaver.model.users.ScreensaverUserRole;
import edu.harvard.med.screensaver.ui.arch.datatable.column.TableColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.DateEntityColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.DateTimeEntityColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.EnumEntityColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.HasFetchPaths;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.IntegerEntityColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.TextEntityColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.TextSetEntityColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.UserNameColumn;
import edu.harvard.med.screensaver.ui.arch.datatable.model.InMemoryEntityDataModel;
import edu.harvard.med.screensaver.ui.arch.searchresults.EntityBasedEntitySearchResults;
import edu.harvard.med.screensaver.ui.arch.searchresults.SearchResults;
import edu.harvard.med.screensaver.ui.users.UserViewer;
import edu.harvard.med.screensaver.util.NullSafeComparator;

/**
 * A {@link SearchResults} for {@link Screen Screens}.
 *
 * @author <a mailto="john_sullivan@hms.harvard.edu">John Sullivan</a>
 * @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a>
 */
public class ScreenSearchResults extends EntityBasedEntitySearchResults<Screen, Integer> {
    private GenericEntityDAO _dao;

    private UserViewer _userViewer;

    /**
     * @motivation for CGLIB2
     */
    protected ScreenSearchResults() {
    }

    public ScreenSearchResults(ScreenViewer screenViewer, UserViewer userViewer, GenericEntityDAO dao) {
        super(screenViewer);
        _userViewer = userViewer;
        _dao = dao;
    }

    public void searchScreensForUser(ScreeningRoomUser screener) {
        setTitle("Screens for screener " + screener.getFullNameFirstLast());
        final Set<Screen> screens = new HashSet<Screen>();
        screens.addAll(screener.getAllAssociatedScreens());
        if (screens.isEmpty()) {
            showMessage("screens.noScreensForUser");
        } else {
            initialize(new InMemoryEntityDataModel<Screen, Integer, Screen>(
                    new EntityDataFetcher<Screen, Integer>(Screen.class, _dao) {
                        @Override
                        public void addDomainRestrictions(HqlBuilder hql) {
                            DataFetcherUtil.addDomainRestrictions(hql, getRootAlias(),
                                    Sets.newHashSet(Iterables.transform(screens, Entity.ToEntityId)));
                        }
                    }));

            sortByCreationDateDesc();
        }
    }

    public void searchScreensForProject(final String projectId) {
        setTitle("Screens for project " + projectId);
        initialize(new InMemoryEntityDataModel<Screen, Integer, Screen>(
                new EntityDataFetcher<Screen, Integer>(Screen.class, _dao) {
                    @Override
                    public void addDomainRestrictions(HqlBuilder hql) {
                        hql.where(getRootAlias(), "projectId", Operator.EQUAL, projectId);
                    }
                }));

        if (getColumnManager().getColumn("Project Phase") != null) {
            getColumnManager().setSortColumnName("Project Phase");
            getColumnManager().setSortAscending(true);
        }
    }

    @Override
    public void searchAll() {
        setTitle("Screens");
        initialize(new InMemoryEntityDataModel<Screen, Integer, Screen>(
                new EntityDataFetcher<Screen, Integer>(Screen.class, _dao) {
                    @Override
                    public void addDomainRestrictions(HqlBuilder hql) {
                        super.addDomainRestrictions(hql);
                        hql.where(getRootAlias(), "projectPhase", Operator.NOT_EQUAL, ProjectPhase.ANNOTATION);
                    }
                }));
        sortByCreationDateDesc();
    }

    private void sortByCreationDateDesc() {
        if (getColumnManager().getColumn("Date Recorded") != null) {
            getColumnManager().setSortColumnName("Date Recorded");
            getColumnManager().setSortAscending(false);
        }
    }

    // implementations of the SearchResults abstract methods

    @SuppressWarnings("unchecked")
    protected List<? extends TableColumn<Screen, ?>> buildColumns() {

        List<TableColumn<Screen, ?>> columns = Lists.newArrayList();
        columns.addAll(buildScreenSummaryColumns(false));
        columns.addAll(buildScreenAdminColumns());
        columns.addAll(buildScreenResultColumns());

        //    TableColumnManager<Screen> columnManager = getColumnManager();
        //    columnManager.addCompoundSortColumns(columnManager.getColumn("Lab Head"),
        //                                         columnManager.getColumn("Lead Screener"),
        //                                         columnManager.getColumn("Screen Number"));
        //    columnManager.addCompoundSortColumns(columnManager.getColumn("Lead Screener"),
        //                                         columnManager.getColumn("Lab Head"),
        //                                         columnManager.getColumn("Screen Number"));

        return columns;
    }

    private List<TableColumn<Screen, ?>> buildScreenResultColumns() {
        List<TableColumn<Screen, ?>> columns = Lists.newArrayList();

        // TODO: should make this a vocab list, but need support for list-of-vocab column type
        columns.add(new EnumEntityColumn<Screen, ScreenResultAvailability>(Screen.screenResult, "Screen Result",
                "'available' if the screen result is loaded into Screensaver and viewable by the current user;"
                        + " 'not shared' if loaded but not viewable by the current user; otherwise 'none'",
                TableColumn.UNGROUPED, ScreenResultAvailability.values()) {
            @Override
            public ScreenResultAvailability getCellValue(Screen screen) {
                if (screen.getScreenResult() == null) {
                    return ScreenResultAvailability.NONE;
                } else if (screen.getScreenResult().isRestricted()) {
                    return ScreenResultAvailability.NOT_SHARED;
                } else {
                    return ScreenResultAvailability.AVAILABLE;
                }
            }

            @Override
            protected Comparator<Screen> getAscendingComparator() {
                return new Comparator<Screen>() {
                    private NullSafeComparator<ScreenResult> _srComparator = new NullSafeComparator<ScreenResult>(
                            true) {
                        @Override
                        protected int doCompare(ScreenResult sr1, ScreenResult sr2) {
                            if (!sr1.isRestricted() && sr2.isRestricted()) {
                                return -1;
                            }
                            if (sr1.isRestricted() && !sr2.isRestricted()) {
                                return 1;
                            }
                            return sr1.getScreen().getFacilityId().compareTo(sr2.getScreen().getFacilityId());
                        }
                    };

                    public int compare(Screen s1, Screen s2) {
                        return _srComparator.compare(s1.getScreenResult(), s2.getScreenResult());
                    }
                };
            }
        });

        columns.add(new TextSetEntityColumn<Screen>(Screen.screenResult.to(ScreenResult.dataColumns),
                "Assay Readout Type", "The assay readout type for the screen", TableColumn.UNGROUPED) {
            @Override
            public Set<String> getCellValue(Screen screen) {
                if (screen.getScreenResult() != null) { // conditional check, fixes issue #107 - adding the "Assay Readout Type" column causes an exception
                    return Sets.newHashSet(Iterables.transform(screen.getScreenResult().getAssayReadoutTypes(),
                            Functions.toStringFunction()));
                } else {
                    return Sets.newHashSet();
                }
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        return columns;
    }

    public List<TableColumn<Screen, ?>> buildScreenAdminColumns() {
        List<TableColumn<Screen, ?>> columns = Lists.newArrayList();

        columns.add(new EnumEntityColumn<Screen, ScreenDataSharingLevel>(
                RelationshipPath.from(Screen.class).toProperty("dataSharingLevel"), "Data Sharing Level",
                "The data sharing level", TableColumn.UNGROUPED, ScreenDataSharingLevel.values()) {
            @Override
            public ScreenDataSharingLevel getCellValue(Screen screen) {
                return screen.getDataSharingLevel();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(false);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new DateEntityColumn<Screen>(
                RelationshipPath.from(Screen.class).toProperty("dataPrivacyExpirationDate"),
                "Data Privacy Expiration Date", "The date on which the screen will become visible to level 1 users",
                TableColumn.UNGROUPED) {
            @Override
            public LocalDate getDate(Screen screen) {
                return screen.getDataPrivacyExpirationDate();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new DateEntityColumn<Screen>(Screen.labActivities.toProperty("dateOfActivity"),
                "Date of First Activity", "The date of the first lab activity performed for this screen",
                TableColumn.UNGROUPED) {
            @Override
            protected LocalDate getDate(Screen screen) {
                return screen.getLabActivities().isEmpty() ? null
                        : screen.getLabActivities().first().getDateOfActivity();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new DateEntityColumn<Screen>(Screen.labActivities.toProperty("dateOfActivity"),
                "Date Of Last Activity", "The date of the last lab activity performed for this screen",
                TableColumn.UNGROUPED) {
            @Override
            protected LocalDate getDate(Screen screen) {
                return screen.getLabActivities().isEmpty() ? null
                        : screen.getLabActivities().last().getDateOfActivity();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        if (!!!getApplicationProperties().isFacility(LincsScreensaverConstants.FACILITY_KEY)) {
            columns.add(new EnumEntityColumn<Screen, ScreenStatus>(Screen.statusItems.toProperty("status"),
                    "Status", "The current status of the screen, e.g., 'Completed', 'Ongoing', 'Pending', etc.",
                    TableColumn.UNGROUPED, ScreenStatus.values()) {
                @Override
                public ScreenStatus getCellValue(Screen screen) {
                    SortedSet<StatusItem> statusItems = screen.getStatusItems();
                    return statusItems.isEmpty() ? null : statusItems.last().getStatus();
                }
            });
            columns.get(columns.size() - 1).setAdministrative(true);

            columns.add(new DateEntityColumn<Screen>(Screen.statusItems.toProperty("statusDate"), "Status Date",
                    "The date of the most recent change of status for the screen", TableColumn.UNGROUPED) {
                @Override
                protected LocalDate getDate(Screen screen) {
                    SortedSet<StatusItem> statusItems = screen.getStatusItems();
                    return statusItems.isEmpty() ? null : statusItems.last().getStatusDate();
                }
            });
            columns.get(columns.size() - 1).setAdministrative(true);
        }

        // TODO: should make this a vocab list, but need support for list-of-vocab column type
        columns.add(new TextSetEntityColumn<Screen>(Screen.fundingSupports.toProperty("value"), "Funding Supports",
                "The list of funding supports for the screen", TableColumn.UNGROUPED) {
            @Override
            public Set<String> getCellValue(Screen screen) {
                return Sets
                        .newHashSet(Iterables.transform(screen.getFundingSupports(), Functions.toStringFunction()));
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new IntegerEntityColumn<Screen>(
                RelationshipPath.from(Screen.class).toProperty("screenedExperimentalWellCount"),
                "Experimental Wells Screened (Non-unique)",
                "The number of experimental library wells that have been screened (counting duplicate wells multiple times, ignoring replicates)",
                TableColumn.UNGROUPED) {
            @Override
            public Integer getCellValue(Screen screen) {
                return screen.getScreenedExperimentalWellCount();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new IntegerEntityColumn<Screen>(
                RelationshipPath.from(Screen.class).toProperty("screenedExperimentalWellCount"),
                "Experimental Wells Screened (Unique)",
                "The number of experimental library wells that have been screened (counting duplicate wells once, ignoring replicates)",
                TableColumn.UNGROUPED) {
            @Override
            public Integer getCellValue(Screen screen) {
                return screen.getUniqueScreenedExperimentalWellCount();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new IntegerEntityColumn<Screen>(
                RelationshipPath.from(Screen.class).toProperty("totalPlatedLabCherryPicks"),
                "Total Plated Cherry Picks",
                "The number of lab cherry picks that have been plated to date, for all cherry pick requests",
                TableColumn.UNGROUPED) {
            @Override
            public Integer getCellValue(Screen screen) {
                return screen.getTotalPlatedLabCherryPicks();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        columns.add(new TextEntityColumn<Screen>(RelationshipPath.from(Screen.class).toProperty("summary"),
                "Summary", "A summary of the screen", TableColumn.UNGROUPED) {
            @Override
            public String getCellValue(Screen screen) {
                return screen.getSummary();
            }
        });
        columns.get(columns.size() - 1).setAdministrative(true);
        columns.get(columns.size() - 1).setVisible(false);

        return columns;
    }

    public List<TableColumn<Screen, ?>> buildScreenSummaryColumns(boolean isNonScreenSearchResults) {
        List<TableColumn<Screen, ?>> columns = Lists.newArrayList();
        columns.add(new TextEntityColumn<Screen>(Screen.facilityId, "Screen ID",
                "The facility-assigned screen identifier", TableColumn.UNGROUPED) {
            @Override
            public String getCellValue(Screen screen) {
                return screen.getFacilityId();
            }

            @Override
            public Object cellAction(Screen screen) {
                // note: we explicitly call getEntityViewer(), since this column may be used in other search result types
                return getEntityViewer().viewEntity(screen);
            }

            @Override
            public boolean isCommandLink() {
                return true;
            }
        });

        columns.add(new EnumEntityColumn<Screen, ScreenType>(
                RelationshipPath.from(Screen.class).toProperty("screenType"), "Screen Type",
                "'RNAi' or 'Small Molecule'", TableColumn.UNGROUPED, ScreenType.values()) {
            @Override
            public ScreenType getCellValue(Screen screen) {
                return screen.getScreenType();
            }
        });

        if (!!!getApplicationProperties().isFacility(LincsScreensaverConstants.FACILITY_KEY)) {
            columns.add(new EnumEntityColumn<Screen, ProjectPhase>(
                    RelationshipPath.from(Screen.class).toProperty("projectPhase"), "Project Phase",
                    "'Primary','Counter', or 'Follow-Up'", TableColumn.UNGROUPED, ProjectPhase.values()) {
                @Override
                public ProjectPhase getCellValue(Screen screen) {
                    return screen.getProjectPhase();
                }
            });
            columns.add(new TextEntityColumn<Screen>(RelationshipPath.from(Screen.class).toProperty("projectId"),
                    "Project ID", "The project ID of the screen", TableColumn.UNGROUPED) {
                @Override
                public String getCellValue(Screen screen) {
                    return screen.getProjectId();
                }

                @Override
                public boolean isCommandLink() {
                    return true;
                }

                @Override
                public Object cellAction(Screen screen) {
                    searchScreensForProject(screen.getProjectId());
                    return BROWSE_SCREENS;
                }
            });
        }

        columns.add(new TextEntityColumn<Screen>(RelationshipPath.from(Screen.class).toProperty("title"), "Title",
                "The title of the screen", TableColumn.UNGROUPED) {
            @Override
            public String getCellValue(Screen screen) {
                return screen.getTitle();
            }
        });
        columns.add(new UserNameColumn<Screen, ScreeningRoomUser>(Screen.labHead, "Lab Head",
                "The head of the lab performing the screen", TableColumn.UNGROUPED, _userViewer) {
            @Override
            public ScreeningRoomUser getUser(Screen screen) {
                return screen.getLabHead();
            }
        });
        ((HasFetchPaths<Screen>) columns.get(columns.size() - 1))
                .addRelationshipPath(Screen.labHead.to(LabHead.labAffiliation));
        columns.add(new TextEntityColumn<Screen>(
                Screen.labHead.to(ScreensaverUser.labAffiliation).toProperty("affiliationName"), "Lab Affiliation",
                "The affiliation of the lab performing the screen", TableColumn.UNGROUPED) {
            @Override
            public String getCellValue(Screen screen) {
                if (screen.getLabHead() != null) {
                    return screen.getLabHead().getLab().getLabAffiliationName();
                }
                return null;
            }
        });
        columns.get(columns.size() - 1).setVisible(false);
        columns.add(new UserNameColumn<Screen, ScreeningRoomUser>(Screen.leadScreener, "Lead Screener",
                "The scientist primarily responsible for running the screen", TableColumn.UNGROUPED, _userViewer) {
            @Override
            public ScreeningRoomUser getUser(Screen screen) {
                return screen.getLeadScreener();
            }
        });

        if (!!!getApplicationProperties().isFacility(LincsScreensaverConstants.FACILITY_KEY)) {
            columns.add(new DateTimeEntityColumn<Screen>(Screen.thisEntity.toProperty("dateCreated"),
                    isNonScreenSearchResults ? "Date Screen Recorded" : "Date Recorded",
                    "The date the screen was first recorded in the Screensaver", TableColumn.UNGROUPED) {
                @Override
                protected DateTime getDateTime(Screen screen) {
                    return screen.getDateCreated();
                }
            });
        } else {
            columns.add(new DateEntityColumn<Screen>(Screen.thisEntity.toProperty("dateCreated"),
                    "Date Data Received", "The date the screen data was received", TableColumn.UNGROUPED) {
                @Override
                protected LocalDate getDate(Screen screen) {
                    return screen.getDateCreated().toLocalDate();
                }
            });

        }

        if (getApplicationProperties().isFacility(LincsScreensaverConstants.FACILITY_KEY)) {
            columns.add(new DateEntityColumn<Screen>(Screen.thisEntity.toProperty("dateLoaded"), "Date Loaded",
                    "The date the screen data was loaded", TableColumn.UNGROUPED) {
                @Override
                protected LocalDate getDate(Screen screen) {
                    return screen.getDateLoaded() == null ? null : screen.getDateLoaded().toLocalDate();
                }
            });
        }

        if (getApplicationProperties().isFacility(LincsScreensaverConstants.FACILITY_KEY)) {
            columns.add(new DateEntityColumn<Screen>(Screen.thisEntity.toProperty("datePubliclyAvailable"),
                    "Date Publicly Available", "The date the screen data was made publicly available",
                    TableColumn.UNGROUPED) {
                @Override
                protected LocalDate getDate(Screen screen) {
                    return screen.getDatePubliclyAvailable() == null ? null
                            : screen.getDatePubliclyAvailable().toLocalDate();
                }
            });
        }

        // RNAi fields

        columns.add(new EnumEntityColumn<Screen, Species>(RelationshipPath.from(Screen.class).toProperty("species"),
                "Species", "The species of the cell organism", TableColumn.UNGROUPED, Species.values()) {
            @Override
            public Species getCellValue(Screen screen) {
                return screen.getSpecies() == null ? null : screen.getSpecies();
            }
        });
        columns.get(columns.size() - 1).setVisible(false);

        // Small Molecule fields
        columns.add(
                new EnumEntityColumn<Screen, AssayType>(RelationshipPath.from(Screen.class).toProperty("assayType"),
                        "Assay Type", "The assay type of the Screen", TableColumn.UNGROUPED, AssayType.values()) {
                    @Override
                    public AssayType getCellValue(Screen screen) {
                        return screen.getAssayType() == null ? null : screen.getAssayType();
                    }
                });
        columns.get(columns.size() - 1).setVisible(false);

        // Non-LINCS Cell Line

        columns.add(new TextSetEntityColumn<Screen>(RelationshipPath.from(Screen.class).to(Screen.cellLines),
                "Cell Lines", "The cell lines associated with this screen", TableColumn.UNGROUPED) {
            public Set<String> getCellValue(Screen screen) {
                Set<CellLine> cellLines = Sets.newHashSet(screen.getCellLines());
                if (cellLines.isEmpty()) {
                    return Sets.newHashSet("<not yet specified>");
                }
                return Sets.newHashSet(Iterables.transform(cellLines, new Function<CellLine, String>() {
                    public String apply(CellLine cell) {
                        return cell.getValue();
                    }
                }));
            }
        });
        columns.get(columns.size() - 1).setVisible(false);
        //    columns.add(new TextEntityColumn<Screen>(RelationshipPath.from(Screen.class).toProperty("cellLine"),
        //      "Cell Line", "The cell line", TableColumn.UNGROUPED) {
        //      @Override
        //      public String getCellValue(Screen screen)
        //      {
        //        return screen.getCellLine() == null ? null : screen.getCellLine().getValue();
        //      }
        //    });

        columns.add(
                new TextEntityColumn<Screen>(RelationshipPath.from(Screen.class).toProperty("transfectionAgent"),
                        "Transfection Agent", "The transfection agent", TableColumn.UNGROUPED) {
                    @Override
                    public String getCellValue(Screen screen) {
                        return screen.getTransfectionAgent() == null ? null
                                : screen.getTransfectionAgent().getValue();
                    }
                });
        columns.get(columns.size() - 1).setVisible(false);

        return columns;
    }
}