package ru.yandex.qatools.htmlelements.loader.decorator;
import org.openqa.selenium.By;
import org.openqa.selenium.support.FindAll;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import ru.yandex.qatools.htmlelements.annotations.Block;
import ru.yandex.qatools.htmlelements.exceptions.HtmlElementsException;
import ru.yandex.qatools.htmlelements.pagefactory.DefaultFieldAnnotationsHandler;
import java.lang.reflect.Field;
import static ru.yandex.qatools.htmlelements.utils.HtmlElementUtils.*;
/**
* Extends default field annotations handling mechanism with processing
* {@link Block} annotation for blocks and lists of blocks.
*
* @author Alexander Tolmachev starlight@yandex-team.ru
* Date: 15.08.12
*/
public class HtmlElementFieldAnnotationsHandler extends DefaultFieldAnnotationsHandler {
public HtmlElementFieldAnnotationsHandler(Field field) {
super(field);
}
@Override
public By buildBy() {
if (isHtmlElement(getField())) {
return buildByFromHtmlElementAnnotations();
}
if (isHtmlElementList(getField())) {
return buildByFromHtmlElementListAnnotations();
} else {
return buildByFromDefaultAnnotations();
}
}
private By buildByFromFindAnnotations() {
if (getField().isAnnotationPresent(FindBys.class)) {
FindBys findBys = getField().getAnnotation(FindBys.class);
return buildByFromFindBys(findBys);
}
if (getField().isAnnotationPresent(FindAll.class)) {
FindAll findBys = getField().getAnnotation(FindAll.class);
return buildBysFromFindAll(findBys);
}
if (getField().isAnnotationPresent(FindBy.class)) {
FindBy findBy = getField().getAnnotation(FindBy.class);
return buildByFromFindBy(findBy);
}
return null;
}
private By buildByFromHtmlElementAnnotations() {
assertValidAnnotations();
By result = buildByFromFindAnnotations();
if (result != null) {
return result;
}
Class<?> fieldClass = getField().getType();
while (fieldClass != Object.class) {
if (fieldClass.isAnnotationPresent(Block.class)) {
Block block = fieldClass.getAnnotation(Block.class);
FindBy findBy = block.value();
return buildByFromFindBy(findBy);
}
if (fieldClass.isAnnotationPresent(FindBy.class)) {
return buildByFromFindBy(fieldClass.getAnnotation(FindBy.class));
}
fieldClass = fieldClass.getSuperclass();
}
return buildByFromDefault();
}
private By buildByFromHtmlElementListAnnotations() {
assertValidAnnotations();
By result = buildByFromFindAnnotations();
if (result != null) {
return result;
}
Class<?> listParameterClass = getGenericParameterClass(getField());
while (listParameterClass != Object.class) {
if (listParameterClass.isAnnotationPresent(Block.class)) {
Block block = listParameterClass.getAnnotation(Block.class);
FindBy findBy = block.value();
return buildByFromFindBy(findBy);
}
if (listParameterClass.isAnnotationPresent(FindBy.class)) {
return buildByFromFindBy(listParameterClass.getAnnotation(FindBy.class));
}
listParameterClass = listParameterClass.getSuperclass();
}
throw new HtmlElementsException(String.format("Cannot determine how to locate element %s", getField()));
}
private By buildByFromDefaultAnnotations() {
return super.buildBy();
}
}