//$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.screenresults; import java.util.List; import java.util.Map; import java.util.Set; import javax.faces.event.ValueChangeEvent; import javax.faces.model.DataModel; import javax.faces.model.ListDataModel; import com.google.common.base.Joiner; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.log4j.Logger; import org.springframework.transaction.annotation.Transactional; import edu.harvard.med.screensaver.ScreensaverConstants; import edu.harvard.med.screensaver.db.Criterion; import edu.harvard.med.screensaver.db.GenericEntityDAO; import edu.harvard.med.screensaver.db.HqlBuilderCallback; import edu.harvard.med.screensaver.db.ScreenResultsDAO; import edu.harvard.med.screensaver.db.Criterion.Operator; import edu.harvard.med.screensaver.db.datafetcher.PropertyPathDataFetcher; import edu.harvard.med.screensaver.db.datafetcher.Tuple; import edu.harvard.med.screensaver.db.hqlbuilder.HqlBuilder; import edu.harvard.med.screensaver.model.libraries.Well; import edu.harvard.med.screensaver.model.meta.PropertyPath; import edu.harvard.med.screensaver.model.meta.RelationshipPath; import edu.harvard.med.screensaver.model.screenresults.DataColumn; import edu.harvard.med.screensaver.model.screenresults.ScreenResult; import edu.harvard.med.screensaver.model.screens.AssayReadoutType; import edu.harvard.med.screensaver.model.screens.ScreenType; import edu.harvard.med.screensaver.model.users.AdministratorUser; import edu.harvard.med.screensaver.service.screenresult.ScreenResultDeleter; import edu.harvard.med.screensaver.ui.arch.datatable.column.TableColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.FetchPaths; import edu.harvard.med.screensaver.ui.arch.view.EntityViewerBackingBean; import edu.harvard.med.screensaver.ui.arch.view.aspects.UICommand; import edu.harvard.med.screensaver.ui.libraries.WellSearchResults; import edu.harvard.med.screensaver.ui.screens.ScreenViewer; /** * JSF backing bean for Screen Result Viewer web page (screenresultviewer.jsp). * <p> * The <code>screenResult</code> property should be set to the {@link ScreenResult} that is to be viewed.<br> * * @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a> * @author <a mailto="john_sullivan@hms.harvard.edu">John Sullivan</a> */ @SuppressWarnings("unchecked") public class ScreenResultViewer extends EntityViewerBackingBean<ScreenResult> { private static Logger log = Logger.getLogger(ScreenResultViewer.class); private ScreenResultsDAO _screenResultsDao; private ScreenResultDeleter _screenResultDeleter; private ScreenViewer _screenViewer; private ScreenResultDataColumnsTables _screenResultDataColumnsTables; private WellSearchResults _wellSearchResults; private boolean _isWellSearchResultsInitialized; private boolean _isFilterPositives = false; private boolean _isShowMutualColumns = false; private DataModel _positivesDataColumnsModel; /** * @motivation for CGLIB2 */ protected ScreenResultViewer() {} public ScreenResultViewer(ScreenResultViewer thisProxy, GenericEntityDAO dao, ScreenResultsDAO screenResultsDao, ScreenResultDeleter screenResultDeleter, ScreenViewer screenViewer, ScreenResultDataColumnsTables screenResultDataColumnsTables, WellSearchResults wellSearchResults) { super(thisProxy, ScreenResult.class, EDIT_SCREEN_RESULT, dao); _screenResultsDao = screenResultsDao; _screenResultDeleter = screenResultDeleter; _screenViewer = screenViewer; _screenResultDataColumnsTables = screenResultDataColumnsTables; _wellSearchResults = wellSearchResults; getIsPanelCollapsedMap().put("screeningSummary", false); getIsPanelCollapsedMap().put("dataColumnsTable", true); getIsPanelCollapsedMap().put("dataTable", true); getIsPanelCollapsedMap().put("heatMaps", true); getIsPanelCollapsedMap().put("cellHTS2", true); } @Override protected void initializeEntity(ScreenResult entity) {} @Override protected void initializeViewer(ScreenResult screenResult) { // lazy initialization of _wellSearchResults, for performance (avoid expense of determining columns, if not being viewed) _isWellSearchResultsInitialized = false; _isFilterPositives = false; _isShowMutualColumns = false; _positivesDataColumnsModel = null; // open viewer with dataTable panel closed, to avoid expense of initializing unless user explicitly requests to view it, while scrolling through multiple screen results getIsPanelCollapsedMap().put("dataTable", true); getIsPanelCollapsedMap().put("heatMaps", true); _screenResultDataColumnsTables.initialize(screenResult.getDataColumnsList()); } /** * @return the assay readout types, as a formatted, comma-delimited string; "<none>" if no assay readout types */ public String getAssayReadoutTypesText() { Set<AssayReadoutType> assayReadoutTypes; if (getEntity() == null) { assayReadoutTypes = Sets.newHashSet(); } else { assayReadoutTypes = getEntity().getAssayReadoutTypes(); if (assayReadoutTypes.isEmpty()) { return "<none>"; } } return Joiner.on(", ").join(assayReadoutTypes); } public ScreenResultDataColumnsTables getDataColumnsTable() { return _screenResultDataColumnsTables; } public DataModel getPartitionedPositivesDataColumnsModel() { if (_positivesDataColumnsModel == null && getEntity() != null) { _positivesDataColumnsModel = new ListDataModel(getEntity().getPartitionedPositivesDataColumns()); } return _positivesDataColumnsModel; } public WellSearchResults getWellSearchResults() { // lazy initialization of _wellSearchResults, for performance (avoid expense of determining columns, if not being viewed) if (!_isWellSearchResultsInitialized && !getIsPanelCollapsedMap().get("dataTable")) { _wellSearchResults.searchWellsForScreenResult(getEntity(), _isFilterPositives); _isWellSearchResultsInitialized = true; if (_isShowMutualColumns) { showMutualColumnsCommand(); } } return _wellSearchResults; } // JSF application methods @UICommand public String delete() { if (getEntity() != null) { _screenResultDeleter.deleteScreenResult(getEntity(), (AdministratorUser) getScreensaverUser()); showMessage("deletedEntity", "screen result"); return _screenViewer.reload(); } return REDISPLAY_PAGE_ACTION_RESULT; } public boolean isFilterPositives() { return _isFilterPositives; } public void setFilterPositives(boolean value) { _isFilterPositives = value; } public void toggleFilterPositives(ValueChangeEvent event) { Boolean showFilterPositives = (Boolean) event.getNewValue(); if (showFilterPositives.booleanValue() != _isFilterPositives) { setFilterPositives(showFilterPositives); } } @UICommand public String filterPositivesCommand() { _isWellSearchResultsInitialized = false; return REDISPLAY_PAGE_ACTION_RESULT; } public boolean isShowMutualColumns() { return _isShowMutualColumns; } public void setShowMutualColumns(boolean value) { _isShowMutualColumns = value; } public void toggleShowMutualColumns(ValueChangeEvent event) { Boolean showMutualColumns = (Boolean) event.getNewValue(); if (showMutualColumns.booleanValue() != _isShowMutualColumns) { setShowMutualColumns(showMutualColumns); } } @UICommand @Transactional public String showMutualColumnsCommand() { final ScreenResult screenResult = getEntity(); String crossScreenCountColumnName = ""; if (screenResult.getScreen().getScreenType() == ScreenType.SMALL_MOLECULE) { crossScreenCountColumnName = "[" + ScreensaverConstants.DEFAULT_BATCH_STUDY_ID_POSITIVE_COUNT_SM + "]"; //TODO: get this from a bean property } else { crossScreenCountColumnName = "[" + ScreensaverConstants.DEFAULT_BATCH_STUDY_ID_POSITIVE_COUNT_RNAI + "]"; } // TODO: must refactor to make this code unit-testable HqlBuilderCallback hqlBuilderCallback = new HqlBuilderCallback() { @Override public void apply(HqlBuilder hql) { hql. where("aw1", "screenResult", Operator.EQUAL, screenResult). where("aw2", "screenResult", Operator.NOT_EQUAL, screenResult); // ignore data columns from the screen result passed in Map<PropertyPath<Well>,List<? extends Criterion<?>>> criteria = FetchPaths.<Well,Tuple<String>>getFilteringCriteria(getWellSearchResults().getColumnManager().getVisibleColumns()); PropertyPathDataFetcher.addFilteringRestrictions(hql, Maps.<RelationshipPath<Well>,String>newHashMap(), criteria); // TODO: to implement [#2372], add the same filtering criteria (HQL where clauses) that were used to filter the WellSearchResult, to the hql object here } }; for (DataColumn mutualPositivesDataColumn : _screenResultsDao.findMutualPositiveColumns(hqlBuilderCallback)) { String mutualPositivesColumnName = WellSearchResults.makeColumnName(mutualPositivesDataColumn, getDao().reloadEntity(mutualPositivesDataColumn, true, DataColumn.ScreenResult.to(ScreenResult.screen)).getScreenResult().getScreen().getFacilityId()); boolean found = false; for (TableColumn tc : getWellSearchResults().getColumnManager().getAllColumns()) { if (tc.getName().equals(mutualPositivesColumnName)) { /* * TODO: this will cause the column to be made invisible if the user has selected on their own and then they * check/and/uncheck the filterPositives command, we would need to maintain the set of _user_ selected columns * separately in order to do remember their selections; in this case, the "show mutual" button just erases the * users choices once it is unchecked. */ tc.setVisible(_isShowMutualColumns); found = true; continue; } if (tc.getName().contains(crossScreenCountColumnName)) { tc.setVisible(_isShowMutualColumns); } } if (!found) { log.warn("Mutual positives data column not found in data table: " + mutualPositivesColumnName); } } return REDISPLAY_PAGE_ACTION_RESULT; } }