All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.fluentlenium.core.conditions.wait.WaitConditionInvocationHandler Maven / Gradle / Ivy
package org.fluentlenium.core.conditions.wait;
import org.fluentlenium.core.FluentControl;
import org.fluentlenium.core.conditions.Conditions;
import org.fluentlenium.core.conditions.ConditionsObject;
import org.fluentlenium.core.conditions.Negation;
import org.fluentlenium.core.conditions.message.MessageContext;
import org.fluentlenium.core.conditions.message.MessageProxy;
import org.fluentlenium.core.wait.FluentWait;
import org.openqa.selenium.WrapsElement;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Invocation handler used to wait for a particular conditions call.
*
* @param type of conditions
*/
public class WaitConditionInvocationHandler> implements InvocationHandler {
private final Class conditionClass;
private final Supplier conditionSupplier;
private final FluentWait wait;
private String context;
private boolean negation;
/**
* Creates a new wait condition invocation handler.
*
* @param conditionClass condition class
* @param wait fluent wait
* @param context base context of generated message if condition is not verified
* @param conditionSupplier supplier of conditions
*/
public WaitConditionInvocationHandler(Class conditionClass, FluentWait wait, String context,
Supplier conditionSupplier) {
this.conditionClass = conditionClass;
this.wait = wait;
this.context = context;
this.conditionSupplier = conditionSupplier;
}
/**
* Get the underlying conditions of wait matcher.
*
* @return underlying conditions.
*/
protected C conditions() {
return conditions(false);
}
/**
* Get the underlying conditions of wait matcher.
*
* @param ignoreNot true if the negation should be ignored.
* @return underlying conditions.
*/
protected C conditions(boolean ignoreNot) {
C conditions = conditionSupplier.get();
return applyNegation(conditions, ignoreNot);
}
/**
* Apply the current negation to the given condition
*
* @param conditions conditions.
* @param ignoreNegation true if the negation should be ignored.
* @return conditions with the negation applied.
*/
protected C applyNegation(C conditions, boolean ignoreNegation) {
if (!ignoreNegation && negation) {
return (C) conditions.not();
}
return conditions;
}
/**
* Builds a message builder proxy.
*
* @return message builder proxy
*/
protected C messageBuilder() {
return messageBuilder(false);
}
/**
* Builds a message builder proxy.
*
* @param ignoreNegation true if the negation should be ignored.
* @return message builder proxy
*/
protected C messageBuilder(boolean ignoreNegation) {
C conditions = MessageProxy.builder(conditionClass, context);
conditions = applyNegation(conditions, ignoreNegation);
return conditions;
}
/**
* Build the final message from default message.
*
* @return final message
*/
protected Function messageCustomizer() {
return Function.identity();
}
/**
* Perform the wait.
*
* @param present predicate to wait for.
* @param message message to use.
*/
protected void until(Predicate present, String message) {
if (wait.hasMessageDefined()) {
wait.untilPredicate(present);
} else {
message = messageCustomizer().apply(message);
wait.withMessage(message).untilPredicate(present);
}
}
/**
* Perform the wait.
*
* @param present predicate to wait for.
* @param messageSupplier default message to use.
*/
protected void until(Predicate present, Supplier messageSupplier) {
if (wait.hasMessageDefined()) {
wait.untilPredicate(present);
} else {
Supplier customMessageSupplier = () -> messageCustomizer().apply(messageSupplier.get());
wait.withMessage(customMessageSupplier).untilPredicate(present);
}
}
/**
* Perform the wait.
*
* @param condition condition object to wait for
* @param messageBuilder message builder matching the condition object
* @param conditionFunction condition function
*/
protected void until(C condition, C messageBuilder, Function conditionFunction) {
Predicate predicate = input -> conditionFunction.apply(condition);
Supplier messageSupplier = () -> {
conditionFunction.apply(messageBuilder);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(MessageProxy.message(messageBuilder));
if (condition instanceof ConditionsObject) {
Object actualObject = ((ConditionsObject) condition).getActualObject();
if (!(actualObject instanceof WrapsElement)) {
stringBuilder.append(" (actual: ").append(actualObject).append(')');
}
}
return stringBuilder.toString();
};
until(predicate, messageSupplier);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isAnnotationPresent(Negation.class)) {
return buildNegationProxy();
}
if (method.isAnnotationPresent(MessageContext.class)) {
context = context + " " + method.getAnnotation(MessageContext.class).value();
}
Class returnType = method.getReturnType();
if (boolean.class.equals(returnType) || Boolean.class.equals(returnType)) {
return waitForCondition(method, args);
} else if (Conditions.class.isAssignableFrom(returnType)) {
return buildChildProxy(method, args);
} else {
throw new IllegalStateException("An internal error has occurred.");
}
}
private Object buildChildProxy(Method method, Object[] args)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method conditionGetter = conditions().getClass().getMethod(method.getName(), method.getParameterTypes());
Conditions childConditions = (Conditions) conditionGetter.invoke(conditions(true), args);
Conditions childProxy = WaitConditionProxy
.custom((Class>) method.getReturnType(), wait, context, () -> childConditions);
WaitConditionInvocationHandler childHandler = (WaitConditionInvocationHandler) Proxy.getInvocationHandler(childProxy);
childHandler.negation = negation;
return childProxy;
}
private boolean waitForCondition(Method method, Object[] args) {
C messageBuilder = messageBuilder();
until(conditions(), messageBuilder, input -> {
try {
return (Boolean) method.invoke(input, args);
} catch (IllegalAccessException e) {
throw new IllegalStateException("An internal error has occured while waiting", e);
} catch (InvocationTargetException e) {
Throwable targetException = e.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException) targetException;
}
throw new IllegalStateException("An internal error has occured while waiting", e);
}
});
return true;
}
private Conditions buildNegationProxy() {
Conditions negationProxy = WaitConditionProxy.custom(conditionClass, wait, context, conditionSupplier);
WaitConditionInvocationHandler negationHandler = (WaitConditionInvocationHandler) Proxy
.getInvocationHandler(negationProxy);
negationHandler.negation = !negation;
return negationProxy;
}
}