package eu.scape_project.planning.sla; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import eu.scape_project.planning.model.Plan; import eu.scape_project.planning.model.measurement.EvaluationScope; import eu.scape_project.planning.model.measurement.Measure; import eu.scape_project.planning.model.transform.NumericTransformer; import eu.scape_project.planning.model.transform.OrdinalTransformer; import eu.scape_project.planning.model.tree.Leaf; import eu.scape_project.planning.validation.ValidationError; import eu.scape_project.watch.domain.DictionaryItem; import eu.scape_project.watch.domain.Notification; import eu.scape_project.watch.domain.Question; import eu.scape_project.watch.domain.RequestTarget; import eu.scape_project.watch.domain.Trigger; /** * Generates trigger for preservation watch based on defined decision criteria. * * @author Michael Kraxner * */ public class TriggerGenerator { private List<Trigger> triggers; private long period; private String recipients; public TriggerGenerator() { } public List<Trigger> generateTriggers(final String recipients, final long period, final Plan plan) { triggers = new ArrayList<Trigger>(); this.period = period; this.recipients = recipients; List<Leaf> leaves = plan.getTree().getRoot().getAllLeaves(); List<ValidationError> errors = null; for (Leaf leaf : leaves) { if (leaf.isCompletelySpecified(errors) && leaf.isCompletelyTransformed(errors) && leaf.isMapped()) { if (EvaluationScope.ALTERNATIVE_ACTION == leaf.getMeasure().getAttribute().getCategory().getScope()) { // generate trigger for preservation watch addTrigger(leaf); } } } return triggers; } private void addTrigger(Leaf leaf) { Measure meas = leaf.getMeasure(); Question q = null; if (leaf.getTransformer() instanceof OrdinalTransformer) { // TODO } else if (leaf.getTransformer() instanceof NumericTransformer){ NumericTransformer numericT = (NumericTransformer)leaf.getTransformer(); String name = meas.getName(); String operator; if (numericT.hasIncreasingOrder()) { // values must be greater or equal threshold 1, therefore we watch for smaller values operator = " < "; } else { // values must be smaller or equal threshold 1, therefore we watch for higher values operator = " > "; } if ("http://purl.org/DP/quality/measures#11".equals(meas.getUri())) { // this value is accumulated, we check for min/max if (numericT.hasIncreasingOrder()) { name = "Minimum " + name; } else { name = "Maximum " + name; } String threshold = "" + numericT.getThreshold1(); String sparql = String.format( "?p rdf:type watch:Property. " + "?p watch:name ?n . " + "?v watch:property ?p. " + "?v watch:floatValue ?fv. " + "FILTER (?n = \"%s\" && ?fv %s %s ) " + " BIND(CONCAT(?n, \" is \", str(?fv) , \", should not be %s %s \") AS ?s )", name, operator, threshold, operator, threshold); q = new Question(sparql, RequestTarget.PROPERTY_VALUE); } } if (q != null) { final Notification n = new Notification("email", Arrays.asList(new DictionaryItem("recepients", this.recipients))); final Trigger trigger = new Trigger(null, null, null, this.period, q, null,Arrays.asList(n)); triggers.add(trigger); } } }