package org.nate.internal.dom4j.cssselectors.internal; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.dom4j.Attribute; import org.dom4j.Element; import org.dom4j.Branch; import se.fishtank.css.selectors.NodeSelectorException; import se.fishtank.css.selectors.specifier.AttributeSpecifier; import se.fishtank.css.util.Assert; /** * Simple port of Christer Sandberg's CSS selectors to Dom4j (https://github.com/chrsan/css-selectors) */ public class AttributeSpecifierChecker implements NodeTraversalChecker { private final AttributeSpecifier specifier; public AttributeSpecifierChecker(AttributeSpecifier specifier) { Assert.notNull(specifier, "specifier is null!"); this.specifier = specifier; } @Override public Set<Branch> check(Set<Branch> nodes) throws NodeSelectorException { Assert.notNull(nodes, "nodes is null!"); Set<Branch> result = new LinkedHashSet<Branch>(); for (Branch node : nodes) { if (!(node instanceof Element)) { continue; } List<Attribute> attributes = ((Element) node).attributes(); Attribute attr = findAttribute(attributes, specifier.getName()); if (attr == null) { continue; } // It just have to be present. if (specifier.getValue() == null) { result.add(node); continue; } String value = attr.getValue().trim(); if (value.length() != 0) { String val = specifier.getValue(); switch (specifier.getMatch()) { case EXACT: if (value.equals(val)) { result.add(node); } break; case HYPHEN: if (value.equals(val) || value.startsWith(val + '-')) { result.add(node); } break; case PREFIX: if (value.startsWith(val)) { result.add(node); } break; case SUFFIX: if (value.endsWith(val)) { result.add(node); } break; case CONTAINS: if (value.contains(val)) { result.add(node); } break; case LIST: for (String v : value.split("\\s+")) { if (v.equals(val)) { result.add(node); } } break; } } } return result; } private Attribute findAttribute(List<Attribute> attributes, String name) { for (Attribute attribute : attributes) { if (attribute.getName().equals(name)) { return attribute; } } return null; } }