// $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.activities; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.SortedSet; import org.apache.log4j.Logger; import org.joda.time.LocalDate; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import edu.harvard.med.screensaver.db.EntityInflator; import edu.harvard.med.screensaver.db.GenericEntityDAO; 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.activities.Activity; import edu.harvard.med.screensaver.model.activities.AdministrativeActivity; import edu.harvard.med.screensaver.model.activities.ServiceActivity; import edu.harvard.med.screensaver.model.activities.ServiceActivityType; import edu.harvard.med.screensaver.model.cherrypicks.CherryPickAssayPlate; import edu.harvard.med.screensaver.model.cherrypicks.CherryPickLiquidTransfer; import edu.harvard.med.screensaver.model.cherrypicks.CherryPickRequest; import edu.harvard.med.screensaver.model.libraries.Copy; import edu.harvard.med.screensaver.model.libraries.Plate; import edu.harvard.med.screensaver.model.libraries.WellVolumeCorrectionActivity; import edu.harvard.med.screensaver.model.meta.RelationshipPath; import edu.harvard.med.screensaver.model.screens.CherryPickScreening; import edu.harvard.med.screensaver.model.screens.FundingSupport; import edu.harvard.med.screensaver.model.screens.LabActivity; import edu.harvard.med.screensaver.model.screens.LibraryScreening; import edu.harvard.med.screensaver.model.screens.Screen; import edu.harvard.med.screensaver.model.screens.ScreenStatus; 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.TextColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.DateEntityColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.EnumEntityColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.IntegerEntityColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.entity.RelatedEntityColumn; 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.column.entity.VocabularyEntityColumn; 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.arch.util.converter.VocabularyConverter; import edu.harvard.med.screensaver.ui.arch.view.EntityViewer; import edu.harvard.med.screensaver.ui.cherrypickrequests.CherryPickRequestViewer; import edu.harvard.med.screensaver.ui.screens.ScreenSearchResults; import edu.harvard.med.screensaver.ui.screens.ScreenViewer; import edu.harvard.med.screensaver.ui.users.UserViewer; import edu.harvard.med.screensaver.util.CollectionUtils; /** * A {@link SearchResults} for {@link Activity Activities}. * * @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a> * @author <a mailto="john_sullivan@hms.harvard.edu">John Sullivan</a> */ public class ActivitySearchResults extends EntityBasedEntitySearchResults<Activity,Integer> { private final static Set<String> activityTypes = Sets.newLinkedHashSet(); { for (ServiceActivityType type : ServiceActivityType.values()) { activityTypes.add(type.toString()); } activityTypes.add(LibraryScreening.ACTIVITY_TYPE_NAME); activityTypes.add(LibraryScreening.EXTERNAL_LIBRARY_SCREENING_ACTIVITY_TYPE_NAME); activityTypes.add(CherryPickScreening.ACTIVITY_TYPE_NAME); activityTypes.add(CherryPickLiquidTransfer.ACTIVITY_TYPE_NAME); } protected static final String SCREEEN_COLUMN_GROUP = "Screen"; private static Logger log = Logger.getLogger(ActivitySearchResults.class); private UserViewer _userViewer; private GenericEntityDAO _dao; private ScreenViewer _screenViewer; private CherryPickRequestViewer _cprViewer; private ScreenSearchResults _screensBrowser; /** * @motivation for CGLIB2 */ protected ActivitySearchResults() { } public ActivitySearchResults(ActivityViewer activityViewer, ScreenViewer screenViewer, ScreenSearchResults screensBrowser, CherryPickRequestViewer cprViewer, UserViewer userViewer, GenericEntityDAO dao) { super((EntityViewer<Activity>) activityViewer); _dao = dao; _screenViewer = screenViewer; _screensBrowser = screensBrowser; _cprViewer = cprViewer; _userViewer = userViewer; } @Override public void searchAll() { setTitle("All Activities"); initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(new EntityDataFetcher<Activity,Integer>(Activity.class, _dao))); } public void searchAllUserActivities() { setTitle("User Activities"); EntityDataFetcher<Activity,Integer> entityDataFetcher = (EntityDataFetcher<Activity,Integer>) new EntityDataFetcher<Activity,Integer>(Activity.class, _dao) { @Override public void addDomainRestrictions(HqlBuilder hql) { // HACK: improve this query so as to be less dependent upon the potential subclasses of AdministrativeActivities hql.where(new edu.harvard.med.screensaver.db.hqlbuilder.Predicate() { @Override public String toHql() { return getRootAlias() + ".class <> " + AdministrativeActivity.class.getName() + " and " + getRootAlias() + ".class <> " + WellVolumeCorrectionActivity.class.getName(); } }); } }; initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(entityDataFetcher)); } public void searchActivitiesForUser(final ScreensaverUser user) { setTitle("Activities for " + user.getFullNameFirstLast()); initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(new EntityDataFetcher<Activity,Integer>(Activity.class, _dao) { @Override public void addDomainRestrictions(HqlBuilder hql) { if (user instanceof ScreeningRoomUser) { ScreeningRoomUser user2 = new EntityInflator<ScreeningRoomUser>(_dao, (ScreeningRoomUser) user, true).need(ScreeningRoomUser.serviceActivities).need(ScreeningRoomUser.activitiesPerformed).inflate(); DataFetcherUtil.addDomainRestrictions(hql, getRootAlias(), Sets.newHashSet(Iterables.transform(((ScreeningRoomUser) user2).getAssociatedActivities(), Entity.ToEntityId))); } else { ScreensaverUser user2 = new EntityInflator<ScreensaverUser>(_dao, (ScreensaverUser) user, true).need(ScreeningRoomUser.activitiesPerformed).inflate(); DataFetcherUtil.addDomainRestrictions(hql, getRootAlias(), Sets.newHashSet(Iterables.transform(((ScreensaverUser) user2).getActivitiesPerformed(), Entity.ToEntityId))); } } })); } public void searchLibraryScreeningActivitiesForCopy(final Copy copy) { setTitle("Library Screenings for library " + copy.getLibrary().getLibraryName() + ", copy " + copy.getName()); initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(new EntityDataFetcher<Activity,Integer>(Activity.class, _dao) { @Override public void addDomainRestrictions(HqlBuilder hql) { DataFetcherUtil.addDomainRestrictions(hql, LibraryScreening.assayPlatesScreened.to("plateScreened").to("copy"), copy, getRootAlias()); } })); } public void searchLibraryScreeningActivitiesForPlate(final Plate plate) { setTitle("Library Screenings for plate " + plate.getPlateNumber()); initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(new EntityDataFetcher<Activity,Integer>(Activity.class, _dao) { @Override public void addDomainRestrictions(HqlBuilder hql) { DataFetcherUtil.addDomainRestrictions(hql, LibraryScreening.assayPlatesScreened.to("plateScreened"), plate, getRootAlias()); } })); } public void searchActivities(final Set<Activity> activities, String title) { setTitle(title); initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(new EntityDataFetcher<Activity,Integer>(Activity.class, _dao) { @Override public void addDomainRestrictions(HqlBuilder hql) { DataFetcherUtil.addDomainRestrictions(hql, getRootAlias(), CollectionUtils.<Integer>entityIds(activities)); } })); } // implementations of the SearchResults abstract methods @Override protected List<? extends TableColumn<Activity,?>> buildColumns() { ArrayList<TableColumn<Activity,?>> columns = Lists.newArrayList(); columns.add(new IntegerEntityColumn<Activity>(RelationshipPath.from(Activity.class).toId(), "Activity ID", "The activity number", TableColumn.UNGROUPED) { @Override public Integer getCellValue(Activity activity) { return activity.getActivityId(); } @Override public Object cellAction(Activity activity) { return viewSelectedEntity(); } @Override public boolean isCommandLink() { return true; } }); // columns.add(new VocabularyEntityColumn<Activity,String>(RelationshipPath.from(Activity.class).toProperty("activityType"), columns.add(new VocabularyEntityColumn<Activity,String>(RelationshipPath.from(Activity.class).toId(), "Activity Type", "The type of the activity", TableColumn.UNGROUPED, new VocabularyConverter<String>(getActivityTypes()), getActivityTypes()) { @Override public String getCellValue(Activity activity) { return activity.getActivityTypeName(); } }); columns.add(new DateEntityColumn<Activity>(RelationshipPath.from(Activity.class).toProperty("datePerformed"), "Date Performed", "The date of the activity", TableColumn.UNGROUPED) { @Override protected LocalDate getDate(Activity activity) { return activity.getDateOfActivity(); } }); columns.add(new DateEntityColumn<Activity>(RelationshipPath.from(Activity.class).toProperty("dateCreated"), "Date Recorded", "The date the activity was recorded", TableColumn.UNGROUPED) { @Override protected LocalDate getDate(Activity activity) { return activity.getDateCreated().toLocalDate(); } }); columns.get(columns.size() - 1).setVisible(showAdminStatusFields()); columns.add(new UserNameColumn<Activity,ScreensaverUser>(RelationshipPath.from(Activity.class).to(Activity.performedBy.getLeaf()), "Performed By", "The person that performed the activity", TableColumn.UNGROUPED, _userViewer) { @Override public ScreensaverUser getUser(Activity activity) { return (ScreensaverUser) activity.getPerformedBy(); } }); columns.add(new UserNameColumn<Activity,ScreeningRoomUser>(RelationshipPath.from(Activity.class).to(ServiceActivity.servicedUser), "Serviced User", "The user that was serviced by this activity", TableColumn.UNGROUPED, _userViewer) { @Override public ScreeningRoomUser getUser(Activity activity) { if (activity instanceof ServiceActivity) { return ((ServiceActivity) activity).getServicedUser(); } return null; } }); columns.addAll(buildLabActivityColumns()); columns.add(new TextEntityColumn<Activity>(RelationshipPath.from(Activity.class).toProperty("comments"), "Comments", "Activity comments", TextColumn.UNGROUPED) { @Override public String getCellValue(Activity activity) { return activity.getComments(); } }); return columns; } private boolean showAdminStatusFields() { return isUserInRole(ScreensaverUserRole.SCREENS_ADMIN) || isUserInRole(ScreensaverUserRole.READ_EVERYTHING_ADMIN); } public void searchActivitiesForScreen(final Screen screen) { setTitle("Activities for screen " + screen.getFacilityId()); initialize(new InMemoryEntityDataModel<Activity,Integer,Activity>(new EntityDataFetcher<Activity,Integer>(Activity.class, _dao) { @Override public void addDomainRestrictions(HqlBuilder hql) { hql.from(getRootAlias(), LabActivity.Screen, "las"); hql.from(getRootAlias(), ServiceActivity.servicedScreen, "sas"); hql.where( new edu.harvard.med.screensaver.db.hqlbuilder.Predicate() { @Override public String toHql() { return "las = " + screen.getScreenId() + " or " + " sas = " + screen.getScreenId(); } } ); } })); } @SuppressWarnings("unchecked") private List<? extends TableColumn<Activity,?>> buildLabActivityColumns() { List<TableColumn<Activity,?>> columns = Lists.newArrayList(); IntegerEntityColumn<Activity> column = new IntegerEntityColumn<Activity>(RelationshipPath.from(Activity.class).toProperty("screenedExperimentalWellCount"), "Experimental Wells Screened (Library Screening)", "The number of experimental library wells that were screened during this activity (ignoring replicates)", TableColumn.UNGROUPED) { @Override public Integer getCellValue(Activity activity) { if (activity instanceof LibraryScreening) { return ((LibraryScreening) activity).getScreenedExperimentalWellCount(); } return null; } }; column.setVisible(false); // TODO: reinstae ordering: // columns.add(2, column); columns.add(new TextEntityColumn<Activity>(RelationshipPath.from( Activity.class).toProperty("fundingSupport"), "Funding Support", "Funding support", TextColumn.UNGROUPED) { @Override public String getCellValue(Activity activity) { if (activity instanceof ServiceActivity) { FundingSupport fs = ((ServiceActivity)activity).getFundingSupport(); return fs == null? "": fs.getValue(); } return null; } }); columns.get(columns.size() - 1).setVisible(false); column = new IntegerEntityColumn<Activity>(CherryPickScreening.cherryPickRequest.castToSupertype(Activity.class), "Cherry Pick Request #", "The cherry pick request number, if applicable", TableColumn.UNGROUPED) { @Override public Integer getCellValue(Activity activity) { if (activity instanceof LabActivity) { CherryPickRequest cherryPickRequest = getCherryPickRequest(activity); return cherryPickRequest == null ? null : cherryPickRequest.getCherryPickRequestNumber(); } return null; } private CherryPickRequest getCherryPickRequest(Activity activity) { if (activity instanceof CherryPickLiquidTransfer) { return ((CherryPickLiquidTransfer) activity).getCherryPickRequest(); } else if (activity instanceof CherryPickScreening) { return ((CherryPickScreening) activity).getCherryPickRequest(); } return null; } @Override public Object cellAction(Activity activity) { return _cprViewer.viewEntity(getCherryPickRequest(activity)); } @Override public boolean isCommandLink() { return true; } }; column.addRelationshipPath(CherryPickLiquidTransfer.cherryPickAssayPlates.to(CherryPickAssayPlate.cherryPickRequest).castToSupertype(Activity.class)); column.setVisible(false); // TODO: reinstate ordering //columns.add(2, column); Iterable<TableColumn<Screen,?>> screenColumns = Iterables.concat(_screensBrowser.buildScreenSummaryColumns(true), _screensBrowser.buildScreenAdminColumns()); screenColumns = Iterables.filter(screenColumns, new Predicate<TableColumn<Screen,?>>() { public boolean apply(TableColumn<Screen,?> c) { return !!!c.getName().equals("Date Of Last Activity"); } }); List<TableColumn<Activity,?>> labActivityScreenColumns = Lists.newArrayList(Iterables.transform(screenColumns, new Function<TableColumn<Screen,?>,TableColumn<Activity,?>>() { public TableColumn<Activity,?> apply(TableColumn<Screen,?> delegateColumn) { RelatedEntityColumn<Activity,Screen,Object> column = new RelatedEntityColumn<Activity,Screen,Object>(Screen.class, LabActivity.Screen.castToSupertype(Activity.class), (TableColumn<Screen,Object>) delegateColumn, SCREEEN_COLUMN_GROUP) { public Screen getRelatedEntity(Activity a) { Screen s = null; if (a instanceof LabActivity) { s = ((LabActivity) a).getScreen(); } else if (a instanceof ServiceActivity) { // reload the activity as a service activity // thereby instantiate the serviced screen lazy connection a = _dao.findEntityById(ServiceActivity.class, a.getActivityId()); s = ((ServiceActivity) a).getServicedScreen(); } if(s != null){ _dao.reloadEntity(s, true, Screen.statusItems); return s; } return null; } }; column.setVisible(false); return column; } })); labActivityScreenColumns.get(0).setVisible(true); columns.addAll(labActivityScreenColumns); return columns; } protected Set<String> getActivityTypes() { return activityTypes; } }