Java tutorial
// $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; } }