package eu.scape_project.planning.efficiency;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import org.supercsv.cellprocessor.FmtDate;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.DMinMax;
import org.supercsv.cellprocessor.constraint.NotNull;
import eu.scape_project.planning.model.Alternative;
import eu.scape_project.planning.model.ChangeLog;
import eu.scape_project.planning.model.DigitalObject;
import eu.scape_project.planning.model.Experiment;
import eu.scape_project.planning.model.Plan;
import eu.scape_project.planning.model.PlanState;
import eu.scape_project.planning.model.SampleObject;
import eu.scape_project.planning.model.Values;
import eu.scape_project.planning.model.scales.Scale;
import eu.scape_project.planning.model.tree.Leaf;
import eu.scape_project.planning.model.tree.TreeNode;
import eu.scape_project.planning.model.values.Value;
public class StateChangeLogGenerator extends StatisticsGenerator {
// private static final Logger LOGGER =
// LoggerFactory.getLogger(StateChangeLogGenerator.class);
/**
* Creates a new plan statistic generator which loads the plans via the
* provided entity manager and outputs to the given writer.
*
* @param writer
* @param em
* @throws IOException
*/
public StateChangeLogGenerator(Writer writer, EntityManager em) throws IOException {
super(writer, em);
setupColumns();
// write the header
listWriter.writeHeader(headers);
}
/**
* Writes the statistics of the given plan to the writer.
*
* @param plan
* @throws IOException
*/
public void writeStatistics(Plan plan) throws IOException {
List<StateChangeLog> stateChangeLogs = generateStatistics(plan);
for (StateChangeLog stateChangeLog : stateChangeLogs) {
listWriter.write(stateChangeLog, headers, processors);
}
listWriter.flush();
}
/**
* Generates the statistics for the given plan.
*
* @param plan
* @return
*/
private List<StateChangeLog> generateStatistics(Plan plan) {
List<StateChangeLog> stateChangeLogs = new ArrayList<StateChangeLog>();
long planId = plan.getPlanProperties().getId();
long createdAt = plan.getChangeLog().getCreated();
// 0 CREATED
// 1 INITIALISED
ChangeLog changelog = plan.getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 1, createdAt, createdAt, changelog.getCreatedBy()));
// 2 Define Basis - BASIS_DEFINED(2)
// - ProjectBasis
changelog = plan.getProjectBasis().getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 2, createdAt, changelog.getChanged(), changelog.getChangedBy()));
// 3. Define Sample Objects - RECORDS_CHOSEN(3)
// - SampleRecordsDefinition
// - samples (also created here)
changelog = plan.getSampleRecordsDefinition().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 3, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
for (SampleObject sample : plan.getSampleRecordsDefinition().getRecords()) {
ChangeLog sampleCL = sample.getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 3, createdAt, sampleCL.getCreated(), sampleCL.getCreatedBy()));
if (sampleCL.getChanged() > sampleCL.getCreated()) {
stateChangeLogs.add(new StateChangeLog(planId, 3, createdAt, sampleCL.getChanged(), sampleCL.getChangedBy()));
}
}
// 4. Identify requirements - TREE_DEFINED(4, "Tree Defined"),
// - nodes/leaves (also created!)
// - scales
// - RequirementsDefinition
changelog = plan.getRequirementsDefinition().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 4, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
List<TreeNode> nodes = plan.getTree().getRoot().getAllChildren();
for (TreeNode treeNode : nodes) {
ChangeLog nodeCL = treeNode.getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 4, createdAt, nodeCL.getCreated(), nodeCL.getCreatedBy()));
// we can only use the scales of leaves, as
// - nodes can be changed when weighting is changed
// - leaves are "changed" when evaluated, aggregation mode is
// changed
if (treeNode instanceof Leaf) {
Scale scale = ((Leaf) treeNode).getScale();
if (scale != null) {
ChangeLog scaleCL = scale.getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 4, createdAt, scaleCL.getChanged(), scaleCL.getChangedBy()));
}
}
}
// 5. Define alternatives - ALTERNATIVES_DEFINED(5,
// "Alternatives Defined")
// - AlternativesDefinition
// - Alternative - only created, "changed" can be overwritten in
// GoDecision)
changelog = plan.getAlternativesDefinition().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 5, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
for (Alternative alternative : plan.getAlternativesDefinition().getAlternatives()) {
ChangeLog altCL = alternative.getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 5, createdAt, altCL.getCreated(), altCL.getCreatedBy()));
}
// 6. Take go decision - GO_CHOSEN(6, "Go Decision Taken")
// - no: Alternative (! - if discarded)
// - GoDecision
changelog = plan.getDecision().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 6, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
// 7. Develop Experiments - EXPERIMENT_DEFINED(7, "Experiments Defined")
// Alternative.Experiment
// as the experiment is created together with the alternative, this
// might result in the same timestamps
for (Alternative alternative : plan.getAlternativesDefinition().getAlternatives()) {
ChangeLog expCL = alternative.getExperiment().getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 7, createdAt, expCL.getChanged(), expCL.getChangedBy()));
}
// 8. Run Experiments - EXPERIMENT_PERFORMED(8, "Experiments Performed")
// - detailedExperimentInfo
// - result files (alternative.experiment.results)
// as the experiment is created together with the alternative, this
// might result in the same timestamps
for (Alternative alternative : plan.getAlternativesDefinition().getAlternatives()) {
Experiment experiment = alternative.getExperiment();
// - result files (alternative.experiment.results)
for (DigitalObject result : experiment.getResults().values()) {
ChangeLog resultCL = result.getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 8, createdAt, resultCL.getChanged(), resultCL.getChangedBy()));
}
}
// 9. Evaluate Experiments - RESULTS_CAPTURED(9, "Results Captured")
// - Evaluation
// - ValueMap-Values
changelog = plan.getEvaluation().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 9, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
for (TreeNode treeNode : nodes) {
if (treeNode instanceof Leaf) {
Leaf leaf = (Leaf) treeNode;
// ValueMap-Values
for (Values values : leaf.getValueMap().values()) {
for (Value value : values.getList()) {
ChangeLog valueCL = value.getChangeLog();
stateChangeLogs
.add(new StateChangeLog(planId, 9, createdAt, valueCL.getChanged(), valueCL.getChangedBy()));
}
}
}
}
// 10. Transform measured values - TRANSFORMATION_DEFINED(10,
// "Transformations Defined")
// - leaf.transformer
// - Transformation
// - leaf (!! - leaf.aggregationMode )
changelog = plan.getTransformation().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 10, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
for (TreeNode treeNode : nodes) {
if (treeNode instanceof Leaf) {
Leaf leaf = (Leaf) treeNode;
if (leaf.getTransformer() != null) {
ChangeLog tCL = leaf.getTransformer().getChangeLog();
stateChangeLogs.add(new StateChangeLog(planId, 10, createdAt, tCL.getChanged(), tCL.getChangedBy()));
}
}
}
// 11. Set importance factors - WEIGHTS_SET(11, "Weights Set")
// - no: node (! - lock )
// - ImportanceWeighting
changelog = plan.getImportanceWeighting().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 11, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
// 12. Analyze results - ANALYSED(12, "Analyzed")
// - Recommendation
changelog = plan.getRecommendation().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 12, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
//
// 13. Create Executable plan - EXECUTEABLE_PLAN_CREATED(13,
// "Executable Plan Created")
// - ExecutablePlanDefinition
changelog = plan.getExecutablePlanDefinition().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 13, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
//
// 14. Define Plan - PLAN_DEFINED(14, "Plan Defined")
// - PlanDefinition
changelog = plan.getPlanDefinition().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 14, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
// 15. Validate Plan
if (plan.getPlanProperties().getState() == PlanState.PLAN_VALIDATED) {
changelog = plan.getPlanProperties().getChangeLog();
if (changelog.getChanged() > createdAt) {
stateChangeLogs.add(new StateChangeLog(planId, 15, createdAt, changelog.getChanged(), changelog.getChangedBy()));
}
}
return stateChangeLogs;
}
protected void setupColumns() {
addColumn("planId", new NotNull());
addColumn("stageNr", new LUndef());
addColumn("hoursSinceStart", new DMinMax(0.0, Double.MAX_VALUE));
addColumn("user", new Optional());
addColumn("timestamp", new FmtDate("yyyy-MM-dd'T'HH:mm:ss"));
finishColumns();
}
}