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.
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.fragment.common.picker;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import org.openqa.selenium.WebElement;
import org.richfaces.fragment.common.picker.ChoicePickerHelper.WebElementPicking.WebElementPicker;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
/**
* @author Juraj Huska
* @author Jiri Stefek
*/
public final class ChoicePickerHelper {
private ChoicePickerHelper() {
}
/**
* @return Returns ChoicePicker for picking choices by index.
*/
public static ByIndexChoicePicker byIndex() {
return new ByIndexChoicePicker();
}
/**
* @return Returns ChoicePicker for picking choices by visible text. The picker can have multiple conditions/filters (e.g. startsWith('xy').endsWith('z')).
*/
public static ByVisibleTextChoicePicker byVisibleText() {
return new ByVisibleTextChoicePicker();
}
/**
* @return Returns ChoicePicker for picking choices by WebElement methods/properties.
*/
public static WebElementPicker byWebElement() {
return new WebElementPickerImpl();
}
public static class ByIndexChoicePicker implements ChoicePicker, MultipleChoicePicker {
private final Set reachableIndexes = new LinkedHashSet();
private final List preparationCommands = Lists.newArrayList();
private ByIndexChoicePicker() {
}
private void addReachableIndex(int index) {
reachableIndexes.add(index);
}
public ByIndexChoicePicker beforeLast(final int positionsBeforeLast) {
preparationCommands.add(new PreparationCommand() {
@Override
public void prepare(List list) {
int countedIndex = list.size() - 1 - positionsBeforeLast;
if (countedIndex >= 0 && countedIndex < list.size()) {
addReachableIndex(countedIndex);
}
}
});
return this;
}
/**
* Picks every nth index from 0 (including).
*
* @param nth has to be greater than 1
* @return same instance
*/
public ByIndexChoicePicker everyNth(final int nth) {
return everyNth(nth, 0);
}
/**
* Picks every nth index from @from (including).
*
* @param nth has to be greater than 1 (the iteration step)
* @param from has to be greater or equals to 0
* @return same instance
*/
public ByIndexChoicePicker everyNth(final int nth, final int from) {
Preconditions.checkArgument(nth > 1);
Preconditions.checkArgument(from >= 0);
preparationCommands.add(new PreparationCommand() {
@Override
public void prepare(List list) {
for (int i = from; i < list.size(); i += nth) {
addReachableIndex(i);
}
}
});
return this;
}
public ByIndexChoicePicker first() {
return index(0);
}
/**
* Picks every index from given range.
*
* @param range range from which will be the indexes picked
* @return same instance
*/
public ByIndexChoicePicker fromRange(final Range range) {
Preconditions.checkNotNull(range);
preparationCommands.add(new PreparationCommand() {
@Override
public void prepare(List list) {
for (int i = 0; i < list.size(); i++) {
if (range.contains(i)) {
addReachableIndex(i);
}
}
}
});
return this;
}
public ByIndexChoicePicker index(final int index) {
preparationCommands.add(new PreparationCommand() {
@Override
public void prepare(List list) {
if (list.size() > index && index >= 0) {
addReachableIndex(index);
}
}
});
return this;
}
public ByIndexChoicePicker indexes(Integer... indexes) {
for (Integer integer : indexes) {
index(integer);
}
return this;
}
public ByIndexChoicePicker last() {
return beforeLast(0);
}
@Override
public WebElement pick(List options) {
List elements = pickInner(options, TRUE);
return (elements.isEmpty() ? null : elements.get(0));
}
private List pickInner(List options, boolean pickFirst) {
Preconditions.checkNotNull(options, "Options cannot be null.");
Preconditions.checkArgument(!reachableIndexes.isEmpty() || !preparationCommands.isEmpty(), "No filter specified.");
if (options.isEmpty()) {
return Collections.emptyList();
}
for (PreparationCommand command : preparationCommands) {
command.prepare(options);
}
if (reachableIndexes.isEmpty()) {
return Collections.emptyList();
}
List result = Lists.newArrayList();
if (pickFirst) {
result.add(options.get(reachableIndexes.iterator().next()));
} else {
for (Integer i : reachableIndexes) {
result.add(options.get(i));
}
}
return result;
}
@Override
public List pickMultiple(List options) {
return pickInner(options, FALSE);
}
@Override
public String toString() {
return (reachableIndexes.isEmpty() ? "unknown index picking" : reachableIndexes.toString());
}
private interface PreparationCommand {
void prepare(List list);
}
};
public static class ByVisibleTextChoicePicker implements ChoicePicker, MultipleChoicePicker {
private final List filters = Lists.newArrayList();
private boolean allRulesMustPass = Boolean.TRUE;
private Function transformationFunction;
private ByVisibleTextChoicePicker() {
}
public ByVisibleTextChoicePicker addFilter(Predicate filter) {
filters.add(filter);
return this;
}
/**
* If true, then all rules/filters must pass to pick an element.
* If false, then if at least one rule/filter passes, element will be picked.
* Default value is true.
* @param allRulesMustPass
*/
public ByVisibleTextChoicePicker allRulesMustPass(boolean allRulesMustPass) {
this.allRulesMustPass = allRulesMustPass;
return this;
}
public ByVisibleTextChoicePicker contains(final String str) {
return addFilter(new Predicate() {
@Override
public boolean apply(WebElement input) {
return input.getText().contains(str);
}
@Override
public String toString() {
return "contains('" + str + "')";
}
});
}
public ByVisibleTextChoicePicker endsWith(final String str) {
return addFilter(new Predicate() {
@Override
public boolean apply(WebElement input) {
return input.getText().endsWith(str);
}
@Override
public String toString() {
return "endsWith('" + str + "')";
}
});
}
public ByVisibleTextChoicePicker match(final String str) {
return addFilter(new Predicate() {
@Override
public boolean apply(WebElement input) {
return input.getText().matches(str);
}
@Override
public String toString() {
return "matches('" + str + "')";
}
});
}
@Override
public WebElement pick(List options) {
List elements = pickInner(options, TRUE);
return (elements == null || (elements.isEmpty()) ? null : elements.get(0));
}
private List pickInner(List options, boolean pickFirst) {
Preconditions.checkNotNull(options, "Options cannot be null.");
Preconditions.checkArgument(!filters.isEmpty(), "No filters specified.");
if (options.isEmpty()) {
return Collections.EMPTY_LIST;
}
if (pickFirst) {
try {
return Lists.newArrayList(Iterables.find(options, new PickPredicate()));
} catch (NoSuchElementException e) {
return Collections.EMPTY_LIST;
}
// Less performant:
//
// Optional tryFind = Iterables.tryFind(options, new PickPredicate());
// return (tryFind.isPresent() ? Lists.newArrayList(tryFind.get()) : Collections.EMPTY_LIST);
} else {
return Lists.newArrayList(Sets.newLinkedHashSet(Iterables.filter(options, new PickPredicate())));
}
}
@Override
public List pickMultiple(List options) {
return pickInner(options, FALSE);
}
/**
* Sets a transformation function, that will be used to transform each WebElement from list of possible choices
* to another WebElement.
*
* Example:
* This picker will be picking and comparing text from such divs:
*
*
* text1
* text2
*
* ,
* but you want to compare the text only with the second span.
* The only thing you need to do is to add this function:
*
* new Function() {
* @Override
* public WebElement apply(WebElement input) {
* return input.findElements(By.tagName("span")).get(1);
* }
* }
*
*
* @param transformationFunction
*/
public void setTransformationFunction(Function transformationFunction) {
this.transformationFunction = transformationFunction;
}
public ByVisibleTextChoicePicker startsWith(final String str) {
return addFilter(new Predicate() {
@Override
public boolean apply(WebElement input) {
return input.getText().startsWith(str);
}
@Override
public String toString() {
return "startsWith('" + str + "')";
}
});
}
@Override
public String toString() {
return (filters.isEmpty() ? "no filters specified" : filters.toString());
}
private WebElement transFormIfNeeded(WebElement input) {
return (transformationFunction == null ? input : transformationFunction.apply(input));
}
private class PickPredicate implements Predicate {
@Override
public boolean apply(WebElement input) {
WebElement element = transFormIfNeeded(input);
if (allRulesMustPass) {
for (Predicate predicate : filters) {
if (!predicate.apply(element)) {
return FALSE;
}
}
return TRUE;
} else {
for (Predicate predicate : filters) {
if (predicate.apply(element)) {
return TRUE;
}
}
return FALSE;
}
}
}
};
public interface WebElementPicking {
ComparationBy text();
ComparationBy attribute(String attributeName);
public interface ComparationBy {
CanBeNegated endsWith(String str);
CanBeNegated equalTo(String str);
CanBeNegated contains(String str);
CanBeNegated matches(String str);
CanBeNegated starstWith(String str);
}
public interface CanBeNegated extends LogicalOperation {
LogicalOperation not();
}
public interface LogicalOperation extends ChoicePicker, MultipleChoicePicker {
WebElementPicking and();
WebElementPicking or();
}
public interface WebElementPicker extends ChoicePicker, MultipleChoicePicker, WebElementPicking {
}
}
public static class WebElementPickerImpl implements WebElementPicker {
private final LinkedList predicates = new LinkedList();
private final LinkedList logicalFunctions = new LinkedList();
private final ComparationBy comparation = new ComparationByImpl();
private final LogicalOperation operation = new LogicalOperationImpl();
private final CanBeNegated canBeNegated = new CanBeNegatedImpl();
private Function transformationFunction;
private Function webElementFunction;
private enum LogicalFunctions {
AND {
@Override
boolean apply(boolean b1, Predicate b2, WebElement e) {
return b1 && b2.apply(e);
}
},
OR {
@Override
boolean apply(boolean b1, Predicate b2, WebElement e) {
return b1 || b2.apply(e);
}
};
abstract boolean apply(boolean b1, Predicate b2, WebElement e);
}
@Override
public ComparationBy attribute(String attributeName) {
webElementFunction = new GetAttributeFunction(attributeName);
return comparation;
}
@Override
public WebElement pick(List options) {
List elements = pickInner(options, TRUE);
return (elements.isEmpty() ? null : elements.get(0));
}
private List pickInner(List options, boolean pickFirst) {
Preconditions.checkNotNull(options, "Options cannot be null.");
Preconditions.checkArgument(!predicates.isEmpty());
Preconditions.checkArgument(predicates.size() - 1 == logicalFunctions.size());
if (options.isEmpty()) {
return Collections.EMPTY_LIST;
}
LinkedHashSet result;
try {
if (pickFirst) {
result = Sets.newLinkedHashSet();
result.add(Iterables.find(options, new FinalPredicate()));
} else {
result = Sets.newLinkedHashSet(Iterables.filter(options, new FinalPredicate()));
}
return Lists.newArrayList(result);
} catch (NoSuchElementException ex) {
return Collections.EMPTY_LIST;
}
}
@Override
public List pickMultiple(List options) {
return pickInner(options, FALSE);
}
@Override
public ComparationBy text() {
webElementFunction = new GetTextFunction();
return comparation;
}
private WebElement transFormIfNeeded(WebElement input) {
return (transformationFunction == null ? input : transformationFunction.apply(input));
}
private class FinalPredicate implements Predicate {
@Override
public boolean apply(WebElement input) {
WebElement transformed = transFormIfNeeded(input);
if (predicates.size() == 1) {
return predicates.peekFirst().apply(input);
}
LinkedList> predicatesCopy = new LinkedList>(predicates);
LinkedList logicalFunctionsCopy = new LinkedList(logicalFunctions);
boolean previousResult = predicatesCopy.removeFirst().apply(transformed);
LogicalFunctions logicalFunction;
while (!logicalFunctionsCopy.isEmpty()) {
logicalFunction = logicalFunctionsCopy.removeFirst();
if (!previousResult && logicalFunction.equals(LogicalFunctions.AND)) {
return previousResult;// return false if previous result was false and the function is AND
}
previousResult = logicalFunction.apply(previousResult, predicatesCopy.removeFirst(), transformed);
}
return previousResult;
}
}
private class ComparationByImpl implements ComparationBy {
@Override
public CanBeNegated contains(String str) {
predicates.add(new MergingPredicate(webElementFunction, new ContainsFunction(str)));
return canBeNegated;
}
@Override
public CanBeNegated endsWith(String str) {
predicates.add(new MergingPredicate(webElementFunction, new EndsWithFunction(str)));
return canBeNegated;
}
@Override
public CanBeNegated equalTo(String str) {
predicates.add(new MergingPredicate(webElementFunction, new EqualsToFunction(str)));
return canBeNegated;
}
@Override
public CanBeNegated matches(String str) {
predicates.add(new MergingPredicate(webElementFunction, new MatchesFunction(str)));
return canBeNegated;
}
@Override
public CanBeNegated starstWith(String str) {
predicates.add(new MergingPredicate(webElementFunction, new StartsWithFunction(str)));
return canBeNegated;
}
}
private class LogicalOperationImpl implements LogicalOperation {
@Override
public WebElementPicking and() {
logicalFunctions.add(LogicalFunctions.AND);
return WebElementPickerImpl.this;
}
@Override
public WebElementPicking or() {
logicalFunctions.add(LogicalFunctions.OR);
return WebElementPickerImpl.this;
}
@Override
public WebElement pick(List options) {
return WebElementPickerImpl.this.pick(options);
}
@Override
public List pickMultiple(List options) {
return WebElementPickerImpl.this.pickMultiple(options);
}
}
private class CanBeNegatedImpl extends LogicalOperationImpl implements CanBeNegated {
@Override
public LogicalOperation not() {
predicates.peekLast().negate();
return operation;
}
}
private static class MergingPredicate implements Predicate {
private final Function elementToString;
private final Function stringToBoolean;
private boolean negate = Boolean.FALSE;
public MergingPredicate(Function elementToString, Function stringToBoolean) {
this.elementToString = elementToString;
this.stringToBoolean = stringToBoolean;
}
public void negate() {
this.negate = Boolean.TRUE;
}
@Override
public boolean apply(WebElement input) {
boolean result = stringToBoolean.apply(elementToString.apply(input));
return negate ? !result : result;
}
@Override
public String toString() {
return "MergingPredicate{" + "elementToString=" + elementToString + ", stringToBoolean=" + stringToBoolean + ", negate=" + negate + '}';
}
}
private class GetTextFunction implements Function {
@Override
public String apply(WebElement input) {
return input.getText();
}
@Override
public String toString() {
return "GetTextFunction()";
}
}
private static class GetAttributeFunction implements Function {
private final String attName;
public GetAttributeFunction(String attName) {
this.attName = attName;
}
@Override
public String apply(WebElement input) {
return input.getAttribute(attName);
}
@Override
public String toString() {
return "GetAttributeFunction{" + "attName=" + attName + '}';
}
}
private static class ContainsFunction extends CompareToFunction {
public ContainsFunction(String compareTo) {
super(compareTo);
}
@Override
public Boolean apply(String input) {
return input.contains(getCompareTo());
}
}
private static class EndsWithFunction extends CompareToFunction {
public EndsWithFunction(String compareTo) {
super(compareTo);
}
@Override
public Boolean apply(String input) {
return input.endsWith(getCompareTo());
}
}
private static class EqualsToFunction extends CompareToFunction {
public EqualsToFunction(String compareTo) {
super(compareTo);
}
@Override
public Boolean apply(String input) {
return input.equals(getCompareTo());
}
}
private static class MatchesFunction extends CompareToFunction {
public MatchesFunction(String compareTo) {
super(compareTo);
}
@Override
public Boolean apply(String input) {
return input.matches(getCompareTo());
}
}
private static class StartsWithFunction extends CompareToFunction {
public StartsWithFunction(String compareTo) {
super(compareTo);
}
@Override
public Boolean apply(String input) {
return input.startsWith(getCompareTo());
}
}
private abstract static class CompareToFunction implements Function {
private final String compareTo;
public CompareToFunction(String compareTo) {
this.compareTo = compareTo;
}
public String getCompareTo() {
return compareTo;
}
@Override
public String toString() {
return getClass().getSimpleName() + '{' + compareTo + '}';
}
}
}
}