Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
ONYX-1753 Not repeatable output parameters that can be entered manual…
Browse files Browse the repository at this point in the history
…ly are handled differently from the repeatable ones
  • Loading branch information
ymarcon committed Feb 1, 2018
1 parent a4a1744 commit fcad80c
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ public boolean hasManualCaptureOutputParameters() {
return false;
}

public boolean hasManualCaptureOutputParameters(boolean repeatable) {
for(InstrumentOutputParameter parameter : getOutputParameters()) {
if(isManualCapture(parameter) && isRepeatable(parameter) == repeatable) return true;
}
return false;
}

/**
* Returns a list of {@link InstrumentOutputParameter}s that permit manual capture. Normally these parameters would be
* captured automatically, but if required they may also be captured manually.
Expand Down Expand Up @@ -380,7 +387,6 @@ public List<InstrumentOutputParameter> getOutputParameters() {

/**
* Shall we expect data from a remote instrument application ?
* @param instrument
* @return
*/
public boolean isInteractive() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,53 @@
package org.obiba.onyx.jade.core.wicket.instrument;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.value.ValueMap;
import org.apache.wicket.validation.validator.StringValidator;
import org.obiba.core.service.EntityQueryService;
import org.obiba.onyx.core.domain.participant.Participant;
import org.obiba.onyx.jade.core.domain.instrument.InstrumentInputParameter;
import org.obiba.onyx.jade.core.domain.instrument.InstrumentOutputParameter;
import org.obiba.onyx.jade.core.domain.instrument.InstrumentParameterCaptureMethod;
import org.obiba.onyx.jade.core.domain.instrument.InstrumentType;
import org.obiba.onyx.jade.core.domain.run.InstrumentRun;
import org.obiba.onyx.jade.core.domain.run.InstrumentRunValue;
import org.obiba.onyx.jade.core.service.ActiveInstrumentRunService;
import org.obiba.onyx.jade.core.service.InstrumentService;
import org.obiba.onyx.jade.core.wicket.InstrumentRunValueDataModel;
import org.obiba.onyx.jade.core.wicket.instrument.validation.IntegrityCheckValidator;
import org.obiba.onyx.util.data.Data;
import org.obiba.onyx.util.data.DataType;
import org.obiba.onyx.wicket.behavior.ButtonDisableBehavior;
import org.obiba.onyx.wicket.data.DataField;
import org.obiba.onyx.wicket.data.DataValidator;
import org.obiba.onyx.wicket.model.MagmaStringResourceModel;
import org.obiba.onyx.wicket.model.SpringStringResourceModel;
import org.obiba.wicket.markup.html.table.DetachableEntityModel;
import org.obiba.wicket.model.MessageSourceResolvableStringModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -52,26 +74,39 @@ public abstract class InstrumentLaunchPanel extends Panel {

private static final Logger log = LoggerFactory.getLogger(InstrumentLaunchPanel.class);

private static final String AUTOMATIC = "AutomaticCapture";

private static final String MANUAL = "ManualCapture";

@SpringBean
private EntityQueryService queryService;

@SpringBean
private ActiveInstrumentRunService activeInstrumentRunService;

@SpringBean
private InstrumentService instrumentService;

private final InstrumentType instrumentType;

private AutomaticCaptureFragment automaticCapture;

private Component manualCapture;

private MeasuresPanel measures;

private Link<Object> startButton;
private String selectedCaptureMethod = AUTOMATIC;

private List<IModel<InstrumentRunValue>> outputRunValueModels = new ArrayList<IModel<InstrumentRunValue>>();

@SuppressWarnings("serial")
public InstrumentLaunchPanel(String id) {
super(id);
InstrumentRun currentRun = activeInstrumentRunService.getInstrumentRun();
setDefaultModel(new Model<InstrumentRun>(currentRun));

setOutputMarkupId(true);

final InstrumentType instrumentType = activeInstrumentRunService.getInstrumentType();
String codebase = instrumentService.getInstrumentInstallPath(instrumentType);
instrumentType = activeInstrumentRunService.getInstrumentType();

// instrument instructions
add(new Label("instrument-instructions", new MagmaStringResourceModel(new MessageSourceResolvableStringModel(instrumentType.getInstructions())) {
Expand All @@ -92,12 +127,46 @@ protected Locale getLocale() {
}
}).setEscapeModelStrings(false));

// general instructions and launcher
add(new Label("general", new StringResourceModel("StartMeasurementWithInstrument", this, new Model<ValueMap>(new ValueMap("name=" + instrumentType.getName())))));
automaticCapture = new AutomaticCaptureFragment("automaticCapture");
add(automaticCapture);

final InstrumentLauncher launcher = new InstrumentLauncher(instrumentType, codebase);
// capture method
final RadioGroup radioGroup = new RadioGroup<String>("radioGroup", new PropertyModel<String>(this, "selectedCaptureMethod"));
radioGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() {
@Override
protected void onUpdate(AjaxRequestTarget target) {
log.info("radioGroup.onUpdate={}", selectedCaptureMethod);
if (measures != null) measures.showManualCapture(selectedCaptureMethod.equals(MANUAL));
if (manualCapture != null) manualCapture.setVisible(selectedCaptureMethod.equals(MANUAL));
automaticCapture.setVisible(selectedCaptureMethod.equals(AUTOMATIC));
target.addComponent(InstrumentLaunchPanel.this);
}
});
add(radioGroup);
radioGroup.setVisible(instrumentType.hasManualCaptureOutputParameters());
ListView radioList = new ListView<String>("radioItem", Arrays.asList(new String[] { AUTOMATIC, MANUAL })) {

@Override
protected void populateItem(final ListItem item) {
Radio radio = new Radio<String>("radio", item.getModel());
radio.setLabel(new StringResourceModel((String) item.getModelObject(), InstrumentLaunchPanel.this, null));
item.add(radio);
item.add(new SimpleFormComponentLabel("radioLabel", radio));
}

}.setReuseItems(true);
radioGroup.add(radioList);
radioGroup.setRequired(true);

if(instrumentType.hasManualCaptureOutputParameters() || instrumentType.isRepeatable()) {
if (instrumentType.hasManualCaptureOutputParameters(false)) {
manualCapture = new ManualCaptureFragment("manualCapture");
add(manualCapture);
manualCapture.setVisible(false);
} else {
add(new EmptyPanel("manualCapture"));
}

if (instrumentType.isRepeatable()) {
add(measures = new MeasuresPanel("measures") {
@Override
public void onAddClick(AjaxRequestTarget target) {
Expand All @@ -107,45 +176,22 @@ public void onAddClick(AjaxRequestTarget target) {

@Override
public void onRefresh(AjaxRequestTarget target) {
startButton.setEnabled(!isSkipMeasurement() && measures.getMeasureCount() < measures.getExpectedMeasureCount());
target.addComponent(startButton);
automaticCapture.setStartButtonEnabled(!isSkipMeasurement() && measures.getMeasureCount() < measures.getExpectedMeasureCount());
target.addComponent(automaticCapture);
}

@Override
public void onSkipUpdate(AjaxRequestTarget target) {
startButton.setEnabled(!isSkipMeasurement() && measures.getMeasureCount() < measures.getExpectedMeasureCount());
target.addComponent(startButton);
automaticCapture.setStartButtonEnabled(!isSkipMeasurement() && measures.getMeasureCount() < measures.getExpectedMeasureCount());
target.addComponent(automaticCapture);
}

});
measures.showManualCapture(false);
} else {
add(new EmptyPanel("measures"));
}

// if(instrumentType.isRepeatable()) {
// add(new AbstractAjaxTimerBehavior(Duration.seconds(10)) {
//
// protected void onTimer(AjaxRequestTarget target) {
// measures.refresh(target);
// }
//
// });
// }

startButton = new Link<Object>("start") {

@Override
public void onClick() {
launcher.launch();
InstrumentLaunchPanel.this.onInstrumentLaunch();
}

};
startButton.add(new ButtonDisableBehavior());
startButton.setOutputMarkupId(true);
startButton.setEnabled(!isMeasureComplete());
add(startButton);

String errMessage = activeInstrumentRunService.updateReadOnlyInputParameterRunValue();
if(errMessage != null) error(errMessage);

Expand Down Expand Up @@ -193,6 +239,12 @@ public Serializable getObject() {
add(instructions);
}

public void saveManualOutputInstrumentRunValues() {
for(IModel<InstrumentRunValue> runValueModel : outputRunValueModels) {
activeInstrumentRunService.update(runValueModel.getObject());
}
}

/**
* Called when instrument launcher is clicked.
*/
Expand All @@ -212,4 +264,128 @@ public boolean isMeasureComplete() {
return false;
}

public class AutomaticCaptureFragment extends Fragment {

private Link<Object> startButton;

public AutomaticCaptureFragment(String id) {
super(id, "automaticCaptureFragment", InstrumentLaunchPanel.this);
setOutputMarkupId(true);
// general instructions and launcher
add(new Label("general", new StringResourceModel("StartMeasurementWithInstrument", InstrumentLaunchPanel.this,
new Model<ValueMap>(new ValueMap("name=" + instrumentType.getName())))));

String codebase = instrumentService.getInstrumentInstallPath(instrumentType);
final InstrumentLauncher launcher = new InstrumentLauncher(instrumentType, codebase);
startButton = new Link<Object>("start") {

@Override
public void onClick() {
launcher.launch();
InstrumentLaunchPanel.this.onInstrumentLaunch();
}

};
startButton.add(new ButtonDisableBehavior());
startButton.setOutputMarkupId(true);
startButton.setEnabled(!isMeasureComplete());
add(startButton);
}

public void setStartButtonEnabled(boolean enabled) {
startButton.setEnabled(enabled);
}
}

public class ManualCaptureFragment extends Fragment {
public ManualCaptureFragment(String id) {
super(id, "manualCaptureFragment", InstrumentLaunchPanel.this);
setOutputMarkupId(true);
add(new Label("title", new StringResourceModel("ProvideTheFollowingInformation", InstrumentLaunchPanel.this, null)));
add(new ManualOutputsFragment("manualOutputs"));
}
}

public class ManualOutputsFragment extends Fragment {

public ManualOutputsFragment(String id) {
super(id, "manualOutputsFragment", InstrumentLaunchPanel.this);

RepeatingView repeat = new RepeatingView("repeat");
add(repeat);

instrumentType.getManualCaptureOutputParameters().stream()
.filter(param -> !instrumentType.isRepeatable(param))
.forEach(param -> {
WebMarkupContainer item = new WebMarkupContainer(repeat.newChildId());
repeat.add(item);

InstrumentRunValue runValue = activeInstrumentRunService.getOrCreateInstrumentRunValue(param);

IModel<InstrumentRunValue> runValueModel = new DetachableEntityModel<InstrumentRunValue>(queryService, runValue);
outputRunValueModels.add(runValueModel);

DataField field = makeDataField(param, runValueModel);
item.add(field);

FormComponentLabel label = new FormComponentLabel("label", field.getField());
item.add(label);

Label labelText = new Label("labelText", new MessageSourceResolvableStringModel(param.getLabel()));
label.add(labelText);
});
}

private DataField makeDataField(InstrumentOutputParameter param, final IModel<InstrumentRunValue> runValueModel) {
List<Data> choices = null;
if(param.getDataSource() == null) {
choices = param.getAllowedValues();
}

DataField field;

if(choices != null && choices.size() > 0) {
field = new DataField("field", new InstrumentRunValueDataModel(runValueModel, param.getDataType()), param.getDataType(), choices, new IChoiceRenderer() {

public Object getDisplayValue(Object object) {
Data data = (Data) object;
return new SpringStringResourceModel(data.getValueAsString()).getString();
}

public String getIdValue(Object object, int index) {
Data data = (Data) object;
return data.getValueAsString();
}

}, param.getMeasurementUnit());
field.setRequired(true);

} else {
final String paramCode = param.getCode();
field = new DataField("field", new InstrumentRunValueDataModel(runValueModel, param.getDataType()), param.getDataType(), param.getMeasurementUnit()) {
@Override
public boolean isRequired() {
return activeInstrumentRunService.getInstrumentType().getInstrumentParameter(paramCode).isRequired(activeInstrumentRunService.getParticipant());
}
};

if(param.getDataType().equals(DataType.TEXT) && (field.getField().getClass().equals(java.awt.TextField.class) || field.getField().getClass().equals(TextArea.class))) {
field.getField().add(new DataValidator(new StringValidator.MaximumLengthValidator(2000), param.getDataType()));
}
}

field.setLabel(new MessageSourceResolvableStringModel(param.getLabel()));
field.add(new AjaxFormComponentUpdatingBehavior("onblur") {
protected void onUpdate(AjaxRequestTarget target) {
activeInstrumentRunService.update((InstrumentRunValue) runValueModel.getObject());
}
});

IntegrityCheckValidator.addChecks(param, field);

return field;
}

}

}
Loading

0 comments on commit fcad80c

Please sign in to comment.