package com.crawljax.condition.eventablecondition; import java.util.List; import javax.inject.Inject; import javax.xml.xpath.XPathExpressionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import com.crawljax.core.CrawljaxException; import com.crawljax.core.configuration.CrawlElement; import com.crawljax.core.configuration.CrawlRules; import com.crawljax.util.XPathHelper; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; /** * Check whether the conditions of an eventable are satisfied. */ public class EventableConditionChecker { private static final Logger LOG = LoggerFactory.getLogger(EventableConditionChecker.class); private final ImmutableList<EventableCondition> eventableConditions; @Inject public EventableConditionChecker(CrawlRules config) { Builder<EventableCondition> builder = ImmutableList.builder(); for (CrawlElement crawlTag : config.getAllCrawlElements()) { EventableCondition eventableCondition = crawlTag.getEventableCondition(); if (eventableCondition != null) { builder.add(eventableCondition); } } this.eventableConditions = builder.build(); LOG.debug("Evenetable conditions {}", eventableConditions); } /** * @param id * Identifier of the {@link EventableCondition}. * @return EventableCondition or <code>null</code> */ public EventableCondition getEventableCondition(String id) { if (!Strings.isNullOrEmpty(id)) { for (EventableCondition eventableCondition : eventableConditions) { if (eventableCondition.getId().equalsIgnoreCase(id)) { return eventableCondition; } } } return null; } /** * Checks whether an XPath expression starts with an XPath eventable condition. * * @param dom * The DOM String. * @param eventableCondition * The eventable condition. * @param xpath * The XPath. * @return boolean whether xpath starts with xpath location of eventable condition xpath * condition * @throws XPathExpressionException * @throws CrawljaxException * when not can be determined whether xpath contains needed xpath locaton */ public boolean checkXpathStartsWithXpathEventableCondition(Document dom, EventableCondition eventableCondition, String xpath) throws XPathExpressionException { if (eventableCondition == null || Strings.isNullOrEmpty(eventableCondition.getInXPath())) { throw new CrawljaxException("Eventable has no XPath condition"); } List<String> expressions = XPathHelper.getXpathForXPathExpressions(dom, eventableCondition.getInXPath()); return checkXPathUnderXPaths(xpath, expressions); } /** * @param xpath * the xpath to check if its under a certain set of full-xPaths. * @param xpathsList * the set of full-length-xPaths * @return true if the xpath is under one of the full-length-xpaths. */ public boolean checkXPathUnderXPaths(String xpath, List<String> xpathsList) { /* check all expressions */ for (String fullXpath : xpathsList) { if (xpath.startsWith(fullXpath)) { LOG.trace("{} IS under xpath {}", xpath, fullXpath); return true; } LOG.trace("{} is not under xpath {}", xpath, fullXpath); } return false; } }