Index: java/org/apache/ivy/event/IvyEventFilter.java =================================================================== --- java/org/apache/ivy/event/IvyEventFilter.java (revision 493699) +++ java/org/apache/ivy/event/IvyEventFilter.java (working copy) @@ -66,7 +66,7 @@ private Filter _attFilter; public IvyEventFilter(String event, String filterExpression, PatternMatcher matcher) { - _matcher = matcher == null ? ExactPatternMatcher.getInstance() : matcher; + _matcher = matcher == null ? ExactPatternMatcher.INSTANCE : matcher; if (event == null) { _nameFilter = NoFilter.INSTANCE; } else { Index: java/org/apache/ivy/external/m2/PomModuleDescriptorParser.java =================================================================== --- java/org/apache/ivy/external/m2/PomModuleDescriptorParser.java (revision 493699) +++ java/org/apache/ivy/external/m2/PomModuleDescriptorParser.java (working copy) @@ -162,7 +162,7 @@ ModuleId mid = (ModuleId)iter.next(); String[] confs = _dd.getModuleConfigurations(); for (int i = 0; i < confs.length; i++) { - _dd.addDependencyArtifactExcludes(confs[i], new DefaultDependencyArtifactDescriptor(_dd, new ArtifactId(mid, PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION), false, ExactPatternMatcher.getInstance())); + _dd.addDependencyArtifactExcludes(confs[i], new DefaultDependencyArtifactDescriptor(_dd, new ArtifactId(mid, PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION), false, ExactPatternMatcher.INSTANCE)); } } _md.addDependency(_dd); Index: java/org/apache/ivy/Ivy.java =================================================================== --- java/org/apache/ivy/Ivy.java (revision 493699) +++ java/org/apache/ivy/Ivy.java (working copy) @@ -243,10 +243,10 @@ addConflictManager("all", new NoConflictManager()); addConflictManager("strict", new StrictConflictManager()); - addMatcher(ExactPatternMatcher.getInstance()); - addMatcher(RegexpPatternMatcher.getInstance()); - addMatcher(ExactOrRegexpPatternMatcher.getInstance()); - addMatcher(GlobPatternMatcher.getInstance()); + addMatcher(ExactPatternMatcher.INSTANCE); + addMatcher(RegexpPatternMatcher.INSTANCE); + addMatcher(ExactOrRegexpPatternMatcher.INSTANCE); + addMatcher(GlobPatternMatcher.INSTANCE); addReportOutputter(new XmlReportOutputter()); addReportOutputter(new LogReportOutputter()); @@ -1767,7 +1767,7 @@ DefaultModuleDescriptor md = new DefaultModuleDescriptor(ModuleRevisionId.newInstance("apache", "ivy-install", "1.0"), getStatusManager().getDefaultStatus(), new Date()); md.addConfiguration(new Configuration("default")); - md.addConflictManager(new ModuleId(ExactPatternMatcher.ANY_EXPRESSION, ExactPatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.getInstance(), new NoConflictManager()); + md.addConflictManager(new ModuleId(ExactPatternMatcher.ANY_EXPRESSION, ExactPatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.INSTANCE, new NoConflictManager()); if (MatcherHelper.isExact(matcher, mrid)) { DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, mrid, false, false, transitive); Index: java/org/apache/ivy/matcher/AbstractPatternMatcher.java =================================================================== --- java/org/apache/ivy/matcher/AbstractPatternMatcher.java (revision 0) +++ java/org/apache/ivy/matcher/AbstractPatternMatcher.java (revision 0) @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + * + */ + +package org.apache.ivy.matcher; + +/** + * An abstract implementation of the pattern matcher providing base template methods + */ +public abstract class AbstractPatternMatcher implements PatternMatcher { + private final String name; + + /** + * Create a new instance of a pattern matcher + * + * @param name the name of the pattern matcher. Never null. + */ + public AbstractPatternMatcher(/*@NotNull*/ String name) { + this.name = name; + } + + public /*@NotNull*/ Matcher getMatcher(/*@NotNull*/String expression) { + if (expression == null) { + throw new NullPointerException(); + } + if (ANY_EXPRESSION.equals(expression)) { + return AnyMatcher.INSTANCE; + } + return newMatcher(expression); + } + + public /*@NotNull*/ String getName() { + return name; + } + + /** + * Returns an instance of the implementation specific matcher. + * + * @param expression the string to be matched. + * @return the instance of the related matcher. Never null. + */ + protected abstract /*@NotNull*/ Matcher newMatcher(/*@NotNull*/ String expression); + + public String toString() { + return getName(); + } +} + Property changes on: java\org\apache\ivy\matcher\AbstractPatternMatcher.java ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: java/org/apache/ivy/matcher/AnyMatcher.java =================================================================== --- java/org/apache/ivy/matcher/AnyMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/AnyMatcher.java (working copy) @@ -17,18 +17,19 @@ */ package org.apache.ivy.matcher; -public class AnyMatcher implements Matcher { - private final static Matcher INSTANCE = new AnyMatcher(); - - public static Matcher getInstance() { - return INSTANCE; +/** + * A matcher that will match everything. + */ +public /*@Immutable*/ class AnyMatcher implements Matcher { + public final static Matcher INSTANCE = new AnyMatcher(); + + public AnyMatcher() { } - - private AnyMatcher() { - - } - public boolean matches(String str) { + public boolean matches(String input) { + if (input == null) { + throw new NullPointerException(); + } return true; } Index: java/org/apache/ivy/matcher/ExactOrRegexpPatternMatcher.java =================================================================== --- java/org/apache/ivy/matcher/ExactOrRegexpPatternMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/ExactOrRegexpPatternMatcher.java (working copy) @@ -18,40 +18,45 @@ package org.apache.ivy.matcher; -public final class ExactOrRegexpPatternMatcher implements PatternMatcher { - public static class ExactOrRegexpMatcher implements Matcher { +/** + * A pattern matcher that tries to match exactly the input with the expression, or match it as a pattern. + *

+ * The evaluation for matching is perform first by checking if expression and input are equals (via equals method) + * else it attempts to do it by trying to match the input using the expression as a regexp. + * + * @see ExactPatternMatcher + * @see RegexpPatternMatcher + */ +public /*@Immutable*/ final class ExactOrRegexpPatternMatcher extends AbstractPatternMatcher { + + public static final ExactOrRegexpPatternMatcher INSTANCE = new ExactOrRegexpPatternMatcher(); + + public ExactOrRegexpPatternMatcher() { + super(EXACT_OR_REGEXP); + } + + protected Matcher newMatcher(String expression) { + return new ExactOrRegexpMatcher(expression); + } + + private static final class ExactOrRegexpMatcher implements Matcher { private Matcher _exact; private Matcher _regexp; - public ExactOrRegexpMatcher(String exp) { - _exact = ExactPatternMatcher.getInstance().getMatcher(exp); - _regexp = RegexpPatternMatcher.getInstance().getMatcher(exp); + public ExactOrRegexpMatcher(String expression) { + _exact = ExactPatternMatcher.INSTANCE.getMatcher(expression); + _regexp = RegexpPatternMatcher.INSTANCE.getMatcher(expression); } - public boolean matches(String str) { - return _exact.matches(str) || _regexp.matches(str); + public boolean matches(String input) { + if (input == null) { + throw new NullPointerException(); + } + return _exact.matches(input) || _regexp.matches(input); } public boolean isExact() { return false; } } - private static final ExactOrRegexpPatternMatcher INSTANCE = new ExactOrRegexpPatternMatcher(); - public static PatternMatcher getInstance() { - return INSTANCE; - } - - private ExactOrRegexpPatternMatcher() { - } - - public String getName() { - return EXACT_OR_REGEXP; - } - - public Matcher getMatcher(String exp) { - if (ANY_EXPRESSION.equals(exp)) { - return AnyMatcher.getInstance(); - } - return new ExactOrRegexpMatcher(exp); - } } Index: java/org/apache/ivy/matcher/ExactPatternMatcher.java =================================================================== --- java/org/apache/ivy/matcher/ExactPatternMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/ExactPatternMatcher.java (working copy) @@ -17,40 +17,40 @@ */ package org.apache.ivy.matcher; -public final class ExactPatternMatcher implements PatternMatcher { +/** + * Implementation of an exact matcher. + *

+ * The matching will be performed against an expression being a string. It will only + * matches if both strings are equal (per equals()) rule or if both strings are null. + */ +public /*@Immutable*/ final class ExactPatternMatcher extends AbstractPatternMatcher { - public static class ExactMatcher implements Matcher { - protected String _exp; + public static final ExactPatternMatcher INSTANCE = new ExactPatternMatcher(); - public ExactMatcher(String exp) { - _exp = exp; + public ExactPatternMatcher() { + super(EXACT); + } + + protected Matcher newMatcher(String expression) { + return new ExactMatcher(expression); + } + + private static /*@Immutable*/ class ExactMatcher implements Matcher { + protected String _expression; + + public ExactMatcher(String expression) { + _expression = expression; } - public boolean matches(String str) { - return str == null ? _exp == null : str.equals(_exp); + public boolean matches(String input) { + if (input == null) { + throw new NullPointerException(); + } + return input.equals(_expression); } public boolean isExact() { return true; } } - - private static final ExactPatternMatcher INSTANCE = new ExactPatternMatcher(); - public static PatternMatcher getInstance() { - return INSTANCE; - } - - private ExactPatternMatcher() { - } - - public String getName() { - return EXACT; - } - - public Matcher getMatcher(String exp) { - if (ANY_EXPRESSION.equals(exp)) { - return AnyMatcher.getInstance(); - } - return new ExactMatcher(exp); - } } Index: java/org/apache/ivy/matcher/GlobPatternMatcher.java =================================================================== --- java/org/apache/ivy/matcher/GlobPatternMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/GlobPatternMatcher.java (working copy) @@ -17,6 +17,8 @@ */ package org.apache.ivy.matcher; +import java.util.regex.PatternSyntaxException; + import org.apache.ivy.util.Message; import org.apache.oro.text.GlobCompiler; import org.apache.oro.text.regex.MalformedPatternException; @@ -25,42 +27,57 @@ -public final class GlobPatternMatcher implements PatternMatcher { - public static class GlobMatcher implements Matcher { - private Pattern _p; +/** + * A pattern matcher matching input using unix-like glob matcher expressions. Meta characters are: + *

+ *

+ * Note that this matcher is available only with + * in your classpath. + * + * @see GlobCompiler + */ +public /*@Immutable*/ final class GlobPatternMatcher extends AbstractPatternMatcher { - public GlobMatcher(String exp) { + public static final GlobPatternMatcher INSTANCE = new GlobPatternMatcher(); + + /* + NOTE: GlobCompiler does ~100K compilation/s + - If necessary look into using ThreadLocal for GlobCompiler/Perl5Matcher to cut on useless object creation + - If expression are reused over and over a LRU cache could make sense + */ + + public GlobPatternMatcher() { + super(GLOB); + } + + protected Matcher newMatcher(String expression) { + return new GlobMatcher(expression); + } + + private static class GlobMatcher implements Matcher { + private Pattern _pattern; + + public GlobMatcher(String expression) throws PatternSyntaxException { try { - _p = new GlobCompiler().compile(exp); + _pattern = new GlobCompiler().compile(expression); } catch (MalformedPatternException e) { - Message.error("impossible to compile glob pattern: "+exp); + throw new PatternSyntaxException(e.getMessage(), expression, 0); } } - public boolean matches(String str) { - return _p != null && new Perl5Matcher().matches(str, _p); + public boolean matches(String input) { + if (input == null) { + throw new NullPointerException(); + } + return new Perl5Matcher().matches(input, _pattern); } public boolean isExact() { return false; } } - private static final GlobPatternMatcher INSTANCE = new GlobPatternMatcher(); - public static PatternMatcher getInstance() { - return INSTANCE; - } - - private GlobPatternMatcher() { - } - public String getName() { - return GLOB; - } - - public Matcher getMatcher(String exp) { - if (ANY_EXPRESSION.equals(exp)) { - return AnyMatcher.getInstance(); - } - return new GlobMatcher(exp); - } } Index: java/org/apache/ivy/matcher/Matcher.java =================================================================== --- java/org/apache/ivy/matcher/Matcher.java (revision 493699) +++ java/org/apache/ivy/matcher/Matcher.java (working copy) @@ -17,7 +17,31 @@ */ package org.apache.ivy.matcher; +/** + * An interface that defines a string matcher. + */ public interface Matcher { - public boolean matches(String str); + + /** + * Check whether a given string is matched by this matcher. + * + * @param input the string to be matched. Cannot be null. + * @return true if the input string is matched, false otherwise. + */ + public boolean matches(/*@NotNull*/ String input); + + /** + * Return if the matcher will match *only* if the expression equals the input. + * + * WARN: + * This is used only as a performance trick, to avoid scanning for things + * when you already know exactly what you want. In the install task where + * it used it avoid scanning the repository to list all modules to find + * that only one matches, and that it has the name requested. + * + * + * @return true if the matcher only matches when the expression is + * equals to the input, false otherwise. + */ public boolean isExact(); } Index: java/org/apache/ivy/matcher/MatcherHelper.java =================================================================== --- java/org/apache/ivy/matcher/MatcherHelper.java (revision 493699) +++ java/org/apache/ivy/matcher/MatcherHelper.java (working copy) @@ -21,38 +21,47 @@ import org.apache.ivy.ModuleId; import org.apache.ivy.ModuleRevisionId; +/** + * Set of helper methods to match ModuleId, ModuleRevisionId, ArtifactId + */ public class MatcherHelper { - public static boolean matches(PatternMatcher m, String exp, String str) { - return m.getMatcher(exp).matches(str); + // TODO this class might be better off as MatcherUtils in util package + + public static boolean matches(PatternMatcher m, String expression, String input) { + return m.getMatcher(expression).matches(input); } + public static boolean matches(PatternMatcher m, ModuleId exp, ModuleId mid) { return matches(m, exp.getOrganisation(), mid.getOrganisation()) - && matches(m, exp.getName(), mid.getName()); + && matches(m, exp.getName(), mid.getName()); } - + public static boolean matches(PatternMatcher m, ModuleRevisionId exp, ModuleRevisionId mrid) { return matches(m, exp.getOrganisation(), mrid.getOrganisation()) - && matches(m, exp.getName(), mrid.getName()) - && matches(m, exp.getRevision(), mrid.getRevision()); + && matches(m, exp.getName(), mrid.getName()) + && matches(m, exp.getRevision(), mrid.getRevision()); } + public static boolean matches(PatternMatcher m, ArtifactId exp, ArtifactId aid) { - return matches(m, exp.getModuleId().getOrganisation(), aid.getModuleId().getOrganisation()) - && matches(m, exp.getModuleId().getName(), aid.getModuleId().getName()) - && matches(m, exp.getName(), aid.getName()) - && matches(m, exp.getExt(), aid.getExt()) - && matches(m, exp.getType(), aid.getType()) - ; + return matches(m, exp.getModuleId(), aid.getModuleId()) + && matches(m, exp.getName(), aid.getName()) + && matches(m, exp.getExt(), aid.getExt()) + && matches(m, exp.getType(), aid.getType()) + ; } - + public static boolean isExact(PatternMatcher m, ModuleRevisionId exp) { return isExact(m, exp.getOrganisation()) - && isExact(m, exp.getName()) - && isExact(m, exp.getRevision()); + && isExact(m, exp.getName()) + && isExact(m, exp.getRevision()); } + + // unused public static boolean isExact(PatternMatcher m, ModuleId exp) { return isExact(m, exp.getOrganisation()) - && isExact(m, exp.getName()); + && isExact(m, exp.getName()); } + public static boolean isExact(PatternMatcher m, String exp) { return m.getMatcher(exp).isExact(); } Index: java/org/apache/ivy/matcher/ModuleIdMatcher.java =================================================================== --- java/org/apache/ivy/matcher/ModuleIdMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/ModuleIdMatcher.java (working copy) @@ -20,6 +20,7 @@ import org.apache.ivy.ModuleId; public class ModuleIdMatcher { +// TODO this class should be moved out of this package private Matcher _orgMatcher; private Matcher _moduleMatcher; private ModuleId _mid; Index: java/org/apache/ivy/matcher/NoMatcher.java =================================================================== --- java/org/apache/ivy/matcher/NoMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/NoMatcher.java (working copy) @@ -17,17 +17,20 @@ */ package org.apache.ivy.matcher; -public class NoMatcher implements Matcher { - private final static Matcher INSTANCE = new NoMatcher(); - - public static Matcher getInstance() { - return INSTANCE; +/** + * A matcher that matches nothing. + */ +public final /*@Immutable*/ class NoMatcher implements Matcher { + + public final static Matcher INSTANCE = new NoMatcher(); + + public NoMatcher() { } - - private NoMatcher() { - } - public boolean matches(String str) { + public boolean matches(String input) { + if (input == null) { + throw new NullPointerException(); + } return false; } Index: java/org/apache/ivy/matcher/PatternMatcher.java =================================================================== --- java/org/apache/ivy/matcher/PatternMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/PatternMatcher.java (working copy) @@ -17,15 +17,56 @@ */ package org.apache.ivy.matcher; +/** + * Interface for a pattern matcher. + *

+ * The pattern matcher is the main abstraction regarding the matching of an expression. Implementation may vary + * depending on the expression syntax handling that is desired. + */ +public interface PatternMatcher { -public interface PatternMatcher { + /** + * 'exact' pattern matcher name + */ public static final String EXACT = "exact"; + + /** + * pattern matcher name 'regexp' + */ public static final String REGEXP = "regexp"; + + /** + * pattern matcher 'glob' + */ public static final String GLOB = "glob"; + + /** + * pattern matcher name 'exactOrRegexp' + */ public static final String EXACT_OR_REGEXP = "exactOrRegexp"; - + + /** + * Any expression string: '*' + */ public static final String ANY_EXPRESSION = "*"; - public Matcher getMatcher(String exp); - public String getName(); + /** + * Return the matcher for the given expression. + * + * @param expression the expression to be matched. Cannot be null ? + * @return the matcher instance for the given expression. Never null. + */ + public /*@NotNull*/ Matcher getMatcher(/*@NotNull*/ String expression); + + /** + * return the name of this pattern matcher + * + * @return the name of this pattern matcher. Never null. + * @see #EXACT + * @see #REGEXP + * @see #GLOB + * @see #EXACT_OR_REGEXP + */ + public /*@NotNull*/ String getName(); } + Index: java/org/apache/ivy/matcher/RegexpPatternMatcher.java =================================================================== --- java/org/apache/ivy/matcher/RegexpPatternMatcher.java (revision 493699) +++ java/org/apache/ivy/matcher/RegexpPatternMatcher.java (working copy) @@ -18,46 +18,50 @@ package org.apache.ivy.matcher; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; -public final class RegexpPatternMatcher implements PatternMatcher { - public static class RegexpMatcher implements Matcher { - private Pattern _p; +/** + * A pattern matcher matching input using regular expressions. + * + * @see Pattern + */ +public final /*@Immutable*/ class RegexpPatternMatcher extends AbstractPatternMatcher { + public static final RegexpPatternMatcher INSTANCE = new RegexpPatternMatcher(); - public RegexpMatcher(String exp) { - _p = Pattern.compile(exp); - } + /* + NOTE: Regexp compiler does ~200K compilation/s + - If necessary look into using ThreadLocal Pattern to cut on useless object creation + - If expression are reused over and over a LRU cache could make sense + */ - public boolean matches(String str) { - return _p.matcher(str).matches(); - } - public boolean isExact() { - return false; - } + public RegexpPatternMatcher() { + super(REGEXP); } - private static final RegexpPatternMatcher INSTANCE = new RegexpPatternMatcher(); - public static PatternMatcher getInstance() { - return INSTANCE; + + protected Matcher newMatcher(String expression) { + return new RegexpMatcher(expression); } - - private RegexpPatternMatcher() { - } - - public boolean match(String str, String exp) { - if (exp == null) { - return str == null; + + private static /*@Immutable*/ class RegexpMatcher implements Matcher { + private Pattern _pattern; + + public RegexpMatcher(String expression) throws PatternSyntaxException { + if (expression == null) { + throw new NullPointerException(); + } + _pattern = Pattern.compile(expression); } - return Pattern.matches(exp, str); - } - public String getName() { - return REGEXP; - } + public boolean matches(String input) { + if (input == null) { + throw new NullPointerException(); + } + return _pattern.matcher(input).matches(); + } - public Matcher getMatcher(String exp) { - if (ANY_EXPRESSION.equals(exp)) { - return AnyMatcher.getInstance(); + public boolean isExact() { + return false; } - return new RegexpMatcher(exp); } } Index: java/org/apache/ivy/resolver/AbstractResolver.java =================================================================== --- java/org/apache/ivy/resolver/AbstractResolver.java (revision 493699) +++ java/org/apache/ivy/resolver/AbstractResolver.java (working copy) @@ -294,7 +294,7 @@ public Matcher getChangingMatcher() { if (_changingPattern == null) { - return NoMatcher.getInstance(); + return NoMatcher.INSTANCE; } PatternMatcher matcher = _ivy.getMatcher(_changingMatcherName); if (matcher == null) {