/** * Compile the supplied expression and return the resulting path expression instance. * * @param expression the expression * @return the path expression; never null * @throws IllegalArgumentException if the expression is null * @throws InvalidPathExpressionException if the expression is blank or is not a valid expression */ public static final PathExpression compile( String expression ) throws InvalidPathExpressionException { return new PathExpression(expression); }
@Override public SequencerDefinition<ReturnType> andOutputtingTo( String into ) { CheckArg.isNotEmpty(into, "into"); return sequencingFrom(PathExpression.compile(fromPathExpression + " => " + into)); } };
/** * @return selectExpression */ public String getSelectExpression() { return this.selectExpression.getSelectExpression(); }
@Test public void shouldDetermineIfPatternMatchesAnything() { assertThat(PathExpression.compile("/.").matchesAnything(), is(true)); assertThat(PathExpression.compile("//").matchesAnything(), is(true)); assertThat(PathExpression.compile("///").matchesAnything(), is(true)); assertThat(PathExpression.compile("///").matchesAnything(), is(true)); assertThat(PathExpression.compile("/*").matchesAnything(), is(true)); assertThat(PathExpression.compile("*").matchesAnything(), is(true)); assertThat(PathExpression.compile("*[*]").matchesAnything(), is(true)); assertThat(PathExpression.compile("*[]").matchesAnything(), is(true)); assertThat(PathExpression.compile("/a").matchesAnything(), is(false)); assertThat(PathExpression.compile("/*[3]").matchesAnything(), is(false)); assertThat(PathExpression.compile("/a/b/c").matchesAnything(), is(false)); }
RepositoryPath repoPath = parseRepositoryPath(this.expression); if (repoPath == null) { throw new InvalidPathExpressionException(GraphI18n.pathExpressionHasInvalidMatch.text(this.expression, matchString = removeUnusedPredicates(matchString); matchString = replaceXPathPatterns(matchString); this.matchPattern = Pattern.compile(matchString, Pattern.CASE_INSENSITIVE); } catch (PatternSyntaxException e) { selectString = removeAllPredicatesExceptIndexes(selectString); selectString = replaceXPathPatterns(selectString); selectString = "(" + selectString + ").*"; // group 1 will have selected path ... this.selectPattern = Pattern.compile(selectString, Pattern.CASE_INSENSITIVE);
@Test public void shouldCompileExpressionWithAnyNode() { expr = PathExpression.compile("/*"); assertThat(expr.getSelectExpression(), is("/*")); assertThat(expr.matcher("/a").matches(), is(true)); assertThat(expr.matcher("/a").getInputPath(), is("/a")); assertThat(expr.matcher("/a").getSelectedNodePath(), is("/a")); assertThat(expr.matcher("/a").groupCount(), is(0)); }
PathExpression.Matcher inputMatcher = selectExpression.matcher(absolutePath); String outputPath = null; RepositoryPath repoPath = null; repoPath = PathExpression.parseRepositoryPath(this.outputExpression); if (repoPath != null) { if (repoPath.repositoryName == null) repoPath = repoPath.withRepositoryName(inputMatcher.getSelectedRepositoryName());
@Test public void shouldCompileExpressionWithExtraWhitespace() { expr = PathExpression.compile(" /a/b/c "); assertThat(expr, is(notNullValue())); assertThat(expr.getSelectExpression(), is("/a/b/c")); expr = PathExpression.compile(" /a/b/c "); assertThat(expr, is(notNullValue())); assertThat(expr.getSelectExpression(), is("/a/b/c")); }
for (String expressionString : expressionStrings) { try { pathExpressions.add(PathExpression.compile(expressionString)); } catch (Throwable t) { problems.addError(t, for (int i = 0; i != pathExpressions.size(); ++i) { PathExpression expression = pathExpressions.get(i); goodExpressionStrings[i] = expression.getExpression();
@Test public void shouldRemoveUnusedPredicates() { assertThat(expr.removeUnusedPredicates("/a/b[-1]/c"), is("/a/b/c")); assertThat(expr.removeUnusedPredicates("/a/b[@name='wacky']/c"), is("/a/b/c")); assertThat(expr.removeUnusedPredicates("/a/b[3][@name='wacky']/c"), is("/a/b[3]/c")); assertThat(expr.removeUnusedPredicates("/a/b[3][@name]/c"), is("/a/b[3]/c")); assertThat(expr.removeUnusedPredicates("/a/b[length(@name)=3]/c"), is("/a/b/c")); }
RepositoryPath repoPath = parseRepositoryPath(absolutePath); if (repoPath == null) {
@Test public void shouldRemoveAllPredicates() { assertThat(expr.removeAllPredicatesExceptIndexes("/a/b/c"), is("/a/b/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[0]/c"), is("/a/b[0]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[1]/c"), is("/a/b[1]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[10]/c"), is("/a/b[10]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[100]/c"), is("/a/b[100]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[1000]/c"), is("/a/b[1000]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[]/c"), is("/a/b[]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[*]/c"), is("/a/b[*]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b/c[@title]"), is("/a/b/c")); // These are legal, but aren't really useful ... assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[1][2][3]/c"), is("/a/b[1][2][3]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[-1]/c"), is("/a/b/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[@name='wacky']/c"), is("/a/b/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[3][@name='wacky']/c"), is("/a/b[3]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[3][@name]/c"), is("/a/b[3]/c")); assertThat(expr.removeAllPredicatesExceptIndexes("/a/b[length(@name)=3]/c"), is("/a/b/c")); }
@Test public void shouldReplaceAllXPathPatterns() { assertThat(expr.replaceXPathPatterns("/a/b[3]/c"), is("/a/b\\[3\\]/c")); assertThat(expr.replaceXPathPatterns("/a/b[*]/c"), is("/a/b(?:\\[\\d+\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[]/c"), is("/a/b(?:\\[\\d+\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[0]/c"), is("/a/b(?:\\[0\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[0,1,2,4]/c"), is("/a/b(?:\\[(?:1|2|4)\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[1,2,4,0]/c"), is("/a/b(?:\\[(?:1|2|4)\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[1,2,0,4]/c"), is("/a/b(?:\\[(?:1|2|4)\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[0,1,2,0,4,0]/c"), is("/a/b(?:\\[(?:1|2|4)\\])?/c")); assertThat(expr.replaceXPathPatterns("/a/b[1,2,4]/c"), is("/a/b\\[(?:1|2|4)\\]/c")); assertThat(expr.replaceXPathPatterns("/a/b[@param]"), is("/a/b/@param")); assertThat(expr.replaceXPathPatterns("/a/b[3][@param]"), is("/a/b\\[3\\]/@param")); assertThat(expr.replaceXPathPatterns("/a/b[c/d/@param]"), is("/a/b/c/d/@param")); assertThat(expr.replaceXPathPatterns("/a/(b|c|d)/e"), is("/a/(b|c|d)/e")); assertThat(expr.replaceXPathPatterns("/a/(b||c|d)/e"), is("/a/(b|c|d)/e")); assertThat(expr.replaceXPathPatterns("/a/(b|||c|d)/e"), is("/a/(b|c|d)/e")); assertThat(expr.replaceXPathPatterns("/a/(|b|c|d)/e"), is("/a(?:/(b|c|d))?/e")); assertThat(expr.replaceXPathPatterns("/a/(b|c|d|)/e"), is("/a(?:/(b|c|d))?/e")); assertThat(expr.replaceXPathPatterns("/a/(b|c|d)[]/e"), is("/a/(b|c|d)(?:\\[\\d+\\])?/e")); assertThat(expr.replaceXPathPatterns("/a/(b|c[2]|d[])/e"), is("/a/(b|c\\[2\\]|d(?:\\[\\d+\\])?)/e")); assertThat(expr.replaceXPathPatterns("/a/(b|c/d|e)/f"), is("/a/(b|c/d|e)/f")); assertThat(expr.replaceXPathPatterns("/a/(b/c)[(d|e)/(f|g)/@something]"), is("/a/(b/c)/(d|e)/(f|g)/@something")); assertThat(expr.replaceXPathPatterns("/a/*/f"), is("/a/[^/]*/f")); assertThat(expr.replaceXPathPatterns("/a//f"), is("/a(?:/[^/]*)*/f")); assertThat(expr.replaceXPathPatterns("/a///f"), is("/a(?:/[^/]*)*/f")); assertThat(expr.replaceXPathPatterns("/a/////f"), is("/a(?:/[^/]*)*/f"));
/** * {@inheritDoc} */ @Override public boolean equals( Object obj ) { if (obj == this) return true; if (obj instanceof SequencerPathExpression) { SequencerPathExpression that = (SequencerPathExpression)obj; if (!this.selectExpression.equals(that.selectExpression)) return false; if (!this.outputExpression.equalsIgnoreCase(that.outputExpression)) return false; return true; } return false; }
@Test public void shouldCompileExpressionWithAnySequenceOfNodes() { expr = PathExpression.compile("//"); assertThat(expr.getSelectExpression(), is("//")); assertThat(expr.matcher("/a").matches(), is(true)); assertThat(expr.matcher("/a").getInputPath(), is("/a")); assertThat(expr.matcher("/a").getSelectedNodePath(), is("/a")); assertThat(expr.matcher("/a").groupCount(), is(0)); assertThat(expr.matcher("/a/b").matches(), is(true)); assertThat(expr.matcher("/a/b").getInputPath(), is("/a/b")); assertThat(expr.matcher("/a/b").getSelectedNodePath(), is("/a/b")); assertThat(expr.matcher("/a/b").groupCount(), is(0)); assertThat(expr.matcher("/a/b/c").matches(), is(true)); assertThat(expr.matcher("/a/b/c").getInputPath(), is("/a/b/c")); assertThat(expr.matcher("/a/b/c").getSelectedNodePath(), is("/a/b/c")); assertThat(expr.matcher("/a/b/c").groupCount(), is(0)); }
@Test public void shouldNotRemoveUsedPredicates() { assertThat(expr.removeUnusedPredicates("/a/b/c"), is("/a/b/c")); assertThat(expr.removeUnusedPredicates("/a/b[0]/c"), is("/a/b[0]/c")); assertThat(expr.removeUnusedPredicates("/a/b[1]/c"), is("/a/b[1]/c")); assertThat(expr.removeUnusedPredicates("/a/b[10]/c"), is("/a/b[10]/c")); assertThat(expr.removeUnusedPredicates("/a/b[100]/c"), is("/a/b[100]/c")); assertThat(expr.removeUnusedPredicates("/a/b[1000]/c"), is("/a/b[1000]/c")); assertThat(expr.removeUnusedPredicates("/a/b[]/c"), is("/a/b[]/c")); assertThat(expr.removeUnusedPredicates("/a/b[*]/c"), is("/a/b[*]/c")); assertThat(expr.removeUnusedPredicates("/a/b[1,2]/c"), is("/a/b[1,2]/c")); assertThat(expr.removeUnusedPredicates("/a/b[1,2,3,4,5]/c"), is("/a/b[1,2,3,4,5]/c")); assertThat(expr.removeUnusedPredicates("/a/b/c[@title]"), is("/a/b/c[@title]")); assertThat(expr.removeUnusedPredicates("/a/b/c[d/e/@title]"), is("/a/b/c[d/e/@title]")); assertThat(expr.removeUnusedPredicates("/a/(b/c)[(d|e)/(f|g)/@something]"), is("/a/(b/c)[(d|e)/(f|g)/@something]")); assertThat(expr.removeUnusedPredicates("/*"), is("/*")); assertThat(expr.removeUnusedPredicates("/*[]"), is("/*[]")); assertThat(expr.removeUnusedPredicates("/*[3]"), is("/*[3]")); // These are legal, but aren't really useful ... assertThat(expr.removeUnusedPredicates("/a/b[1][2][3]/c"), is("/a/b[1][2][3]/c")); }
@Test public void shouldMatchExpressionsWithExactFullPathAndExtraPathInsideMatch() { expr = PathExpression.compile("/a/b/c[d/e/@something]"); assertThat(expr.matcher("/a/b/c/d/e/@something").matches(), is(true)); assertThat(expr.matcher("/a/b/c/d/e/@something").getInputPath(), is("/a/b/c/d/e/@something")); assertThat(expr.matcher("/a/b/c/d/e/@something").getSelectedNodePath(), is("/a/b/c")); assertThat(expr.matcher("/a/b/c/d/e/@something").groupCount(), is(0)); assertThat(expr.matcher("/a/b/c/d/E/@something2").matches(), is(false)); assertThat(expr.matcher("/a/b/c/d/ex/@something").matches(), is(false)); assertThat(expr.matcher("/a/b[1]/c/d/e/@something").matches(), is(false)); }
@Test( expected = IllegalArgumentException.class ) public void shouldNotCompileNullExpression() { PathExpression.compile(null); }