package edu.ualberta.med.biobank.forms;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.widgets.Section;
import edu.ualberta.med.biobank.SessionManager;
import edu.ualberta.med.biobank.common.action.specimenType.SpecimenTypeGetAllAction;
import edu.ualberta.med.biobank.common.action.study.StudyGetClinicInfoAction.ClinicInfo;
import edu.ualberta.med.biobank.common.action.study.StudyGetInfoAction;
import edu.ualberta.med.biobank.common.action.study.StudyInfo;
import edu.ualberta.med.biobank.common.action.study.StudySaveAction;
import edu.ualberta.med.biobank.common.action.study.StudySaveAction.AliquotedSpecimenSaveInfo;
import edu.ualberta.med.biobank.common.action.study.StudySaveAction.SourceSpecimenSaveInfo;
import edu.ualberta.med.biobank.common.action.study.StudySaveAction.StudyEventAttrSaveInfo;
import edu.ualberta.med.biobank.common.peer.StudyPeer;
import edu.ualberta.med.biobank.common.wrappers.AliquotedSpecimenWrapper;
import edu.ualberta.med.biobank.common.wrappers.CommentWrapper;
import edu.ualberta.med.biobank.common.wrappers.ContactWrapper;
import edu.ualberta.med.biobank.common.wrappers.GlobalEventAttrWrapper;
import edu.ualberta.med.biobank.common.wrappers.ModelWrapper;
import edu.ualberta.med.biobank.common.wrappers.SourceSpecimenWrapper;
import edu.ualberta.med.biobank.common.wrappers.SpecimenTypeWrapper;
import edu.ualberta.med.biobank.common.wrappers.StudyWrapper;
import edu.ualberta.med.biobank.gui.common.BgcLogger;
import edu.ualberta.med.biobank.gui.common.validators.NonEmptyStringValidator;
import edu.ualberta.med.biobank.gui.common.widgets.BgcBaseText;
import edu.ualberta.med.biobank.gui.common.widgets.BgcEntryFormWidgetListener;
import edu.ualberta.med.biobank.gui.common.widgets.MultiSelectEvent;
import edu.ualberta.med.biobank.gui.common.widgets.utils.ComboSelectionUpdate;
import edu.ualberta.med.biobank.model.ActivityStatus;
import edu.ualberta.med.biobank.model.AliquotedSpecimen;
import edu.ualberta.med.biobank.model.Comment;
import edu.ualberta.med.biobank.model.Contact;
import edu.ualberta.med.biobank.model.EventAttrCustom;
import edu.ualberta.med.biobank.model.SourceSpecimen;
import edu.ualberta.med.biobank.model.SpecimenType;
import edu.ualberta.med.biobank.model.Study;
import edu.ualberta.med.biobank.model.StudyEventAttr;
import edu.ualberta.med.biobank.treeview.AdapterBase;
import edu.ualberta.med.biobank.treeview.admin.StudyAdapter;
import edu.ualberta.med.biobank.widgets.EventAttrWidget;
import edu.ualberta.med.biobank.widgets.infotables.CommentsInfoTable;
import edu.ualberta.med.biobank.widgets.infotables.entry.AliquotedSpecimenEntryInfoTable;
import edu.ualberta.med.biobank.widgets.infotables.entry.ClinicAddInfoTable;
import edu.ualberta.med.biobank.widgets.infotables.entry.SourceSpecimenEntryInfoTable;
import edu.ualberta.med.biobank.widgets.utils.GuiUtil;
public class StudyEntryForm extends BiobankEntryForm {
public static final String ID =
"edu.ualberta.med.biobank.forms.StudyEntryForm"; //$NON-NLS-1$
private static final String MSG_NEW_STUDY_OK =
Messages.StudyEntryForm_creation_msg;
private static final String MSG_STUDY_OK =
Messages.StudyEntryForm_edition_msg;
private static final String DATE_PROCESSED_INFO_FIELD_NAME =
Messages.study_visit_info_dateProcessed;
protected static BgcLogger log = BgcLogger
.getLogger(StudyEntryForm.class.getName());
private static class StudyEventAttrCustom extends EventAttrCustom {
public EventAttrWidget widget;
public boolean inStudy;
}
private final StudyWrapper study = new StudyWrapper(
SessionManager.getAppService());
private ClinicAddInfoTable contactEntryTable;
private final List<StudyEventAttrCustom> pvCustomInfoList;
private AliquotedSpecimenEntryInfoTable aliquotedSpecimenEntryTable;
private final BgcEntryFormWidgetListener listener =
new BgcEntryFormWidgetListener() {
@Override
public void selectionChanged(MultiSelectEvent event) {
setDirty(true);
}
};
private ComboViewer activityStatusComboViewer;
private SourceSpecimenEntryInfoTable sourceSpecimenEntryTable;
private CommentsInfoTable commentEntryTable;
private final CommentWrapper comment = new CommentWrapper(
SessionManager.getAppService());
private StudyInfo studyInfo;
private List<SpecimenTypeWrapper> specimenTypeWrappers;
public StudyEntryForm() {
super();
pvCustomInfoList = new ArrayList<StudyEventAttrCustom>();
}
@Override
public void init() throws Exception {
Assert.isTrue((adapter instanceof StudyAdapter),
"Invalid editor input: object of type " //$NON-NLS-1$
+ adapter.getClass().getName());
updateStudyInfo(adapter.getId());
String tabName;
if (study.isNew()) {
tabName = Messages.StudyEntryForm_title_new;
study.setActivityStatus(ActivityStatus.ACTIVE);
} else {
tabName =
NLS.bind(Messages.StudyEntryForm_title_edit,
study.getNameShort());
}
setPartName(tabName);
}
private void updateStudyInfo(Integer id) throws Exception {
if (id != null) {
studyInfo =
SessionManager.getAppService().doAction(
new StudyGetInfoAction(id));
study.setWrappedObject(studyInfo.getStudy());
} else {
studyInfo = new StudyInfo();
study.setWrappedObject(new Study());
}
comment.setWrappedObject(new Comment());
List<SpecimenType> specimenTypes =
SessionManager.getAppService()
.doAction(new SpecimenTypeGetAllAction()).getList();
specimenTypeWrappers =
ModelWrapper.wrapModelCollection(SessionManager.getAppService(),
specimenTypes, SpecimenTypeWrapper.class);
((AdapterBase) adapter).setModelObject(study);
}
@Override
protected void createFormContent() throws Exception {
form.setText(Messages.StudyEntryForm_main_title);
form.setMessage(getOkMessage(), IMessageProvider.NONE);
page.setLayout(new GridLayout(1, false));
Composite client = toolkit.createComposite(page);
GridLayout layout = new GridLayout(2, false);
layout.horizontalSpacing = 10;
client.setLayout(layout);
client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
toolkit.paintBordersFor(client);
setFirstControl(createBoundWidgetWithLabel(client, BgcBaseText.class,
SWT.NONE, "Name", null, study,
StudyPeer.NAME.getName(), new NonEmptyStringValidator(
Messages.StudyEntryForm_name_validator_msg)));
createBoundWidgetWithLabel(client, BgcBaseText.class, SWT.NONE,
"Name Short", null, study,
StudyPeer.NAME_SHORT.getName(), new NonEmptyStringValidator(
Messages.StudyEntryForm_nameShort_validator_msg));
activityStatusComboViewer =
createComboViewer(client, "Activity status",
ActivityStatus.valuesList(), study.getActivityStatus(),
Messages.StudyEntryForm_activity_validator_msg,
new ComboSelectionUpdate() {
@Override
public void doSelection(Object selectedObject) {
study
.setActivityStatus((ActivityStatus) selectedObject);
}
});
createCommentSection();
createClinicSection();
createSourceSpecimensSection();
createAliquotedSpecimensSection();
createEventAttrSection();
createButtonsSection();
}
private void createClinicSection() {
Section section = createSection(Messages.StudyEntryForm_contacts_title);
List<Contact> contacts = new ArrayList<Contact>();
for (ClinicInfo clinicInfo : studyInfo.getClinicInfos())
contacts.addAll(clinicInfo.getContacts());
contactEntryTable =
new ClinicAddInfoTable(section, contacts);
contactEntryTable.adaptToToolkit(toolkit, true);
contactEntryTable.addSelectionChangedListener(listener);
addSectionToolbar(section, Messages.StudyEntryForm_contacts_button_add,
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
contactEntryTable.createClinicContact();
}
});
section.setClient(contactEntryTable);
}
private void createCommentSection() {
Composite client = createSectionWithClient("Comments");
GridLayout gl = new GridLayout(2, false);
client.setLayout(gl);
commentEntryTable =
new CommentsInfoTable(client, study.getCommentCollection(false));
GridData gd = new GridData();
gd.horizontalSpan = 2;
gd.grabExcessHorizontalSpace = true;
gd.horizontalAlignment = SWT.FILL;
commentEntryTable.setLayoutData(gd);
createBoundWidgetWithLabel(client, BgcBaseText.class, SWT.MULTI,
"Add a comment", null, comment, "message", null); //$NON-NLS-1$
}
private void createSourceSpecimensSection() {
Section section =
createSection(Messages.StudyEntryForm_source_specimens_title);
sourceSpecimenEntryTable =
new SourceSpecimenEntryInfoTable(
section,
ModelWrapper.wrapModelCollection(
SessionManager.getAppService(),
studyInfo.getSourceSpecimens(), SourceSpecimenWrapper.class),
specimenTypeWrappers);
sourceSpecimenEntryTable.adaptToToolkit(toolkit, true);
sourceSpecimenEntryTable.addSelectionChangedListener(listener);
addSectionToolbar(section,
Messages.StudyEntryForm_source_specimens_button_add,
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
sourceSpecimenEntryTable.addSourceSpecimen();
aliquotedSpecimenEntryTable
.setAvailableSpecimenTypes(sourceSpecimenEntryTable
.getList());
}
});
section.setClient(sourceSpecimenEntryTable);
}
private void createAliquotedSpecimensSection() {
Composite client =
createSectionWithClient(Messages.StudyEntryForm_aliquoted_specimens_title);
GridLayout layout = (GridLayout) client.getLayout();
layout.numColumns = 1;
layout.verticalSpacing = 0;
toolkit.createLabel(client, Messages.StudyEntryForm_1, SWT.LEFT);
aliquotedSpecimenEntryTable =
new AliquotedSpecimenEntryInfoTable(client,
ModelWrapper.wrapModelCollection(
SessionManager.getAppService(),
studyInfo.getAliquotedSpcs(),
AliquotedSpecimenWrapper.class), true, true);
aliquotedSpecimenEntryTable.adaptToToolkit(toolkit, true);
aliquotedSpecimenEntryTable.addSelectionChangedListener(listener);
aliquotedSpecimenEntryTable
.setAvailableSpecimenTypes(sourceSpecimenEntryTable
.getList());
addSectionToolbar((Section) client.getParent(),
Messages.StudyEntryForm_aliquoted_specimens_button_add,
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
aliquotedSpecimenEntryTable.addAliquotedSpecimen();
}
}, AliquotedSpecimenWrapper.class);
}
private void createEventAttrSection() throws Exception {
Composite client =
createSectionWithClient(Messages.StudyEntryForm_visit_info_title);
GridLayout gl = (GridLayout) client.getLayout();
gl.numColumns = 1;
toolkit.createLabel(client, Messages.StudyEntryForm_2,
SWT.LEFT);
StudyEventAttrCustom studyEventAttrCustom;
Map<String, StudyEventAttr> studyEventAttrLabelMap =
new HashMap<String, StudyEventAttr>();
for (StudyEventAttr sea : studyInfo.getStudyEventAttrs()) {
studyEventAttrLabelMap.put(sea.getGlobalEventAttr().getLabel(),
sea);
}
for (GlobalEventAttrWrapper geAttr : GlobalEventAttrWrapper
.getAllGlobalEventAttrs(SessionManager.getAppService())) {
String label = geAttr.getLabel();
boolean selected = false;
studyEventAttrCustom = new StudyEventAttrCustom();
studyEventAttrCustom.setGlobalEventAttr(geAttr.getWrappedObject());
studyEventAttrCustom.setLabel(label);
studyEventAttrCustom.setType(geAttr.getTypeName());
StudyEventAttr sea = studyEventAttrLabelMap.get(label);
if (sea != null) {
studyEventAttrCustom.setStudyEventAttrId(sea.getId());
String permissible = sea.getPermissible();
if ((permissible != null) && !permissible.isEmpty()) {
studyEventAttrCustom.setAllowedValues(permissible
.split(";")); //$NON-NLS-1$
}
selected =
sea.getActivityStatus().equals(ActivityStatus.ACTIVE);
}
studyEventAttrCustom.setIsDefault(false);
studyEventAttrCustom.widget =
new EventAttrWidget(client, SWT.NONE, studyEventAttrCustom,
selected);
studyEventAttrCustom.widget.addSelectionChangedListener(listener);
studyEventAttrCustom.inStudy = (sea != null);
pvCustomInfoList.add(studyEventAttrCustom);
}
}
private void createButtonsSection() {
Composite client = toolkit.createComposite(page);
GridLayout layout = new GridLayout(2, false);
layout.horizontalSpacing = 10;
client.setLayout(layout);
client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
toolkit.paintBordersFor(client);
}
@Override
protected String getOkMessage() {
if (study.getId() == null) {
return MSG_NEW_STUDY_OK;
}
return MSG_STUDY_OK;
}
@Override
protected void saveForm() throws Exception {
// save of source specimen is made inside the entryinfotable
study.getWrappedObject().setContacts(
new HashSet<Contact>(contactEntryTable.getList()));
final StudySaveAction saveAction = new StudySaveAction();
saveAction.setId(study.getId());
saveAction.setName(study.getName());
saveAction.setNameShort(study.getNameShort());
saveAction.setActivityStatus(study.getActivityStatus());
saveAction.setContactIds(getContactInfos());
saveAction.setSourceSpecimenSaveInfo(getSourceSpecimenInfos());
saveAction.setAliquotSpecimenSaveInfo(getAliquotedSpecimenInfos());
saveAction.setStudyEventAttrSaveInfo(getStudyEventAttrInfos());
saveAction.setCommentText(comment.getMessage());
Integer id =
SessionManager.getAppService().doAction(saveAction).getId();
study.setId(id);
((AdapterBase) adapter).setModelObject(study);
}
private HashSet<Integer> getContactInfos() {
HashSet<Integer> contactIds = new HashSet<Integer>();
for (ContactWrapper wrapper : study.getContactCollection(false)) {
contactIds.add(wrapper.getId());
}
return contactIds;
}
private HashSet<SourceSpecimenSaveInfo> getSourceSpecimenInfos() {
HashSet<SourceSpecimenSaveInfo> sourceSpecimenSaveInfos =
new HashSet<SourceSpecimenSaveInfo>();
Set<SourceSpecimen> newSourceSpcs =
new HashSet<SourceSpecimen>(studyInfo.getSourceSpecimens());
// remove the ones deleted
for (SourceSpecimenWrapper wrapper : sourceSpecimenEntryTable
.getDeletedSourceSpecimens()) {
newSourceSpcs.remove(wrapper.getWrappedObject());
}
// add the ones not modified
for (SourceSpecimen ss : newSourceSpcs) {
if (!sourceSpecimenEntryTable
.getAddedOrModifiedSourceSpecimens().contains(ss)) {
sourceSpecimenSaveInfos.add(new SourceSpecimenSaveInfo(ss));
}
}
// add the modified ones
for (SourceSpecimenWrapper wrapper : sourceSpecimenEntryTable
.getAddedOrModifiedSourceSpecimens()) {
sourceSpecimenSaveInfos.add(new SourceSpecimenSaveInfo(
wrapper.getWrappedObject()));
}
return sourceSpecimenSaveInfos;
}
private HashSet<AliquotedSpecimenSaveInfo> getAliquotedSpecimenInfos() {
HashSet<AliquotedSpecimenSaveInfo> aliquotedSpecimenSaveInfos =
new HashSet<AliquotedSpecimenSaveInfo>();
Set<AliquotedSpecimen> newAliquotedSpcs =
new HashSet<AliquotedSpecimen>(studyInfo.getAliquotedSpcs());
// remove the ones deleted
for (AliquotedSpecimenWrapper wrapper : aliquotedSpecimenEntryTable
.getDeletedAliquotedSpecimens()) {
newAliquotedSpcs.remove(wrapper.getWrappedObject());
}
// add the ones not modified
for (AliquotedSpecimen as : newAliquotedSpcs) {
if (!aliquotedSpecimenEntryTable
.getAddedOrModifiedAliquotedSpecimens().contains(as)) {
aliquotedSpecimenSaveInfos
.add(new AliquotedSpecimenSaveInfo(as));
}
}
// add the modified ones
for (AliquotedSpecimenWrapper wrapper : aliquotedSpecimenEntryTable
.getAddedOrModifiedAliquotedSpecimens()) {
aliquotedSpecimenSaveInfos.add(new AliquotedSpecimenSaveInfo(
wrapper.getWrappedObject()));
}
return aliquotedSpecimenSaveInfos;
}
private HashSet<StudyEventAttrSaveInfo> getStudyEventAttrInfos() {
final HashSet<StudyEventAttrSaveInfo> studyEventAttrSaveInfos =
new HashSet<StudyEventAttrSaveInfo>();
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
for (StudyEventAttrCustom studyEventAttrCustom : pvCustomInfoList) {
String label = studyEventAttrCustom.getLabel();
if (label.equals(DATE_PROCESSED_INFO_FIELD_NAME)
|| (!studyEventAttrCustom.widget.getSelected() && !studyEventAttrCustom.inStudy))
continue;
StudyEventAttrSaveInfo studyEventAttrSaveInfo =
new StudyEventAttrSaveInfo();
studyEventAttrSaveInfo.id =
studyEventAttrCustom.getStudyEventAttrId();
studyEventAttrSaveInfo.globalEventAttrId =
studyEventAttrCustom.getGlobalEventAttrId();
studyEventAttrSaveInfo.permissible =
studyEventAttrCustom.widget.getValues();
// TODO: required not used at the moment
studyEventAttrSaveInfo.required = false;
if (!studyEventAttrCustom.widget.getSelected()
&& studyEventAttrCustom.inStudy) {
studyEventAttrSaveInfo.activityStatus =
ActivityStatus.CLOSED;
} else if (studyEventAttrCustom.widget.getSelected()) {
studyEventAttrSaveInfo.activityStatus =
ActivityStatus.ACTIVE;
}
log.debug(studyEventAttrSaveInfo.toString());
studyEventAttrSaveInfos.add(studyEventAttrSaveInfo);
}
}
});
return studyEventAttrSaveInfos;
}
@Override
public String getNextOpenedFormId() {
return StudyViewForm.ID;
}
@Override
public void setValues() throws Exception {
if (study.isNew()) {
study.setActivityStatus(ActivityStatus.ACTIVE);
}
GuiUtil.reset(activityStatusComboViewer, study.getActivityStatus());
contactEntryTable.reload();
aliquotedSpecimenEntryTable.reload();
sourceSpecimenEntryTable.reload(ModelWrapper.wrapModelCollection(
SessionManager.getAppService(),
studyInfo.getSourceSpecimens(), SourceSpecimenWrapper.class));
commentEntryTable.setList(study.getCommentCollection(false));
resetPvCustomInfo();
}
private void resetPvCustomInfo() throws Exception {
Map<String, StudyEventAttr> studyEventAttrLabelMap =
new HashMap<String, StudyEventAttr>();
for (StudyEventAttr sea : studyInfo.getStudyEventAttrs()) {
studyEventAttrLabelMap.put(sea.getGlobalEventAttr().getLabel(),
sea);
}
for (StudyEventAttrCustom studyPvAttrCustom : pvCustomInfoList) {
boolean selected = false;
StudyEventAttr sea =
studyEventAttrLabelMap.get(studyPvAttrCustom.getLabel());
if (sea != null) {
String permissible = sea.getPermissible();
if ((permissible != null) && !permissible.isEmpty()) {
studyPvAttrCustom.setAllowedValues(permissible
.split(";")); //$NON-NLS-1$
}
selected = true;
studyPvAttrCustom.inStudy = true;
}
selected |= (studyPvAttrCustom.getAllowedValues() != null);
studyPvAttrCustom.widget.setSelected(selected);
studyPvAttrCustom.widget.reloadAllowedValues(studyPvAttrCustom);
}
}
}