/* Date: February 24, 2011
* Template: PluginScreenJavaTemplateGen.java.ftl
* generator: org.molgenis.generators.ui.PluginScreenJavaTemplateGen 3.3.3
*
* THIS FILE IS A TEMPLATE. PLEASE EDIT :-)
*/
package org.molgenis.protocol;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.molgenis.framework.db.Database;
import org.molgenis.framework.ui.EasyPluginController;
import org.molgenis.framework.ui.ScreenController;
import org.molgenis.framework.ui.ScreenMessage;
import org.molgenis.framework.ui.ScreenView;
import org.molgenis.framework.ui.html.MolgenisForm;
import org.molgenis.matrix.MatrixException;
import org.molgenis.pheno.Measurement;
import org.molgenis.pheno.ObservationElement;
import org.molgenis.pheno.ObservedValue;
import org.molgenis.util.Tuple;
public class ApplyProtocolPlugin extends EasyPluginController
{
private static final long serialVersionUID = -5500131586262572567L;
private ApplyProtocolPluginModel model;
private ApplyProtocolUI ui;
private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm", Locale.US);
private ApplyProtocolService service = new ApplyProtocolService();
public ApplyProtocolPlugin(String name, ScreenController<?> parent)
{
super(name, parent);
model = new ApplyProtocolPluginModel(this);
ui = new ApplyProtocolUI(model);
}
@Override
public Show handleRequest(Database db, Tuple request, OutputStream out)
{
ScreenMessage message = null;
String action = request.getString("__action");
try
{
if (ui.targetMatrixViewer != null && action.startsWith(ui.targetMatrixViewer.getName()))
{
ui.targetMatrixViewer.setDatabase(db);
ui.targetMatrixViewer.handleRequest(db, request);
action = "init";
}
if (action.equals("Select"))
{
message = handleSelect(db, request);
}
if (action.equals("Clear"))
{
ui.initScreen(db, this, db.getLogin().getUserId(), db.getLogin().getUserName());
}
if (action.equals("Apply"))
{
message = handleApply(request, db);
}
if (action.equals("ApplyAllDefaults"))
{
message = handleApplyAllDefaults(db, request);
}
if (action.contains("ApplyDefault_"))
{
message = handleApplyDefaults(db, request, Integer.parseInt(action.substring(13)));
}
if (action.contains("ApplyStartTime_"))
{
message = handleApplyStartTime(db, request, Integer.parseInt(action.substring(15)));
}
if (action.contains("ApplyEndTime_"))
{
message = handleApplyEndTime(db, request, Integer.parseInt(action.substring(13)));
}
}
catch (Exception e)
{
message = new ScreenMessage("Something went wrong while handling your request: " + e.getMessage(), false);
}
if (message != null)
{
this.setMessages(message);
}
return Show.SHOW_MAIN;
}
@Override
public void reload(Database db)
{
if (ui.targetMatrixViewer != null)
{
ui.targetMatrixViewer.setDatabase(db);
}
model.setService(service);
ui.setService(service);
int userId = db.getLogin().getUserId();
// Only first time or if user changed:
if (ui.getProtocolApplicationContainer() == null || userId != model.getUserId())
{
model.setUserAndInvestigationIds(db, userId);
try
{
ui.initScreen(db, this, userId, db.getLogin().getUserName());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public ScreenView getView()
{
MolgenisForm form = new MolgenisForm(this.model);
form.add(ui.getProtocolApplicationContainer());
return form;
}
ScreenMessage handleApply(Tuple request, Database db)
{
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm", Locale.US);
try
{
int userId = db.getLogin().getUserId();
int ownInvId = service.getOwnUserInvestigationIds(db, userId).get(0);
List<Integer> investigationIds = service.getWritableUserInvestigationIds(db, userId);
int paId = service.makeProtocolApplication(db, ownInvId, model.getProtocolName());
for (int row = 1; row <= model.getFullTargetList().size(); row++)
{
int targetId = model.getTargetsIdList().get(row - 1);
for (int col = 0; col < model.getFeaturesList().size(); col++)
{
Measurement measurement = model.getFeaturesList().get(col);
String dataType = measurement.getDataType();
int colNrInTable = col;
if (model.isTimeInfo())
{
colNrInTable *= 3;
}
List<ObservedValue> originalValues = service.getObservedValuesByTargetAndFeature(db, targetId,
measurement, investigationIds, ownInvId);
if (!model.isNewProtocolApplication())
{
// User chose to edit existing values (db.update())
// Note: if a value did not yet exist for the
// target-feature combination,
// a new one is made and added to the DB.
// Loop through the values
int valueCounter = 0;
for (ObservedValue originalObservedValue : originalValues)
{
String oldValue = "";
if (dataType.equals("xref"))
{
if (originalObservedValue.getRelation_Name() != null)
{
oldValue = originalObservedValue.getRelation_Name();
}
}
else
{
oldValue = originalObservedValue.getValue();
}
Date oldStartTime = originalObservedValue.getTime();
Date oldEndTime = originalObservedValue.getEndtime();
// Get new/modified value/relation
Date startTime = null;
Date endTime = null;
if (model.isTimeInfo())
{
// If date-time info supplied, get and parse
// that as well
if (request.getString((colNrInTable + 1) + "_" + row + "_" + valueCounter) != null)
{
String startTimeString = request.getString((colNrInTable + 1) + "_" + row + "_"
+ valueCounter);
startTime = formatter.parse(startTimeString);
}
if (request.getString((colNrInTable + 2) + "_" + row + "_" + valueCounter) != null)
{
String endTimeString = request.getString((colNrInTable + 2) + "_" + row + "_"
+ valueCounter);
endTime = formatter.parse(endTimeString);
}
}
String newValue = "";
if (request.getString(colNrInTable + "_" + row + "_" + valueCounter) != null)
{
newValue = request.getString(colNrInTable + "_" + row + "_" + valueCounter);
}
// Compare, and update if necessary
if (!oldValue.equals(newValue) || oldStartTime != startTime || oldEndTime != endTime)
{
if (dataType.equals("xref"))
{
// Set _Id instead of _Name because
// db.update() doesn't resolve foreign keys
originalObservedValue.setRelation_Id(Integer.parseInt(newValue));
originalObservedValue.setValue(null);
}
else
{
originalObservedValue.setValue(newValue);
}
originalObservedValue.setTime(startTime);
originalObservedValue.setEndtime(endTime);
if (originalObservedValue.getProtocolApplication_Id() == null)
{
// No prot.app set yet -> new value ->
// db.add()
originalObservedValue.setProtocolApplication_Id(paId);
db.add(originalObservedValue);
}
else
{
// Prot.app. already set -> existing value
// -> db.update()
db.update(originalObservedValue);
}
// TODO: add value to batch list and add/update
// later
}
if (!model.isAllValues())
{
// If user wants only the first value, jump out
// now:
break;
}
valueCounter++;
} // end of value loop
}
else
{
// User chose to enter new values (db.add())
Date startTime = null;
Date endTime = null;
ObservedValue newValue = new ObservedValue();
if (model.isTimeInfo())
{
// If date-time info supplied, get and parse that as
// well
if (request.getString((colNrInTable + 1) + "_" + row + "_0") != null)
{
String startTimeString = request.getString((colNrInTable + 1) + "_" + row + "_0");
startTime = formatter.parse(startTimeString);
}
if (request.getString((colNrInTable + 2) + "_" + row + "_0") != null)
{
String endTimeString = request.getString((colNrInTable + 2) + "_" + row + "_0");
endTime = formatter.parse(endTimeString);
}
}
String value = "";
if (request.getString(colNrInTable + "_" + row + "_0") != null)
{
value = request.getString(colNrInTable + "_" + row + "_0");
}
// Compare, and update if necessary
if (dataType.equals("xref"))
{
newValue.setRelation_Id(Integer.parseInt(value));
newValue.setValue(null);
}
else
{
newValue.setValue(value);
}
newValue.setFeature(measurement);
newValue.setTarget(targetId);
newValue.setTime(startTime);
newValue.setEndtime(endTime);
newValue.setProtocolApplication(paId);
// TODO: is it correct that new values are always
// assigned to the investigation
// owned by the current user?
if (model.getOwnInvestigationId(db) != -1)
{
newValue.setInvestigation_Id(model.getOwnInvestigationId(db));
}
db.add(newValue);
// TODO: add to batch list and add later
}
} // end of feature loop
} // end of target loop
// Reset table:
ui.fillTableCells(db);
return new ScreenMessage("Protocol applied successfully", true);
}
catch (Exception e)
{
e.printStackTrace();
if (e.getMessage() != null)
{
return new ScreenMessage("Something went wrong while applying protocol: " + e.getMessage(), false);
}
}
return null;
}
ScreenMessage handleApplyAllDefaults(Database db, Tuple request)
{
int sizeTargets = model.getFullTargetList().size();
int sizeFeatures = model.getFeaturesList().size();
for (int col = 0; col < sizeFeatures; col++)
{
int colNrInTable = col;
if (model.isTimeInfo())
{
colNrInTable *= 3;
}
Measurement measurement = model.getFeaturesList().get(col);
String dataType = "string";
try
{
dataType = measurement.getDataType();
}
catch (Exception e)
{
// do nothing, stick with default
}
// Placeholder to store value from default in
ObservedValue newValue = new ObservedValue();
// Put value in appropriate field
if (dataType.equals("xref"))
{
newValue.setRelation_Id(request.getInt(colNrInTable + "_0_0"));
}
else
{
newValue.setValue(request.getString(colNrInTable + "_0_0"));
}
try
{
for (int row = 1; row <= sizeTargets; row++)
{
ui.makeInputAndSetCell(db, col, colNrInTable, row, 0, newValue);
}
}
catch (Exception e)
{
return new ScreenMessage("Setting defaults failed: " + e, false);
}
}
return null;
}
/**
* Takes the default value for each column and puts it in all the input
* boxes for that column (a.k.a. feature).
*
* @param request
* @param i
*/
ScreenMessage handleApplyDefaults(Database db, Tuple request, int col)
{
int featureNr = col;
// int nrOfCols = model.getFeaturesList().size();
if (model.isTimeInfo())
{
featureNr /= 3;
// nrOfCols *= 3;
}
Measurement measurement = model.getFeaturesList().get(featureNr);
int sizeTargets = model.getFullTargetList().size();
String dataType = "string";
try
{
dataType = measurement.getDataType();
}
catch (Exception e)
{
// do nothing, stick with default
}
fixValues(db, request);
// Placeholder to store value from default in
ObservedValue newValue = new ObservedValue();
// Put value in appropriate field
if (dataType.equals("xref"))
{
newValue.setRelation_Id(request.getInt(col + "_0_0"));
}
else
{
newValue.setValue(request.getString(col + "_0_0"));
}
try
{
for (int row = 1; row <= sizeTargets; row++)
{
ui.makeInputAndSetCell(db, featureNr, col, row, 0, newValue);
}
}
catch (Exception e)
{
return new ScreenMessage("Setting defaults failed: " + e, false);
}
return null;
}
/**
* Makes the table based on the protocol and targets selected by the user.
*
* @param db
* @param request
* @throws MatrixException
*/
ScreenMessage handleSelect(Database db, Tuple request) throws MatrixException
{
List<String> fullTargetList = new ArrayList<String>();
// Get protocol
Object protocol = request.getObject("Protocols");
if (protocol == null)
{
return new ScreenMessage("No protocol selected", false);
}
model.setProtocolName(protocol.toString());
// Set some feature info only once
try
{
model.setFeaturesLists(db, service.getMeasurementsByProtocol(db, model.getProtocolName()));
}
catch (Exception e)
{
e.printStackTrace();
return new ScreenMessage("Error: could not retrieve measurements for chosen protocol", false);
}
// Get targets
@SuppressWarnings("unchecked")
List<ObservationElement> rows = (List<ObservationElement>) ui.targetMatrixViewer.getSelection(db);
int rowCnt = 0;
for (ObservationElement row : rows)
{
if (request.getBool(ApplyProtocolUI.TARGETMATRIX + "_selected_" + rowCnt) != null)
{
model.getTargetList().add(row.getId().toString());
fullTargetList.add(row.getId().toString());
}
rowCnt++;
}
// if (targetListObject != null) {
// for (Object o : targetListObject) {
// String tmpString = (String)o;
// model.getTargetList().add(tmpString);
// fullTargetList.add(tmpString);
// }
// }
// Get batches
List<?> batchesListObject = request.getList("Batches");
if (batchesListObject != null)
{
for (Object o : batchesListObject)
{
String tmpString = (String) o;
model.getBatchesList().add(tmpString);
}
}
// Get targets from batches and add them to the full target list
if (model.getBatchesList() != null)
{
for (Object o : model.getBatchesList())
{
Integer id = Integer.parseInt((String) o);
fullTargetList.addAll(service.getTargetsFromBatch(db, id));
}
}
if (fullTargetList.size() == 0)
{
return new ScreenMessage("No animals selected", false);
}
model.setFullTargetList(fullTargetList);
// Get new/edit values
if (request.getString("NewOrEdit").equals("New"))
{
model.setNewProtocolApplication(true);
}
else
{
model.setNewProtocolApplication(false);
}
// Get date-time info yes/no
if (request.getBool("TimeBox") != null)
{
model.setTimeInfo(true);
}
else
{
model.setTimeInfo(false);
}
// Get all values yes/no
if (request.getBool("AllValuesBox") != null)
{
model.setAllValues(true);
}
else
{
model.setAllValues(false);
}
ui.setValues();
// Make the table div
ui.makeTable(db);
if (model.isAllValues() == false)
{
// Show Apply all defaults button only when showing one value per
// cell
ui.makeApplyAllDefaultsButton();
}
ui.makeApplyButton();
ui.addTableDiv();
return null;
}
public ScreenMessage handleApplyStartTime(Database db, Tuple request, int col)
{
fixValues(db, request);
try
{
String startTimeString = request.getString(col + "_0_0");
Date startTime = dateTimeFormat.parse(startTimeString);
for (int row = 1; row <= model.getFullTargetList().size(); row++)
{
ui.makeDateInputAndSetCell(col, row, 0, startTime);
}
}
catch (Exception e)
{
return new ScreenMessage("Setting start date-time defaults failed: " + e, false);
}
return null;
}
public ScreenMessage handleApplyEndTime(Database db, Tuple request, int col)
{
fixValues(db, request);
try
{
String endTimeString = request.getString(col + "_0_0");
Date endTime = dateTimeFormat.parse(endTimeString);
for (int row = 1; row <= model.getFullTargetList().size(); row++)
{
ui.makeDateInputAndSetCell(col, row, 0, endTime);
}
}
catch (Exception e)
{
return new ScreenMessage("Setting end date-time defaults failed: " + e, false);
}
return null;
}
/**
* Go through all inputs in the table and set their values, so changes that
* the user already made don't get lost. Works only for cells that contain
* one input.
*/
private void fixValues(Database db, Tuple request)
{
int nrOfCols = model.getFeaturesList().size();
if (model.isTimeInfo())
{
nrOfCols *= 3;
}
for (int colNr = 0; colNr < nrOfCols; colNr++)
{
for (int row = 1; row <= model.getFullTargetList().size(); row++)
{
ui.fixCellValue(db, colNr, row, request.getString(colNr + "_" + row + "_0"));
}
}
}
}