package com.samknows.measurement.schedule.condition; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import android.util.Log; import com.samknows.measurement.schedule.failaction.RetryFailAction; import com.samknows.measurement.TestRunner.TestContext; public class ConditionGroup extends Condition implements Serializable { private static final long serialVersionUID = 1L; public String id; public final List<Condition> conditions = new ArrayList<>(); public RetryFailAction failAction; public static ConditionGroup parseXml(Element node) { ConditionGroup cg = new ConditionGroup(); cg.id = node.getAttribute("id"); NodeList conditions = node.getElementsByTagName("condition"); for (int i = 0; i < conditions.getLength(); i++) { Element condition = (Element) conditions.item(i); cg.conditions.add(Condition.parseXml(condition)); } NodeList list = node.getElementsByTagName("action"); if (cg != null && list.getLength() > 0) { cg.failAction = RetryFailAction.parseXml((Element) list.item(0)); } return cg; } @Override public String getConditionStringForReportingFailedCondition() { Log.e(this.getClass().toString(), "getConditionStringForReportingFailedCondition - unexpected call!"); return "CONDITION_GROUP"; } @Override public ConditionGroupResult doTestBefore(TestContext tc) { Executor executor = Executors.newCachedThreadPool(); ConditionGroupResult result = new ConditionGroupResult(); List<Future<ConditionResult>> futureResults = new ArrayList<>(); // request for result from all conditions for (Condition c : conditions) { try { Future<ConditionResult> cr = c.testBefore(tc); // // ENABLE THIS IF YOU WANT TO FORCE CONDITION FAILURE AT // RUNTIME IN DEBUGGER (START) // cr.get().isSuccess = false; // // ENABLE THIS IF YOU WANT TO FORCE CONDITION FAILURE AT // RUNTIME IN DEBUGGER (END) futureResults.add(cr); if (!cr.isDone()) { executor.execute((FutureTask<?>) cr); } else if (!cr.get().isSuccess && !c.failQuiet) { // if we have // result // and it // fails // than skip // all the // rest // conditions tc.resultsContainer.addFailedCondition(c); } } catch (Exception e) { e.printStackTrace(); result.isSuccess = false; tc.resultsContainer.addFailedCondition(c); } } for (Future<ConditionResult> future : futureResults) { try { result.add(future.get()); if (!future.get().isSuccess && !future.get().isFailQuiet()) { tc.resultsContainer.addFailedCondition(future.get() .getType()); } } catch (Exception e) { e.printStackTrace(); result.isSuccess = false; tc.resultsContainer .addFailedCondition(ConditionResult.JSON_CRASH); } } return result; } @Override public ConditionGroupResult testAfter(TestContext tc) { ConditionGroupResult result = new ConditionGroupResult(); for (Condition c : conditions) { result.add(c.testAfter(tc)); } return result; } @Override public void release(TestContext tc) { for (Condition c : conditions) c.release(tc); } @Override public boolean needSeparateThread() { return false; } }