// Copyright 2015 ThoughtWorks, Inc. // This file is part of Gauge-Java. // This program is free software. // // It is dual-licensed under: // 1) the GNU General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version; // or // 2) the Eclipse Public License v1.0. // // You can redistribute it and/or modify it under the terms of either license. // We would then provide copied of each license in a separate .txt file with the name of the license as the title of the file. package com.thoughtworks.gauge.execution; import com.thoughtworks.gauge.ClassInstanceManager; import com.thoughtworks.gauge.ExecutionContext; import com.thoughtworks.gauge.Operator; import com.thoughtworks.gauge.hook.Hook; import com.thoughtworks.gauge.tag.TagMatcher; import gauge.messages.Spec; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class HooksExecutor { private final List<Hook> hooks; private final ExecutionContext info; private ClassInstanceManager manager; public HooksExecutor(List<Hook> hooks, ExecutionContext executionInfo, ClassInstanceManager manager) { this.hooks = hooks; this.info = executionInfo; this.manager = manager; } public Spec.ProtoExecutionResult execute() { Spec.ProtoExecutionResult result; long totalHooksExecutionTime = 0; for (Hook hook : hooks) { result = new TaggedHookExecutor(hook, info).execute(); totalHooksExecutionTime += result.getExecutionTime(); if (result.getFailed()) { return Spec.ProtoExecutionResult.newBuilder(result).setExecutionTime(totalHooksExecutionTime).build(); } } return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(totalHooksExecutionTime).build(); } private boolean methodHasArguments(Method method, Object... arg) { if (method.getParameterTypes().length != arg.length) { return false; } List<Class> argsClassList = createClassList(arg); Class<?>[] parameterTypes = method.getParameterTypes(); boolean isValid = true; for (int i = 0; i < parameterTypes.length; i++) { if (!(argsClassList.indexOf(parameterTypes[i]) == i)) { isValid = false; } } return isValid; } private List<Class> createClassList(Object[] objects) { ArrayList<Class> classes = new ArrayList<Class>(); for (Object obj : objects) { classes.add(obj.getClass()); } return classes; } private class TaggedHookExecutor { private final Hook hook; private final ExecutionContext info; TaggedHookExecutor(Hook hook, ExecutionContext info) { this.hook = hook; this.info = info; } public Spec.ProtoExecutionResult execute() { if (tagsMatch(hook.getTags(), hook.getTagsAggregation(), info.getAllTags())) { return executeHook(); } return Spec.ProtoExecutionResult.newBuilder().setExecutionTime(0).setFailed(false).build(); } private boolean tagsMatch(List<String> tags, Operator tagsAggregation, List<String> allTags) { return new TagMatcher().isMatch(tags, tagsAggregation, allTags); } private Spec.ProtoExecutionResult executeHook() { MethodExecutor methodExecutor = new MethodExecutor(manager); if (methodHasArguments(hook.getMethod(), info)) { return methodExecutor.execute(hook.getMethod(), info); } Spec.ProtoExecutionResult result = methodExecutor.execute(hook.getMethod()); return result.toBuilder().setRecoverableError(false).build(); } } }