// $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.model.screens; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Transient; import javax.persistence.Version; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.Sets; import org.apache.log4j.Logger; import org.hibernate.annotations.Sort; import org.hibernate.annotations.SortType; import org.hibernate.annotations.Type; import org.joda.time.LocalDate; import edu.harvard.med.screensaver.ScreensaverConstants; import edu.harvard.med.screensaver.db.ScreenResultsDAO; import edu.harvard.med.screensaver.model.AbstractEntityVisitor; import edu.harvard.med.screensaver.model.AttachedFile; import edu.harvard.med.screensaver.model.AttachedFilesEntity; import edu.harvard.med.screensaver.model.BusinessRuleViolationException; import edu.harvard.med.screensaver.model.DataModelViolationException; import edu.harvard.med.screensaver.model.DuplicateEntityException; import edu.harvard.med.screensaver.model.MolarConcentration; import edu.harvard.med.screensaver.model.RequiredPropertyException; import edu.harvard.med.screensaver.model.activities.AdministrativeActivity; import edu.harvard.med.screensaver.model.activities.AdministrativeActivityType; import edu.harvard.med.screensaver.model.activities.ServiceActivity; import edu.harvard.med.screensaver.model.annotations.Derived; import edu.harvard.med.screensaver.model.annotations.ToMany; import edu.harvard.med.screensaver.model.cells.ExperimentalCellInformation; import edu.harvard.med.screensaver.model.cherrypicks.CherryPickLiquidTransfer; import edu.harvard.med.screensaver.model.cherrypicks.CherryPickLiquidTransferStatus; import edu.harvard.med.screensaver.model.cherrypicks.CherryPickRequest; import edu.harvard.med.screensaver.model.cherrypicks.RNAiCherryPickRequest; import edu.harvard.med.screensaver.model.cherrypicks.SmallMoleculeCherryPickRequest; import edu.harvard.med.screensaver.model.libraries.Library; import edu.harvard.med.screensaver.model.libraries.LibraryPlate; import edu.harvard.med.screensaver.model.libraries.Plate; import edu.harvard.med.screensaver.model.libraries.Reagent; import edu.harvard.med.screensaver.model.libraries.Well; import edu.harvard.med.screensaver.model.meta.Cardinality; import edu.harvard.med.screensaver.model.meta.PropertyPath; import edu.harvard.med.screensaver.model.meta.RelationshipPath; import edu.harvard.med.screensaver.model.screenresults.AnnotationType; import edu.harvard.med.screensaver.model.screenresults.AssayPlate; import edu.harvard.med.screensaver.model.screenresults.ScreenResult; import edu.harvard.med.screensaver.model.users.AdministratorUser; 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.util.NullSafeUtils; /** * A screen tracks the progress of performing a screening assay, including a description of its biological significance, * its experimental protocol, and additional data to support the administrative needs of the facility. After screening * data is generated, a screen will contain a {@link ScreenResult}. * * @author <a mailto="john_sullivan@hms.harvard.edu">John Sullivan</a> * @author <a mailto="andrew_tolopko@hms.harvard.edu">Andrew Tolopko</a> */ @Entity @org.hibernate.annotations.Proxy public class Screen extends Study implements AttachedFilesEntity<ScreenAttachedFileType,Integer> { // private static data private static final Logger log = Logger.getLogger(Screen.class); private static final long serialVersionUID = 0L; public static final RelationshipPath<Screen> thisEntity = RelationshipPath.from(Screen.class); public static final PropertyPath<Screen> facilityId = thisEntity.toProperty("facilityId"); public static final RelationshipPath<Screen> screenResult = thisEntity.to("screenResult", Cardinality.TO_ONE); public static final RelationshipPath<Screen> labHead = thisEntity.to("labHead", Cardinality.TO_ONE); public static final RelationshipPath<Screen> leadScreener = thisEntity.to("leadScreener", Cardinality.TO_ONE); public static final RelationshipPath<Screen> collaborators = thisEntity.to("collaborators"); public static final RelationshipPath<Screen> annotationTypes = thisEntity.to("annotationTypes"); public static final RelationshipPath<Screen> cherryPickRequests = thisEntity.to("cherryPickRequests"); public static final RelationshipPath<Screen> labActivities = thisEntity.to("labActivities"); public static final RelationshipPath<Screen> serviceActivities = thisEntity.to("serviceActivities"); public static final RelationshipPath<Screen> statusItems = thisEntity.to("statusItems"); public static final RelationshipPath<Screen> fundingSupports = thisEntity.to("fundingSupports"); public static final PropertyPath<Screen> billingItems = thisEntity.toCollectionOfValues("billingItems"); public static final RelationshipPath<Screen> attachedFiles = thisEntity.to("attachedFiles"); public static final RelationshipPath<Screen> publications = thisEntity.to("publications"); public static final PropertyPath<Screen> keywords = thisEntity.toCollectionOfValues("keywords"); public static final PropertyPath<Screen> cellLines= thisEntity.toCollectionOfValues("cellLines"); public static final RelationshipPath<Screen> pinTransferApprovalActivity = thisEntity.to("pinTransferApprovalActivity", Cardinality.TO_ONE); public static final RelationshipPath<Screen> reagents = thisEntity.to("reagents"); public static final RelationshipPath<Screen> assayPlates = thisEntity.to("assayPlates"); public static final RelationshipPath<Screen> experimentalCellInfomationSet = thisEntity.to("experimentalCellInformationSet"); public static final Function<Screen,String> ToFacilityId = new Function<Screen,String>() { public String apply(Screen screen) { return screen.getFacilityId(); } }; public static final Function<Screen,String> ToNameFunction = new Function<Screen,String>() { public String apply(Screen s) { return s.getFacilityId(); } }; public static final Function<Screen,ScreenDataSharingLevel> ToDataSharingLevel = new Function<Screen,ScreenDataSharingLevel>() { public ScreenDataSharingLevel apply(Screen s) { return s.getDataSharingLevel(); } }; // private instance data // study (provides annotation of library contents) private Integer _version; private String _title; private ScreeningRoomUser _leadScreener; // should rename private LabHead _labHead; private SortedSet<ScreeningRoomUser> _collaborators = new TreeSet<ScreeningRoomUser>(); private Set<Publication> _publications = new HashSet<Publication>(); private String _url; private String _summary; private String _comments; private SortedSet<AnnotationType> _annotationTypes = new TreeSet<AnnotationType>(); private Set<Reagent> _reagents = new HashSet<Reagent>(); private StudyType _studyType; private boolean _isDownloadable = true; private Well wellStudied; // generic screen private String _facilityId; private ScreenType _screenType; private Set<AttachedFile> _attachedFiles = new HashSet<AttachedFile>(); private SortedSet<String> _keywords = new TreeSet<String>(); private String _publishableProtocol; private ScreenResult _screenResult; private SortedSet<AssayPlate> _assayPlates = Sets.newTreeSet(); private ProjectPhase _projectPhase; private String _projectId; // iccb screen private SortedSet<StatusItem> _statusItems = new TreeSet<StatusItem>(); private SortedSet<LabActivity> _labActivities = new TreeSet<LabActivity>(); private SortedSet<ServiceActivity> _serviceActivities = new TreeSet<ServiceActivity>(); private LocalDate _dataMeetingScheduled; private LocalDate _dataMeetingComplete; private BillingInformation _billingInformation = new BillingInformation(this, false); private List<BillingItem> _billingItems = new ArrayList<BillingItem>(); private Set<FundingSupport> _fundingSupports = new HashSet<FundingSupport>(); private LocalDate _dateOfApplication; private Set<AbaseTestset> _abaseTestsets = new HashSet<AbaseTestset>(); private String _abaseStudyId; private String _abaseProtocolId; private String _comsRegistrationNumber; private LocalDate _comsApprovalDate; private String _publishableProtocolComments; private LocalDate _publishableProtocolDateEntered; private String _publishableProtocolEnteredBy; private AdministrativeActivity _pinTransferApprovalActivity; private Set<CherryPickRequest> _cherryPickRequests = Sets.newHashSet(); private ScreenDataSharingLevel _dataSharingLevel; private LocalDate _minAllowedDataPrivacyExpirationDate; private LocalDate _maxAllowedDataPrivacyExpirationDate; private LocalDate _dataPrivacyExpirationDate; private LocalDate _dataPrivacyExpirationNotifiedDate; private LocalDate _pubchemDepositedDate; private Integer _pubchemAssayId; private int _assayPlatesScreenedCount; private int _librariesScreenedCount; private int _libraryPlatesScreenedCount; private int _libraryPlatesDataLoadedCount; private int _libraryPlatesDataAnalyzedCount; private int _screenedExperimentalWellCount; private int _uniqueScreenedExperimentalWellCount; private int _totalPlatedLabCherryPicks; private Integer _minScreenedReplicateCount; private Integer _maxScreenedReplicateCount; private Integer _minDataLoadedReplicateCount; private Integer _maxDataLoadedReplicateCount; private Species _species; private AssayType _assayType; // private CellLine _cellLine; private SortedSet<CellLine> _cellLines= new TreeSet<CellLine>(); private TransfectionAgent _transfectionAgent; private MolarConcentration perturbagenMolarConcentration; private BigDecimal perturbagenUgMlConcentration; // lincs screen private SortedSet<ExperimentalCellInformation> _experimentalCellInformationSet = Sets.newTreeSet(); /** * Construct an uninitialized <code>Screen</code>. * * @motivation for new Screen creation via user interface, where even required * fields are allowed to be uninitialized, initially * @motivation for hibernate and proxy/concrete subclass constructors */ protected Screen() {} public Screen(AdministratorUser createdBy) { super(createdBy); _dataSharingLevel = ScreenDataSharingLevel.PRIVATE; } /** * Construct an initialized <code>Screen</code>. * @param facilityId the screen facility ID * @param leadScreener the lead screener * @param labHead the lab head * @param screenType the screen type * @param studyType the study type * @param projectPhase TODO * @param title the title */ public Screen(AdministratorUser createdBy, String facilityId, ScreeningRoomUser leadScreener, LabHead labHead, ScreenType screenType, StudyType studyType, ProjectPhase projectPhase, String title) { this(createdBy); _facilityId = facilityId; _screenType = screenType; // note: must be set before updateFacilityUsageRoleForAssociatedScreens() is called _studyType = studyType; _projectPhase = projectPhase; setLeadScreener(leadScreener); setLabHead(labHead); _title = title; } // public instance methods public Object acceptVisitor(AbstractEntityVisitor visitor) { // TODO: HACK, until we have the real Study->Screen->IccbScreen hierarchy if (isStudyOnly()) { return visitor.visit((Study) this); } return visitor.visit(this); } /** * Get the id for the screen. * @return the id for the screen */ @Id @org.hibernate.annotations.GenericGenerator( name="screen_id_seq", strategy="sequence", parameters = { @org.hibernate.annotations.Parameter(name="sequence", value="screen_id_seq") } ) @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="screen_id_seq") public Integer getScreenId() { return getEntityId(); } @ManyToMany(fetch = FetchType.LAZY, cascade={ CascadeType.PERSIST, CascadeType.MERGE }) @JoinTable(name="screenUpdateActivity", joinColumns=@JoinColumn(name="screenId", nullable=false, updatable=false), inverseJoinColumns=@JoinColumn(name="updateActivityId", nullable=false, updatable=false, unique=true)) @org.hibernate.annotations.Cascade(value={org.hibernate.annotations.CascadeType.SAVE_UPDATE}) @Sort(type=SortType.NATURAL) @ToMany(singularPropertyName="updateActivity", hasNonconventionalMutation=true /* model testing framework doesn't understand this is a containment relationship, and so requires addUpdateActivity() method*/) @Override public SortedSet<AdministrativeActivity> getUpdateActivities() { return _updateActivities; } /** * Get the lead screener. * @return the lead screener */ @ManyToOne(fetch=FetchType.LAZY, cascade={ CascadeType.PERSIST, CascadeType.MERGE }) @JoinColumn(name="leadScreenerId"/*, nullable=false*/) @org.hibernate.annotations.ForeignKey(name="fk_screen_to_lead_screener") @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.PROXY) @org.hibernate.annotations.Cascade(value={ org.hibernate.annotations.CascadeType.SAVE_UPDATE }) @edu.harvard.med.screensaver.model.annotations.ToOne(inverseProperty="screensLed") public ScreeningRoomUser getLeadScreener() { return _leadScreener; } /** * Set the lead screener. * @param leadScreener the new lead screener */ public void setLeadScreener(ScreeningRoomUser leadScreener) { if (isHibernateCaller()) { _leadScreener = leadScreener; return; } if (leadScreener == null) { throw new NullPointerException(); } if (_leadScreener != null) { _leadScreener.getScreensLed().remove(this); _leadScreener.updateFacilityUsageRoleForAssociatedScreens(); } _leadScreener = leadScreener; _leadScreener.getScreensLed().add(this); _leadScreener.updateFacilityUsageRoleForAssociatedScreens(); } /** * Get the lab head. * @return the lab head */ @ManyToOne(fetch=FetchType.EAGER, cascade={ CascadeType.PERSIST, CascadeType.MERGE }) @JoinColumn(name="labHeadId") @org.hibernate.annotations.ForeignKey(name="fk_screen_to_lab_head") @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.PROXY) @org.hibernate.annotations.Cascade(value={ org.hibernate.annotations.CascadeType.SAVE_UPDATE }) @edu.harvard.med.screensaver.model.annotations.ToOne(inverseProperty="screensHeaded") public LabHead getLabHead() { return _labHead; } /** * Set the lab head. * @param labHead the new lab head */ public void setLabHead(LabHead labHead) { if (isHibernateCaller()) { _labHead = labHead; return; } if (NullSafeUtils.nullSafeEquals(labHead, _labHead)) { return; } if (_labHead != null) { _labHead.getScreensHeaded().remove(this); _labHead.updateFacilityUsageRoleForAssociatedScreens(); } _labHead = labHead; if (_labHead != null) { _labHead.getScreensHeaded().add(this); _labHead.updateFacilityUsageRoleForAssociatedScreens(); } } /** * Get the set of collaborators. * @return the set of collaborators */ @ManyToMany(fetch=FetchType.LAZY) @JoinTable( name="collaboratorLink", joinColumns=@JoinColumn(name="screenId"), inverseJoinColumns=@JoinColumn(name="collaboratorId") ) @org.hibernate.annotations.ForeignKey(name="fk_collaborator_link_to_screen") @org.hibernate.annotations.LazyCollection(value=org.hibernate.annotations.LazyCollectionOption.TRUE) @edu.harvard.med.screensaver.model.annotations.ToMany(inverseProperty="screensCollaborated") @Sort(type=SortType.NATURAL) public SortedSet<ScreeningRoomUser> getCollaborators() { return _collaborators; } /** * Add the collaborator. * @param collaborator the collaborator to add * @return true iff the screen did not already have the collaborator */ public boolean addCollaborator(ScreeningRoomUser collaborator) { if (_collaborators.add(collaborator)) { collaborator.getScreensCollaborated().add(this); collaborator.updateFacilityUsageRoleForAssociatedScreens(); return true; } return false; } /** * Remove the collaborator. * @param collaborator the collaborator to remove * @return true iff the screen previously had the collaborator */ public boolean removeCollaborator(ScreeningRoomUser collaborator) { if (_collaborators.remove(collaborator)) { collaborator.getScreensCollaborated().remove(this); collaborator.updateFacilityUsageRoleForAssociatedScreens(); return true; } return false; } @Transient public Set<ScreeningRoomUser> getAssociatedScreeningRoomUsers() { Set<ScreeningRoomUser> users = new HashSet<ScreeningRoomUser>(); if (getLabHead() != null) { users.add(getLabHead()); } users.add(getLeadScreener()); users.addAll(getCollaborators()); return users; } /** * Get the screen result. * @return the screen result */ @OneToOne( mappedBy="screen", cascade={ CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, fetch=FetchType.LAZY ) @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.PROXY) @org.hibernate.annotations.Cascade(value={ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE }) public ScreenResult getScreenResult() { return _screenResult; } AssayPlate createAssayPlate(Plate plateScreened, int replicateOrdinal, LibraryScreening libraryScreening) { AssayPlate assayPlate = new AssayPlate(this, plateScreened, replicateOrdinal); assayPlate.setLibraryScreening(libraryScreening); if (!_assayPlates.add(assayPlate)) { throw new DuplicateEntityException(this, assayPlate); } return assayPlate; } /** * @motivation this alternate factory method is necessary for cases where * Screensaver has not been used to track library copies or * library screenings, so that the necessary Plate and/or * AssayPlate entities do not exist. */ public AssayPlate createAssayPlate(int plateNumber, int replicateOrdinal) { AssayPlate assayPlate = new AssayPlate(this, plateNumber, replicateOrdinal); if (!_assayPlates.add(assayPlate)) { throw new DuplicateEntityException(this, assayPlate); } return assayPlate; } public SortedSet<AssayPlate> findAssayPlates(final int plateNumber) { return ImmutableSortedSet.copyOf(Iterables.filter(getAssayPlates(), new Predicate<AssayPlate>() { public boolean apply(AssayPlate ap) { return ap.getPlateNumber() == plateNumber; } })); } /** * The collection of {@link AssayPlate}s that have been created for this * screen, which may contain multiple instances for a given library * {@link Plate} and replicate (if it required re-screening). * * @return Collection of {@link AssayPlate}s */ @OneToMany(mappedBy = "screen", cascade = { CascadeType.ALL }, orphanRemoval = true) @Sort(type=SortType.NATURAL) public SortedSet<AssayPlate> getAssayPlates() { return _assayPlates; } private void setAssayPlates(SortedSet<AssayPlate> assayPlates) { _assayPlates = assayPlates; } public int getLibrariesScreenedCount() { return _librariesScreenedCount; } public void setLibrariesScreenedCount(int librariesScreenedCount) { _librariesScreenedCount = librariesScreenedCount; } /** * @return a SortedSet of LibraryPlates. The library property will be null if the AssayPlate was not screened, but has * had data loaded. */ @Transient public SortedSet<LibraryPlate> getLibraryPlatesScreened() { Multimap<Integer,AssayPlate> index = Multimaps.index(Iterables.filter(getAssayPlates(), AssayPlate.IsScreened), new Function<AssayPlate,Integer>() { @Override public Integer apply(AssayPlate p) { return p.getPlateNumber(); } }); SortedSet<LibraryPlate> libraryPlates = Sets.newTreeSet(); for (Integer plateNumber : index.keySet()) { AssayPlate firstAssayPlate = Iterables.get(index.get(plateNumber), 0); Library library = null; if (firstAssayPlate.getPlateScreened() != null) { library = firstAssayPlate.getPlateScreened().getCopy().getLibrary(); } libraryPlates.add(new LibraryPlate(plateNumber, library, Sets.newHashSet(index.get(plateNumber)))); } return libraryPlates; } @Transient public SortedSet<AssayPlate> getAssayPlatesDataLoaded() { return Sets.newTreeSet(Iterables.filter(getAssayPlates(), AssayPlate.IsDataLoaded)); } @Transient public SortedSet<AssayPlate> getAssayPlatesScreened() { return Sets.newTreeSet(Iterables.filter(getAssayPlates(), AssayPlate.HasLibraryScreening)); } @Derived public int getAssayPlatesScreenedCount() { return _assayPlatesScreenedCount; } public void setAssayPlatesScreenedCount(int assayPlatesScreenedCount) { _assayPlatesScreenedCount = assayPlatesScreenedCount; } @Derived public int getLibraryPlatesScreenedCount() { return _libraryPlatesScreenedCount; } public void setLibraryPlatesScreenedCount(int libraryPlatesScreenedCount) { _libraryPlatesScreenedCount = libraryPlatesScreenedCount; } @Derived public int getLibraryPlatesDataLoadedCount() { return _libraryPlatesDataLoadedCount; } public void setLibraryPlatesDataLoadedCount(int libraryPlatesDataLoadedCount) { _libraryPlatesDataLoadedCount = libraryPlatesDataLoadedCount; } @Derived public int getLibraryPlatesDataAnalyzedCount() { return _libraryPlatesDataAnalyzedCount; } public void setLibraryPlatesDataAnalyzedCount(int libraryPlatesDataAnalyzedCount) { _libraryPlatesDataAnalyzedCount = libraryPlatesDataAnalyzedCount; } @Derived public Integer getMinScreenedReplicateCount() { return _minScreenedReplicateCount; } public void setMinScreenedReplicateCount(Integer minScreenedReplicateCount) { _minScreenedReplicateCount = minScreenedReplicateCount; } @Derived public Integer getMaxScreenedReplicateCount() { return _maxScreenedReplicateCount; } public void setMaxScreenedReplicateCount(Integer maxScreenedReplicateCount) { _maxScreenedReplicateCount = maxScreenedReplicateCount; } @Derived public Integer getMinDataLoadedReplicateCount() { return _minDataLoadedReplicateCount; } public void setMinDataLoadedReplicateCount(Integer minDataLoadedReplicateCount) { _minDataLoadedReplicateCount = minDataLoadedReplicateCount; } @Derived public Integer getMaxDataLoadedReplicateCount() { return _maxDataLoadedReplicateCount; } public void setMaxDataLoadedReplicateCount(Integer maxDataLoadedReplicateCount) { _maxDataLoadedReplicateCount = maxDataLoadedReplicateCount; } @Derived public int getScreenedExperimentalWellCount() { return _screenedExperimentalWellCount; } public void setScreenedExperimentalWellCount(int screenedExperimentalWellCount) { _screenedExperimentalWellCount = screenedExperimentalWellCount; } @Derived public int getUniqueScreenedExperimentalWellCount() { return _uniqueScreenedExperimentalWellCount; } public void setUniqueScreenedExperimentalWellCount(int uniqueScreenedExperimentalWellCount) { _uniqueScreenedExperimentalWellCount = uniqueScreenedExperimentalWellCount; } @Derived public int getTotalPlatedLabCherryPicks() { return _totalPlatedLabCherryPicks; } public void setTotalPlatedLabCherryPicks(int totalPlatedLabCherryPicks) { _totalPlatedLabCherryPicks = totalPlatedLabCherryPicks; } /** * Create and return a new screen result for the screen. * * @return the new screen result */ public ScreenResult createScreenResult() { _screenResult = new ScreenResult(this, null); return _screenResult; } /** * Clear the screen result (in memory only). Use {@link ScreenResultsDAO#deleteScreenResult(ScreenResult)} to delete * from persistent storage. */ public void clearScreenResult() { _screenResult = null; for (AssayPlate assayPlate : getAssayPlates()) { assayPlate.setScreenResultDataLoading(null); } } /** * Get the status items. A Screen may only contain one status with a given * {@link ScreenStatus#getRank() rank} value (StatusItems with the same rank are mutually * exclusive). Ordering of StatusItems must be equivalent whether by * {@link ScreenStatus#getRank() rank} or {@link StatusItem#getStatusDate() date}. * * @return the status items */ @ElementCollection(fetch=FetchType.EAGER) @JoinTable(name = "screen_status_item", joinColumns = @JoinColumn(name = "screen_id")) @Sort(type=SortType.NATURAL) public SortedSet<StatusItem> getStatusItems() { return _statusItems; } @Transient public StatusItem getCurrentStatusItem() { if (_statusItems.isEmpty()) { return null; } return _statusItems.last(); } /** * Create and return a new <code>StatusItem</code> for this screen. * @param statusDate the status date * @param screenStatus the status value * @return the new status item */ public StatusItem createStatusItem(LocalDate statusDate, ScreenStatus screenStatus) { for (StatusItem statusItem : _statusItems) { if (statusItem.getStatus().getRank() == screenStatus.getRank()) { throw new BusinessRuleViolationException("screen status " + screenStatus + " is mutually exclusive with existing screen status " + statusItem.getStatus()); } if (screenStatus.getRank() < statusItem.getStatus().getRank()) { if (statusDate.compareTo(statusItem.getStatusDate()) > 0) { throw new BusinessRuleViolationException("date of new screen status must not be after date of subsequent screen status"); } } else { if (statusDate.compareTo(statusItem.getStatusDate()) < 0) { throw new BusinessRuleViolationException("date of new screen status must not be before the date of the previous screen status"); } } } StatusItem newStatusItem = new StatusItem(statusDate, screenStatus); _statusItems.add(newStatusItem); return newStatusItem; } /** * Get the lab activities. * @return the lab activities */ @OneToMany(mappedBy = "screen", cascade = { CascadeType.ALL }) @Sort(type=SortType.NATURAL) @edu.harvard.med.screensaver.model.annotations.ToMany(singularPropertyName="labActivity", hasNonconventionalMutation=true /* uses createLibraryScreening() and createRNAiCherryPickScreening */) public SortedSet<LabActivity> getLabActivities() { return _labActivities; } /** * Get the service activities. * @return the service activities */ @OneToMany(mappedBy = "servicedScreen", cascade = { CascadeType.ALL }) @Sort(type=SortType.NATURAL) @edu.harvard.med.screensaver.model.annotations.ToMany(singularPropertyName="serviceActivity", hasNonconventionalMutation=true ) public SortedSet<ServiceActivity> getServiceActivities() { return _serviceActivities; } /** * Get all the lab activities for this screen of a particular type. * @param <E> the type of the lab activities to get * @param clazz the type of the lab activities to get * @return all the lab activities for this screen of a particular type. */ @SuppressWarnings("unchecked") @Transient public <E extends LabActivity> SortedSet<E> getLabActivitiesOfType(Class<E> clazz) { SortedSet<E> result = new TreeSet<E>(); for (LabActivity labActivity : _labActivities) { if (clazz.isAssignableFrom(labActivity.getClass())) { result.add((E) labActivity); } } return result; } /** * Create and return a new library screening for the screen. * @param performedBy the user that performed the screening * @param dateOfActivity the date the lab activity took place * @return the new library screening */ public LibraryScreening createLibraryScreening(AdministratorUser recordedBy, ScreeningRoomUser performedBy, LocalDate dateOfActivity) { LibraryScreening libraryScreening = new LibraryScreening(this, recordedBy, performedBy, dateOfActivity); _labActivities.add(libraryScreening); return libraryScreening; } /** * Create and return a new cherry pick liquid transfer for the screen. * @param performedBy the user that performed the activity * @param dateOfActivity the date the lab activity took place * @param status the status of the cherry pick liquid transfer * @return the new cherry pick liquid transfer */ public CherryPickLiquidTransfer createCherryPickLiquidTransfer(AdministratorUser recordedBy, ScreensaverUser performedBy, LocalDate dateOfActivity, CherryPickLiquidTransferStatus status) { CherryPickLiquidTransfer cherryPickLiquidTransfer = new CherryPickLiquidTransfer(this, recordedBy, performedBy, dateOfActivity, status); _labActivities.add(cherryPickLiquidTransfer); return cherryPickLiquidTransfer; } /** * Create and return a new cherry pick screening for the screen. * @param performedBy the user that performed the screening * @param dateOfActivity the date the screening took place * @param cherryPickRequest the cherry pick request * @return the newly created cherry pick screening */ public CherryPickScreening createCherryPickScreening(AdministratorUser recordedBy, ScreeningRoomUser performedBy, LocalDate dateOfActivity, CherryPickRequest cherryPickRequest) { CherryPickScreening screening = new CherryPickScreening( this, recordedBy, performedBy, dateOfActivity, cherryPickRequest); _labActivities.add(screening); return screening; } /** * Get the cherry pick requests. * @return the cherry pick requests */ @OneToMany(mappedBy = "screen", cascade = { CascadeType.ALL }) public Set<CherryPickRequest> getCherryPickRequests() { return _cherryPickRequests; } /** * Create and return a new cherry pick request for the screen of the appropriate type ({@link * SmallMoleculeCherryPickRequest} or {@link RNAiCherryPickRequest}. The cherry pick request will * have the {@link #getLeadScreener() lead screener} as the {@link * CherryPickRequest#getRequestedBy() requestor}, and the current date as the {@link * CherryPickRequest#getDateRequested() date requested}. It will not be a legacy ScreenDB * cherry pick. * @return the new cherry pick request */ public CherryPickRequest createCherryPickRequest(AdministratorUser createdBy) { return createCherryPickRequest(createdBy, getLeadScreener(), new LocalDate()); } /** * Create and return a new cherry pick request for the screen of the appropriate type ({@link * SmallMoleculeCherryPickRequest} or {@link RNAiCherryPickRequest}. The cherry pick request will * not be a legacy ScreenDB cherry pick. * @param requestedBy the requestor * @param dateRequested the date requested * @return the new cherry pick request */ public CherryPickRequest createCherryPickRequest(AdministratorUser createdBy, ScreeningRoomUser requestedBy, LocalDate dateRequested) { CherryPickRequest cherryPickRequest; if (getScreenType().equals(ScreenType.RNAI)) { cherryPickRequest = new RNAiCherryPickRequest(createdBy, this, requestedBy, dateRequested); } else if(getScreenType().equals(ScreenType.SMALL_MOLECULE)) { cherryPickRequest = new SmallMoleculeCherryPickRequest(createdBy, this, requestedBy, dateRequested); } else { throw new UnsupportedOperationException( "screen of type " + getScreenType() + " does not support cherry pick requests"); } _cherryPickRequests.add(cherryPickRequest); return cherryPickRequest; } /** * Get the set of abase testsets. * @return the abase testsets */ @OneToMany(mappedBy = "screen", cascade = { CascadeType.ALL }, orphanRemoval = true) public Set<AbaseTestset> getAbaseTestsets() { return _abaseTestsets; } /** * Create and return an <code>AbaseTestset</code> for the screen. * @param testsetDate the testset date * @param testsetName the testset name * @param comments the comments * @return the new abase testset */ public AbaseTestset createAbaseTestset(LocalDate testsetDate, String testsetName, String comments) { AbaseTestset abaseTestset = new AbaseTestset(this, testsetDate, testsetName, comments); _abaseTestsets.add(abaseTestset); return abaseTestset; } /** * Get the publications. * @return the publications */ @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.LAZY) @JoinTable(name = "screenPublicationLink", joinColumns = @JoinColumn(name = "screenId"), inverseJoinColumns = @JoinColumn(name = "publicationId")) @org.hibernate.annotations.ForeignKey(name = "fk_screen_publication_link_to_screen") public Set<Publication> getPublications() { return _publications; } // note: for automated model unit tests, we can't name this createPublication or addPublication public Publication addCopyOfPublication(Publication publicationDTO) { Publication publication = new Publication(); publication.setPubmedId(publicationDTO.getPubmedId()); publication.setPubmedCentralId(publicationDTO.getPubmedCentralId()); publication.setTitle(publicationDTO.getTitle()); publication.setYearPublished(publicationDTO.getYearPublished()); publication.setAuthors(publicationDTO.getAuthors()); publication.setJournal(publicationDTO.getJournal()); publication.setVolume(publicationDTO.getVolume()); publication.setPages(publicationDTO.getPages()); addPublication(publication); return publication; } /** * Get the attached files. * @return the attached files */ @OneToMany(mappedBy = "screen", cascade = { CascadeType.ALL }, orphanRemoval=true) @ToMany(hasNonconventionalMutation=true) public Set<AttachedFile> getAttachedFiles() { return _attachedFiles; } /** * Create and return a new attached file for the screen. * @param filename the filename * @param fileType the file type * @param fileContents the file contents * @throws IOException */ public AttachedFile createAttachedFile(String filename, ScreenAttachedFileType fileType, LocalDate fileDate, String fileContents) throws IOException { return createAttachedFile(filename, fileType, fileDate, new ByteArrayInputStream(fileContents.getBytes())); } /** * Create and return a new attached file for the screen. * * @param filename the filename * @param fileType the file type * @param fileContents the file contents * @throws IOException */ public AttachedFile createAttachedFile(String filename, ScreenAttachedFileType fileType, LocalDate fileDate, InputStream fileContents) throws IOException { AttachedFile attachedFile = new AttachedFile(this, filename, fileType, fileDate, fileContents); _attachedFiles.add(attachedFile); return attachedFile; } public void removeAttachedFile(AttachedFile attachedFile) { _attachedFiles.remove(attachedFile); } /** * Get the billing information. * @return the billing information */ @edu.harvard.med.screensaver.model.annotations.Column(hasNonconventionalSetterMethod=true) public BillingInformation getBillingInformation() { return _billingInformation; } /** * Get the set of billing items. * @return the billing items */ @ElementCollection @edu.harvard.med.screensaver.model.annotations.ElementCollection(hasNonconventionalMutation = true) @JoinTable(name = "screen_billing_item", joinColumns = @JoinColumn(name = "screen_id")) @org.hibernate.annotations.IndexColumn(name="ordinal") public List<BillingItem> getBillingItems() { return _billingItems; } /** * Set the set of billing items. * @param billingItems the new set of billing items * @motivation for hibernate */ private void setBillingItems(List<BillingItem> billingItems) { _billingItems = billingItems; } /** * Create and return a new billing item for this billing information. * @param itemToBeCharged the item to be charged * @param amount the amount * @param dateSentForBilling the date sent for billing * @return the new billing item for this billing information */ public BillingItem createBillingItem(String itemToBeCharged, BigDecimal amount, LocalDate dateSentForBilling) { if (itemToBeCharged == null) { throw new RequiredPropertyException(this, "billing item name"); } if (amount == null) { throw new RequiredPropertyException(this, "billing item amount"); } // allowed, as per [#1607] //if (dateSentForBilling == null) { // throw new RequiredPropertyException(this, "billing item date faxed"); //} BillingItem billingItem = new BillingItem(itemToBeCharged, amount, dateSentForBilling); _billingItems.add(billingItem); return billingItem; } public BillingItem addCopyOfBillingItem(BillingItem dtoBillingItem) { return createBillingItem(dtoBillingItem.getItemToBeCharged(), dtoBillingItem.getAmount(), dtoBillingItem.getDateSentForBilling()); } @Column(unique=true, nullable=false) @org.hibernate.annotations.Type(type="text") public String getFacilityId() { return _facilityId; } public void setFacilityId(String name) { _facilityId = name; } @Column @org.hibernate.annotations.Type(type="edu.harvard.med.screensaver.model.screens.Species$UserType") public Species getSpecies() { return _species; } public void setSpecies(Species value) { _species = value; } @Column @org.hibernate.annotations.Type(type="edu.harvard.med.screensaver.model.screens.AssayType$UserType") public AssayType getAssayType() { return _assayType; } public void setAssayType(AssayType value) { _assayType = value; } /** * Get the study type. * @return the study type */ @Column(nullable = false) @org.hibernate.annotations.Type(type="edu.harvard.med.screensaver.model.screens.StudyType$UserType") public StudyType getStudyType() { return _studyType; } /** * Set the study type. * * @param studyType the new studyType */ public void setStudyType(StudyType studyType) { // commenting this until comprehensive testing is performed, since it requires many relationships to be eager fetched, which may cause problems // if (isDataLoaded()) { // throw new BusinessRuleViolationException("screen type is immutable after screen contains data"); // } _studyType = studyType; } /** * Get the screen type. * @return the screen type */ @Column(nullable=false) @org.hibernate.annotations.Type(type="edu.harvard.med.screensaver.model.screens.ScreenType$UserType") public ScreenType getScreenType() { return _screenType; } /** * Set the screen type. * @param screenType the new screen type * @motivation for hibernate */ public void setScreenType(ScreenType screenType) { // commenting this until comprehensive testing is performed, since it requires many relationships to be eager fetched, which may cause problems // if (isDataLoaded()) { // throw new BusinessRuleViolationException("screen type is immutable after screen contains data"); // } _screenType = screenType; } public void setProjectPhase(ProjectPhase projectPhase) { _projectPhase = projectPhase; } @Column(nullable = false) @org.hibernate.annotations.Type(type = "edu.harvard.med.screensaver.model.screens.ProjectPhase$UserType") public ProjectPhase getProjectPhase() { return _projectPhase; } @Transient public boolean isDataLoaded() { return getScreenResult() != null || !getCherryPickRequests().isEmpty() || !getAnnotationTypes().isEmpty() || !getLabActivities().isEmpty(); } /** * Get the title. * @return the title */ @Column(nullable=false) @org.hibernate.annotations.Type(type="text") public String getTitle() { return _title; } /** * Set the title. * @param title the new title */ public void setTitle(String title) { _title = title; } public void setProjectId(String projectId) { _projectId = projectId; } @Column(nullable = true) @org.hibernate.annotations.Type(type = "text") public String getProjectId() { return _projectId; } /** * Get the study url. * @return the study url */ @Column(nullable=true) @org.hibernate.annotations.Type(type="text") public String getUrl() { return _url; } /** * Set the study url. * @param url the new study url */ public void setUrl(String url) { _url = url; } /** * Get the data meeting scheduled. * @return the data meeting scheduled */ @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getDataMeetingScheduled() { return _dataMeetingScheduled; } /** * Set the data meeting scheduled date. * @param dataMeetingScheduled the new data meeting scheduled date */ public void setDataMeetingScheduled(LocalDate dataMeetingScheduled) { _dataMeetingScheduled = dataMeetingScheduled; } /** * Get the data meeting completed date. * @return the data meeting completed date */ @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getDataMeetingComplete() { return _dataMeetingComplete; } /** * Set the data meeting complete. * @param dataMeetingComplete the new data meeting complete */ public void setDataMeetingComplete(LocalDate dataMeetingComplete) { _dataMeetingComplete = dataMeetingComplete; } /** * Get the keywords. * @return the keywords */ @ElementCollection @Column(name="keyword", nullable=false) @JoinTable( name="screenKeyword", joinColumns=@JoinColumn(name="screenId") ) @Sort(type=SortType.NATURAL) @org.hibernate.annotations.Type(type="text") @org.hibernate.annotations.ForeignKey(name="fk_screen_keyword_to_screen") public SortedSet<String> getKeywords() { return _keywords; } /** * Set the keywords. * @param keywords the new keywords */ public void setKeywords(SortedSet<String> keywords) { _keywords = keywords; } /** * Add the keyword. * @param keyword the keyword to add * @return true iff the screen did not already have the keyword */ public boolean addKeyword(String keyword) { return _keywords.add(keyword); } /** * Remove the keyword. * @param keyword the keyword to remove * @return true iff the screen previously had the keyword */ public boolean removeKeyword(String keyword) { return _keywords.remove(keyword); } /** * Get the set of funding supports. * @return the set of funding supports */ @ManyToMany(fetch=FetchType.EAGER) @JoinTable( name="screenFundingSupportLink", joinColumns=@JoinColumn(name="screenId"), inverseJoinColumns=@JoinColumn(name="fundingSupportId")) @org.hibernate.annotations.LazyCollection(value=org.hibernate.annotations.LazyCollectionOption.TRUE) @edu.harvard.med.screensaver.model.annotations.ToMany(unidirectional=true) public Set<FundingSupport> getFundingSupports() { return _fundingSupports; } /** * Add the funding support. * @param fundingSupport the funding support to add * @return true iff the screen did not already have the funding support */ public boolean addFundingSupport(FundingSupport fundingSupport) { return _fundingSupports.add(fundingSupport); } /** * Remove the funding support. * @param fundingSupport the funding support to remove * @return true iff the screen previously had the funding support */ public boolean removeFundingSupport(FundingSupport fundingSupport) { return _fundingSupports.remove(fundingSupport); } /** * Get the summary. * @return the summary */ @org.hibernate.annotations.Type(type="text") public String getSummary() { return _summary; } /** * Set the summary. * @param summary the new summary */ public void setSummary(String summary) { _summary = summary; } /** * Get the comments. * @return the comments */ @org.hibernate.annotations.Type(type="text") public String getComments() { return _comments; } /** * Set the comments. * @param comments the new comments */ public void setComments(String comments) { _comments = comments; } /** * Get the abase study id. * @return the abase study id */ @org.hibernate.annotations.Type(type="text") public String getAbaseStudyId() { return _abaseStudyId; } /** * Set the abase study id. * @param abaseStudyId the new abase study id */ public void setAbaseStudyId(String abaseStudyId) { _abaseStudyId = abaseStudyId; } /** * Get the abase protocol id. * @return the abase protocol id */ @org.hibernate.annotations.Type(type="text") public String getAbaseProtocolId() { return _abaseProtocolId; } /** * Set the abase protocol id. * @param abaseProtocolId the new abase protocol id */ public void setAbaseProtocolId(String abaseProtocolId) { _abaseProtocolId = abaseProtocolId; } @org.hibernate.annotations.Type(type="text") public String getComsRegistrationNumber() { return _comsRegistrationNumber; } public void setComsRegistrationNumber(String comsRegistrationNumber) { _comsRegistrationNumber = comsRegistrationNumber; } @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getComsApprovalDate() { return _comsApprovalDate; } public void setComsApprovalDate(LocalDate comsApprovalDate) { _comsApprovalDate = comsApprovalDate; } // TODO: extract PublishableProtocol value-typed collection /** * Get the date the publishable protocol was entered. * @return the date the publishable protocol was entered */ @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getPublishableProtocolDateEntered() { return _publishableProtocolDateEntered; } /** * Set the date the publishable protocol was entered. * @param publishableProtocolDateEntered the new date the publishable protocol was entered */ public void setPublishableProtocolDateEntered(LocalDate publishableProtocolDateEntered) { _publishableProtocolDateEntered = publishableProtocolDateEntered; } /** * Get the initials of the administrator who entered the publishable protocol. * @return the initials of the administrator who entered the publishable protocol */ @org.hibernate.annotations.Type(type="text") public String getPublishableProtocolEnteredBy() { return _publishableProtocolEnteredBy; } /** * Set the initials of the administrator who entered the publishable protocol. * @param publishableProtocolEnteredBy the new initials of the administrator who * entered the publishable protocol */ public void setPublishableProtocolEnteredBy(String publishableProtocolEnteredBy) { _publishableProtocolEnteredBy = publishableProtocolEnteredBy; } /** * Get the publishable protocol. * @return the publishable protocol */ @org.hibernate.annotations.Type(type="text") public String getPublishableProtocol() { return _publishableProtocol; } /** * Set the publishable protocol. * @param publishableProtocol the new publishable protocol */ public void setPublishableProtocol(String publishableProtocol) { _publishableProtocol = publishableProtocol; } /** * Get the publishable protocol comments. * @return the publishable protocol comments */ @org.hibernate.annotations.Type(type="text") public String getPublishableProtocolComments() { return _publishableProtocolComments; } /** * Set the publishable protocol comments. * @param publishableProtocolComments the new publishable protocol comments */ public void setPublishableProtocolComments(String publishableProtocolComments) { _publishableProtocolComments = publishableProtocolComments; } @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY) @JoinColumn(name = "pin_transfer_admin_activity_id") @org.hibernate.annotations.ForeignKey(name = "fk_screen_to_pin_transfer_admin_activity") @org.hibernate.annotations.LazyToOne(value = org.hibernate.annotations.LazyToOneOption.PROXY) @org.hibernate.annotations.Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE }) @edu.harvard.med.screensaver.model.annotations.ToOne(unidirectional=true, hasNonconventionalSetterMethod=true) public AdministrativeActivity getPinTransferApprovalActivity() { return _pinTransferApprovalActivity; } private void setPinTransferApprovalActivity(AdministrativeActivity pinTransferApprovalActivity) { _pinTransferApprovalActivity = pinTransferApprovalActivity; } public void setPinTransferApproved(AdministratorUser recordedBy, AdministratorUser approvedBy, LocalDate dateApproved, String comments) { if (_pinTransferApprovalActivity != null) { throw new BusinessRuleViolationException("pin transfer approval already recorded"); } _pinTransferApprovalActivity = new AdministrativeActivity(recordedBy, approvedBy, dateApproved, AdministrativeActivityType.PIN_TRANSFER_APPROVAL); _pinTransferApprovalActivity.setComments(comments); } /** * Get the date of application. * @return the date of application */ @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getDateOfApplication() { return _dateOfApplication; } /** * Set the date of application. * @param dateOfApplication the new date of application */ public void setDateOfApplication(LocalDate dateOfApplication) { _dateOfApplication = dateOfApplication; } /** * Get the annotation types provided by this study. * @return the annotation types */ @OneToMany(mappedBy = "study", cascade = { CascadeType.ALL }, orphanRemoval = true) @Sort(type = SortType.NATURAL) public SortedSet<AnnotationType> getAnnotationTypes() { return _annotationTypes; } /** * Create and return a new annotation type for the study. * @param name the name of the annotation type * @param description the description for the annotation type * @param isNumeric true iff this annotation type contains numeric result values * @return the new annotation type */ public AnnotationType createAnnotationType( String name, String description, boolean isNumeric) { verifyNameIsUnique(name); AnnotationType annotationType = new AnnotationType( this, name, description, _annotationTypes.size(), isNumeric); _annotationTypes.add(annotationType); return annotationType; } /** * Get the set of reagents associated with this screen result. <i>Do not modify * the returned collection.</i> To add a reagent, call {@link #addReagent}. * @motivation efficiently find all reagent-related data for a study (w/o reading annotationTypes.annotationValues.reagents) * @return the set of reagents associated with this screen result */ @ManyToMany(fetch=FetchType.LAZY) @JoinTable(name = "studyReagentLink", joinColumns = @JoinColumn(name = "studyId"), inverseJoinColumns = @JoinColumn(name = "reagentId")) @org.hibernate.annotations.ForeignKey(name="fk_reagent_link_to_study") @org.hibernate.annotations.LazyCollection(value=org.hibernate.annotations.LazyCollectionOption.TRUE) @edu.harvard.med.screensaver.model.annotations.ToMany(inverseProperty="studies") public Set<Reagent> getReagents() { return _reagents; } /** * Add the reagent. * @param reagent the reagent to add * @return true iff the screen did not already have the reagent */ public boolean addReagent(Reagent reagent) { return addReagent(reagent, true); } public boolean addReagent(Reagent reagent, boolean createStudiesLink) { if (_reagents.add(reagent)) { if (createStudiesLink) { reagent.addStudy(this); } return true; } return false; } /** * Remove the reagent. * @param reagent the reagent to remove * @return true iff the screen previously had the reagent */ public boolean removeReagent(Reagent reagent) { if (_reagents.remove(reagent)) { reagent.removeStudy(this); return true; } return false; } public boolean addPublication(Publication p) { return _publications.add(p); } @Transient public List<ScreenStatus> getCandidateStatuses() { List<ScreenStatus> candidateStatuses = new ArrayList<ScreenStatus>(Arrays.asList(ScreenStatus.values())); Set<Integer> illegalStatusRanks = new HashSet<Integer>(); for (StatusItem statusItem : getStatusItems()) { illegalStatusRanks.add(statusItem.getStatus().getRank()); } Iterator<ScreenStatus> iter = candidateStatuses.iterator(); while (iter.hasNext()) { if (illegalStatusRanks.contains(iter.next().getRank())) { iter.remove(); } } return candidateStatuses; } // private instance methods /** * Set the id for the screen. * @param screenId the new id for the screen * @motivation for hibernate */ private void setScreenId(Integer screenId) { setEntityId(screenId); } /** * Get the version for the screen. * @return the version for the screen * @motivation for hibernate */ @Version @Column(nullable=false) private Integer getVersion() { return _version; } /** * Set the version for the screen. * @param version the new version for the screen * @motivation for hibernate */ private void setVersion(Integer version) { _version = version; } /** * Set the set of collaborators. * @param collaborators the new set of collaborators * @motivation for hibernate */ private void setCollaborators(SortedSet<ScreeningRoomUser> collaborators) { _collaborators = collaborators; } /** * Set the screen result. * @param screenResult the new screen result * @motivation for hibernate */ private void setScreenResult(ScreenResult screenResult) { _screenResult = screenResult; } /** * Set the status items. * @param statusItems the new status items * @motivation for hibernate */ private void setStatusItems(SortedSet<StatusItem> statusItems) { _statusItems = statusItems; } /** * @motivation for hibernate */ private void setLabActivities(SortedSet<LabActivity> labActivities) { _labActivities = labActivities; } /** * @motivation for hibernate */ private void setServiceActivities(SortedSet<ServiceActivity> values) { _serviceActivities = values; } /** * Set the cherry pick requests. * @param cherryPickRequests the new cherry pick requests * @motivation for hibernate */ private void setCherryPickRequests(Set<CherryPickRequest> cherryPickRequests) { _cherryPickRequests = cherryPickRequests; } /** * Set the abase testsets. * @param abaseTestsets the new abase testsets * @motivation for hibernate */ private void setAbaseTestsets(Set<AbaseTestset> abaseTestsets) { _abaseTestsets = abaseTestsets; } /** * Set the publications. * @param publications the new publications * @motivation for hibernate */ private void setPublications(Set<Publication> publications) { _publications = publications; } /** * Set the attached files. * @param attachedFiles the new attached files * @motivation for hibernate */ private void setAttachedFiles(Set<AttachedFile> attachedFiles) { _attachedFiles = attachedFiles; } /** * Set the billing information. * @param billingInformation the new billing information * @motivation for hibernate */ private void setBillingInformation(BillingInformation billingInformation) { _billingInformation = billingInformation; } /** * Set the funding supports. * @param fundingSupports the new funding supports * @motivation for hibernate */ private void setFundingSupports(Set<FundingSupport> fundingSupports) { _fundingSupports = fundingSupports; } /** * Set the annotation types. * @param annotationTypes the new annotation types * @motivation for hibernate */ private void setAnnotationTypes(SortedSet<AnnotationType> annotationTypes) { _annotationTypes = annotationTypes; } /** * Set the reagents. * @param reagents the new reagents * @motivation for hibernate */ private void setReagents(Set<Reagent> reagents) { _reagents = reagents; } private void verifyNameIsUnique(String name) { for (AnnotationType at : getAnnotationTypes()) { if (at.getName().equals(name)) { throw new DuplicateEntityException(this, at); } } } /** * Get the set of libraries that this screen has been authorized to screen, * even if the library's screening status would otherwise not permit it. */ @Transient public Set<Library> getLibrariesPermitted() { return Collections.emptySet(); } // public void setCellLine(CellLine _cellLine) // { // this._cellLine = _cellLine; // } // @ManyToOne // @JoinColumn(name="cellLineId", nullable=true) // @org.hibernate.annotations.ForeignKey(name="fk_screen_to_cell_line") // @org.hibernate.annotations.Cascade(value={ org.hibernate.annotations.CascadeType.SAVE_UPDATE }) // @edu.harvard.med.screensaver.model.annotations.ToOne(unidirectional=true) // public CellLine getCellLine() // { // return _cellLine; // } /** * Get the set of cell lines. * @return the set of cell lines */ @ManyToMany(fetch=FetchType.LAZY) @edu.harvard.med.screensaver.model.annotations.Column(hasNonconventionalSetterMethod = true) @JoinTable( name="screenCellLine", joinColumns=@JoinColumn(name="screenId"), inverseJoinColumns=@JoinColumn(name="cellLineId") ) @org.hibernate.annotations.ForeignKey(name="fk_screen_cell_line_to_screen") @org.hibernate.annotations.LazyCollection(value=org.hibernate.annotations.LazyCollectionOption.TRUE) @Sort(type=SortType.NATURAL) public SortedSet<CellLine> getCellLines() { return _cellLines; } /** * Set the cellLines. * @param cellLines the new cellLines */ private void setCellLines(SortedSet<CellLine> cellLines) { _cellLines = cellLines; } /** * Add the cell line. * @param keyword the cell line to add * @return true iff the screen did not already have the cell line */ public boolean addCellLine(CellLine cellLine) { return _cellLines.add(cellLine); } /** * Remove the cell line. * @param cell line the cell line to remove * @return true iff the screen previously had the cellline */ public boolean removeCellLine(CellLine cellLine) { return _cellLines.remove(cellLine); } public void setTransfectionAgent(TransfectionAgent _transfectionAgent) { this._transfectionAgent = _transfectionAgent; } @ManyToOne @JoinColumn(name="transfectionAgentId", nullable=true) @org.hibernate.annotations.ForeignKey(name="fk_screen_to_transfection_agent") @org.hibernate.annotations.Cascade(value={ org.hibernate.annotations.CascadeType.SAVE_UPDATE }) @edu.harvard.med.screensaver.model.annotations.ToOne(unidirectional=true) public TransfectionAgent getTransfectionAgent() { return _transfectionAgent; } @Column(nullable=false) //@org.hibernate.annotations.Type(type="edu.harvard.med.screensaver.model.screens.ScreenDataSharingLevel$UserType") public ScreenDataSharingLevel getDataSharingLevel() { return _dataSharingLevel; } public void setDataSharingLevel(ScreenDataSharingLevel dataSharingLevel) { _dataSharingLevel = dataSharingLevel; } /** * The date on which a level 2 or 3 screen is to become level 1. */ @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getDataPrivacyExpirationDate() { return _dataPrivacyExpirationDate; } public void setDataPrivacyExpirationDate(LocalDate dataPrivacyExpirationDate) { if(dataPrivacyExpirationDate == null) { if(_maxAllowedDataPrivacyExpirationDate != null || _minAllowedDataPrivacyExpirationDate != null) { throw new DataModelViolationException("null value not allowed for condition if(maxAllowedDataPrivacyExpirationDate != null || minAllowedDataPrivacyExpirationDate != null)"); } } LocalDate min = _minAllowedDataPrivacyExpirationDate; LocalDate max = _maxAllowedDataPrivacyExpirationDate; if( max != null && dataPrivacyExpirationDate.compareTo(max) > 0 ) { dataPrivacyExpirationDate = max; } else if( min != null && dataPrivacyExpirationDate.compareTo(min) < 0 ) { dataPrivacyExpirationDate = min; } _dataPrivacyExpirationDate = dataPrivacyExpirationDate; } public void setMinAllowedDataPrivacyExpirationDate(LocalDate minAllowedDataPrivacyExpirationDate) { _minAllowedDataPrivacyExpirationDate = minAllowedDataPrivacyExpirationDate; if(minAllowedDataPrivacyExpirationDate == null) return; if( _dataPrivacyExpirationDate == null || _dataPrivacyExpirationDate.compareTo(minAllowedDataPrivacyExpirationDate) < 0 ) { _dataPrivacyExpirationDate = minAllowedDataPrivacyExpirationDate; } } @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getMinAllowedDataPrivacyExpirationDate() { return _minAllowedDataPrivacyExpirationDate; } public void setMaxAllowedDataPrivacyExpirationDate(LocalDate maxAllowedDataPrivacyExpirationDate) { _maxAllowedDataPrivacyExpirationDate = maxAllowedDataPrivacyExpirationDate; if(maxAllowedDataPrivacyExpirationDate == null) return; if( _dataPrivacyExpirationDate == null || _dataPrivacyExpirationDate.compareTo(maxAllowedDataPrivacyExpirationDate) > 0 ) { _dataPrivacyExpirationDate = maxAllowedDataPrivacyExpirationDate; } } @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getMaxAllowedDataPrivacyExpirationDate() { return _maxAllowedDataPrivacyExpirationDate; } /** * Call this to set the {@link Screen#getDataPrivacyExpirationDate()} after the * {@link Screen#getMinAllowedDataPrivacyExpirationDate()} and the {@link Screen#getMaxAllowedDataPrivacyExpirationDate()} * have been set.<br> */ private void updateDataPrivacyExpirationDate() { LocalDate requestedDate = getDataPrivacyExpirationDate(); LocalDate max = getMaxAllowedDataPrivacyExpirationDate(); LocalDate min = getMinAllowedDataPrivacyExpirationDate(); if( requestedDate.compareTo(max) > 0 & max != null ) { _dataPrivacyExpirationDate = max; } else if(min != null && requestedDate.compareTo(min) < 0 ) { _dataPrivacyExpirationDate = min; }else { _dataPrivacyExpirationDate = requestedDate; } } public void setDataPrivacyExpirationNotifiedDate(LocalDate dataPrivacyExpirationNotifiedDate) { _dataPrivacyExpirationNotifiedDate = dataPrivacyExpirationNotifiedDate; } /** * The date at which a dataPrivacyExpiration email was sent to Screensaver * Users associated with this Screen. */ @Column @Type(type="edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getDataPrivacyExpirationNotifiedDate() { return _dataPrivacyExpirationNotifiedDate; } @Column(nullable = true) @Type(type = "edu.harvard.med.screensaver.db.usertypes.LocalDateType") public LocalDate getPubchemDepositedDate() { return _pubchemDepositedDate; } public void setPubchemDepositedDate(LocalDate pubchemDepositedDate) { _pubchemDepositedDate = pubchemDepositedDate; } @Column(nullable = true) public Integer getPubchemAssayId() { return _pubchemAssayId; } public void setPubchemAssayId(Integer pubchemAssayId) { _pubchemAssayId = pubchemAssayId; } /** * Specify the specific compound studied, if applicable * for [#3155] Create a linkable field for "compound studied" on the study */ public void setWellStudied(Well wellStudied) { this.wellStudied = wellStudied; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="wellStudiedId", nullable=true, updatable=true) @org.hibernate.annotations.ForeignKey(name="fk_screen_to_well_studied") @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.PROXY) public Well getWellStudied() { return wellStudied; } @Column(precision=ScreensaverConstants.MOLAR_CONCENTRATION_PRECISION, scale=ScreensaverConstants.MOLAR_CONCENTRATION_SCALE) @org.hibernate.annotations.Type(type = "edu.harvard.med.screensaver.db.usertypes.MolarConcentrationType") public MolarConcentration getPerturbagenMolarConcentration() { return perturbagenMolarConcentration; } public void setPerturbagenMolarConcentration(MolarConcentration value) { this.perturbagenMolarConcentration = value; } public void setPerturbagenUgMlConcentration(BigDecimal ugMlConcentration) { this.perturbagenUgMlConcentration = ugMlConcentration; } @Column(precision = ScreensaverConstants.UG_ML_CONCENTRATION_PRECISION, scale = ScreensaverConstants.UG_ML_CONCENTRATION_SCALE) public BigDecimal getPerturbagenUgMlConcentration() { return this.perturbagenUgMlConcentration; } /** */ @OneToMany(mappedBy = "screen", cascade = { CascadeType.ALL }, orphanRemoval = false) @ToMany(hasNonconventionalMutation=true ) @org.hibernate.annotations.Sort(type=org.hibernate.annotations.SortType.NATURAL) @org.hibernate.annotations.ForeignKey(name = "fk_experimental_cell_information_set_to_screen") public Set<ExperimentalCellInformation> getExperimentalCellInformationSet() { return _experimentalCellInformationSet; } public void setExperimentalCellInformationSet(SortedSet<ExperimentalCellInformation> value) { _experimentalCellInformationSet = value; } }