/****************************************************************************
* Copyright 2008-2011 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial Contributors:
* Håkan Råberg
* Manish Chakravarty
* Pavan K S
***************************************************************************/
package com.thoughtworks.krypton.driver.web.selenium.locator;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.thoughtworks.krypton.driver.web.browser.BrowserSession;
public class NameLocatorStrategy extends AttributeLocatorStrategy {
private List<Filter> filters = new ArrayList<Filter>();
public NameLocatorStrategy() {
super("name", "name");
filters.add(new NameFilter());
filters.add(new IndexFilter());
filters.add(new ValueFilter());
}
public Element locate(BrowserSession session, String locator) {
locator = locator.substring(prefix.length());
String[] locatorAndFilter = locator.split(" ");
List<Node> locateAll = session.locateAll("//*[@" + attribute + "='" + locatorAndFilter[0] + "']");
List<Node> matches = locateAll;
for (int i = 1; i < locatorAndFilter.length; i++) {
for (Filter filter : filters) {
if (filter.canFilter(locatorAndFilter[1])) {
matches = filter.matches(locateAll, locatorAndFilter[1]);
break;
}
}
}
if (!matches.isEmpty()) {
return (Element) matches.get(0);
}
return null;
}
private static class AttributeFilter implements Filter {
private String attribute;
private String prefix;
public AttributeFilter(String attribute) {
this.attribute = attribute;
this.prefix = attribute + "=";
}
public boolean canFilter(String filter) {
return filter.startsWith(prefix);
}
public List<Node> matches(List<Node> list, String filter) {
if (filter.startsWith(prefix)) {
filter = filter.substring(prefix.length());
}
List<Node> matching = new ArrayList<Node>();
for (Node node : list) {
if (filter.equals(((Element) node).getAttribute(attribute))) {
matching.add(node);
}
}
return matching;
}
}
private static class IndexFilter implements Filter {
private static final String PREFIX = "index=";
public boolean canFilter(String filter) {
return filter.startsWith(PREFIX);
}
public List<Node> matches(List<Node> list, String filter) {
int index = Integer.parseInt(filter.substring(PREFIX.length()));
List<Node> matching = new ArrayList<Node>();
matching.add(list.get(index));
return matching;
}
}
private final class NameFilter extends AttributeFilter {
public NameFilter() {
super("name");
}
}
private final class ValueFilter extends AttributeFilter {
public ValueFilter() {
super("value");
}
public boolean canFilter(String filter) {
return true;
}
}
private static interface Filter {
boolean canFilter(String filter);
List<Node> matches(List<Node> list, String filter);
}
}