001/*-----------------------------------------------------------------------+ 002 | com.teamscale.checks 003 | | 004 $Id$ 005 | | 006 | Copyright (c) 2009-2015 CQSE GmbH | 007 +-----------------------------------------------------------------------*/ 008package eu.cqse.check.framework.core.xpath; 009 010import java.util.HashMap; 011import java.util.Map; 012import java.util.Map.Entry; 013 014import org.conqat.lib.commons.string.StringUtils; 015import org.jaxen.BaseXPath; 016import org.jaxen.Function; 017import org.jaxen.JaxenException; 018import org.jaxen.SimpleFunctionContext; 019 020import eu.cqse.check.framework.core.CheckException; 021import eu.cqse.check.framework.core.xpath.functions.AllModifiersSelectionFunction; 022import eu.cqse.check.framework.core.xpath.functions.AllTokensSelectionFunction; 023import eu.cqse.check.framework.core.xpath.functions.AnyModifierSelectionFunction; 024import eu.cqse.check.framework.core.xpath.functions.AnyTokenSelectionFunction; 025import eu.cqse.check.framework.core.xpath.functions.NameMatchesFunction; 026import eu.cqse.check.framework.core.xpath.functions.SubTypeSelectionFunction; 027import eu.cqse.check.framework.core.xpath.functions.TokenSequenceFunction; 028import eu.cqse.check.framework.core.xpath.functions.TypeSelectionFunction; 029 030/** 031 * Utilities for handling of xPath. 032 */ 033public class CheckXPathUtils { 034 035 /** Mapping from function names to functions. */ 036 private static final Map<String, Function> NAME_TO_FUNCTION_MAP = new HashMap<>(); 037 038 /** Used to cache the created xPaths to avoid parsing it multiple times */ 039 private static final Map<String, BaseXPath> XPATH_CACHE = new HashMap<>(); 040 041 static { 042 NAME_TO_FUNCTION_MAP.put(TypeSelectionFunction.NAME, new TypeSelectionFunction()); 043 NAME_TO_FUNCTION_MAP.put(SubTypeSelectionFunction.NAME, new SubTypeSelectionFunction()); 044 NAME_TO_FUNCTION_MAP.put(NameMatchesFunction.NAME, new NameMatchesFunction()); 045 NAME_TO_FUNCTION_MAP.put(AllModifiersSelectionFunction.NAME, new AllModifiersSelectionFunction()); 046 NAME_TO_FUNCTION_MAP.put(AnyModifierSelectionFunction.NAME, new AnyModifierSelectionFunction()); 047 NAME_TO_FUNCTION_MAP.put(AllTokensSelectionFunction.NAME, new AllTokensSelectionFunction()); 048 NAME_TO_FUNCTION_MAP.put(AnyTokenSelectionFunction.NAME, new AnyTokenSelectionFunction()); 049 NAME_TO_FUNCTION_MAP.put(TokenSequenceFunction.NAME, new TokenSequenceFunction()); 050 } 051 052 /** Return the xPath object for the given xPath. */ 053 public static BaseXPath getXPath(String xPath) throws CheckException { 054 if (XPATH_CACHE.containsKey(xPath)) { 055 return XPATH_CACHE.get(xPath); 056 } 057 BaseXPath path; 058 try { 059 path = new BaseXPath(xPath, new ShallowEntityNavigator()); 060 } catch (JaxenException e) { 061 throw new CheckException("Error compiling xpath: " + e.getMessage(), e); 062 } 063 SimpleFunctionContext context = (SimpleFunctionContext) path.getFunctionContext(); 064 for (Entry<String, Function> entry : NAME_TO_FUNCTION_MAP.entrySet()) { 065 context.registerFunction(StringUtils.EMPTY_STRING, entry.getKey(), entry.getValue()); 066 } 067 XPATH_CACHE.put(xPath, path); 068 return path; 069 } 070}