michael-o commented on a change in pull request #15:
URL: 
https://github.com/apache/maven-common-artifact-filters/pull/15#discussion_r563674915



##########
File path: 
src/main/java/org/apache/maven/shared/artifact/filter/PatternIncludesArtifactFilter.java
##########
@@ -107,322 +147,829 @@ public boolean include( final Artifact artifact )
      */
     protected boolean patternMatches( final Artifact artifact )
     {
-        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+        // Check if the main artifact matches
+        char[][] artifactGatvCharArray = new char[][] {
+                            emptyOrChars( artifact.getGroupId() ),
+                            emptyOrChars( artifact.getArtifactId() ),
+                            emptyOrChars( artifact.getType() ),
+                            emptyOrChars( artifact.getBaseVersion() )
+                    };
+        Boolean match = match( artifactGatvCharArray );
+        if ( match != null )
+        {
+            return match;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    char[][] depGatvCharArray = tokenizeAndSplit( trailItem );
+                    match = match( depGatvCharArray );
+                    if ( match != null)
+                    {
+                        return match;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private Boolean match( char[][] gatvCharArray )
+    {
+        if ( simplePatterns != null && simplePatterns.size() > 0 )
+        {
+            // We add the parts one by one to the builder
+            StringBuilder sb = new StringBuilder();
+            for ( int i = 0; i < 4; i++ )
+            {
+                if ( i > 0 )
+                {
+                    sb.append( ":" );
+                }
+                sb.append( gatvCharArray[i] );
+                Map<String, Pattern> map = simplePatterns.get( i );
+                if ( map != null )
+                {
+                    // Check if one of the pattern matches
+                    Pattern p = map.get( sb.toString() );
+                    if ( p != null )
+                    {
+                        patternsTriggered.add( p );
+                        return true;
+                    }
+                }
+            }
+        }
+        // Check all other patterns
+        for ( Pattern pattern : patterns )
+        {
+            if ( pattern.matches( gatvCharArray ) )
+            {
+                patternsTriggered.add( pattern );
+                return !(pattern instanceof NegativePattern);
+            }
+        }
+
+        return null;
     }
 
     /**
-     * @param artifactId add artifact to the filtered artifacts list.
+     * @param artifact add artifact to the filtered artifacts list.
      */
-    protected void addFilteredArtifactId( final String artifactId )
+    protected void addFilteredArtifactId( final Artifact artifact )
     {
-        filteredArtifactIds.add( artifactId );
+        filteredArtifact.add( artifact );
     }
 
-    private Boolean negativeMatch( final Artifact artifact )
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
     {
-        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        // if there are no patterns, there is nothing to report.
+        if ( !patterns.isEmpty() )
         {
-            return null;
+            final List<Pattern> missed = new ArrayList<>( patterns );
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( Pattern pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );
+                }
+
+                buffer.append( "\n" );
+
+                logger.warn( buffer.toString() );
+            }
         }
-        else
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Includes filter:" + getPatternsAsString();
+    }
+
+    /**
+     * @return pattern as a string.
+     */
+    protected String getPatternsAsString()
+    {
+        final StringBuilder buffer = new StringBuilder();
+        for ( Pattern pattern : patterns )
         {
-            return match( artifact, negativePatterns );
+            buffer.append( "\no '" ).append( pattern ).append( "'" );

Review comment:
       This should be the system line separator.

##########
File path: 
src/main/java/org/apache/maven/shared/artifact/filter/PatternIncludesArtifactFilter.java
##########
@@ -107,322 +147,829 @@ public boolean include( final Artifact artifact )
      */
     protected boolean patternMatches( final Artifact artifact )
     {
-        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+        // Check if the main artifact matches
+        char[][] artifactGatvCharArray = new char[][] {
+                            emptyOrChars( artifact.getGroupId() ),
+                            emptyOrChars( artifact.getArtifactId() ),
+                            emptyOrChars( artifact.getType() ),
+                            emptyOrChars( artifact.getBaseVersion() )
+                    };
+        Boolean match = match( artifactGatvCharArray );
+        if ( match != null )
+        {
+            return match;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    char[][] depGatvCharArray = tokenizeAndSplit( trailItem );
+                    match = match( depGatvCharArray );
+                    if ( match != null)
+                    {
+                        return match;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private Boolean match( char[][] gatvCharArray )
+    {
+        if ( simplePatterns != null && simplePatterns.size() > 0 )
+        {
+            // We add the parts one by one to the builder
+            StringBuilder sb = new StringBuilder();
+            for ( int i = 0; i < 4; i++ )
+            {
+                if ( i > 0 )
+                {
+                    sb.append( ":" );
+                }
+                sb.append( gatvCharArray[i] );
+                Map<String, Pattern> map = simplePatterns.get( i );
+                if ( map != null )
+                {
+                    // Check if one of the pattern matches
+                    Pattern p = map.get( sb.toString() );
+                    if ( p != null )
+                    {
+                        patternsTriggered.add( p );
+                        return true;
+                    }
+                }
+            }
+        }
+        // Check all other patterns
+        for ( Pattern pattern : patterns )
+        {
+            if ( pattern.matches( gatvCharArray ) )
+            {
+                patternsTriggered.add( pattern );
+                return !(pattern instanceof NegativePattern);
+            }
+        }
+
+        return null;
     }
 
     /**
-     * @param artifactId add artifact to the filtered artifacts list.
+     * @param artifact add artifact to the filtered artifacts list.
      */
-    protected void addFilteredArtifactId( final String artifactId )
+    protected void addFilteredArtifactId( final Artifact artifact )
     {
-        filteredArtifactIds.add( artifactId );
+        filteredArtifact.add( artifact );
     }
 
-    private Boolean negativeMatch( final Artifact artifact )
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
     {
-        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        // if there are no patterns, there is nothing to report.
+        if ( !patterns.isEmpty() )
         {
-            return null;
+            final List<Pattern> missed = new ArrayList<>( patterns );
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( Pattern pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );
+                }
+
+                buffer.append( "\n" );
+
+                logger.warn( buffer.toString() );
+            }
         }
-        else
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Includes filter:" + getPatternsAsString();
+    }
+
+    /**
+     * @return pattern as a string.
+     */
+    protected String getPatternsAsString()
+    {
+        final StringBuilder buffer = new StringBuilder();
+        for ( Pattern pattern : patterns )
         {
-            return match( artifact, negativePatterns );
+            buffer.append( "\no '" ).append( pattern ).append( "'" );
         }
+
+        return buffer.toString();
     }
 
     /**
-     * @param artifact check for positive match.
-     * @return true/false.
+     * @return description.
      */
-    protected Boolean positiveMatch( final Artifact artifact )
+    protected String getFilterDescription()
+    {
+        return "artifact inclusion filter";
+    }
+
+    /** {@inheritDoc} */
+    public void reportFilteredArtifacts( final Logger logger )
     {
-        if ( positivePatterns == null || positivePatterns.isEmpty() )
+        if ( !filteredArtifact.isEmpty() && logger.isDebugEnabled() )
         {
-            return null;
+            final StringBuilder buffer =
+                new StringBuilder( "The following artifacts were removed by 
this " + getFilterDescription() + ": " );
+
+            for ( Artifact artifactId : filteredArtifact )
+            {
+                buffer.append( '\n' ).append( artifactId.getId() );

Review comment:
       Same here

##########
File path: 
src/test/java/org/apache/maven/shared/artifact/filter/OldPatternIncludesArtifactFilter.java
##########
@@ -0,0 +1,428 @@
+package org.apache.maven.shared.artifact.filter;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import 
org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * TODO: include in maven-artifact in future
+ *
+ * @author <a href="mailto:br...@apache.org";>Brett Porter</a>
+ * @see StrictPatternIncludesArtifactFilter
+ */
+public class OldPatternIncludesArtifactFilter
+        implements ArtifactFilter, StatisticsReportingArtifactFilter
+{
+    private final List<String> positivePatterns;
+
+    private final List<String> negativePatterns;
+
+    private final boolean actTransitively;
+
+    private final Set<String> patternsTriggered = new HashSet<>();
+
+    private final List<String> filteredArtifactIds = new ArrayList<>();
+
+    /**
+     * @param patterns The pattern to be used.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> patterns 
)
+    {
+        this( patterns, false );
+    }
+
+    /**
+     * @param patterns The pattern to be used.
+     * @param actTransitively transitive yes/no.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> 
patterns, final boolean actTransitively )
+    {
+        this.actTransitively = actTransitively;
+        final List<String> pos = new ArrayList<>();
+        final List<String> neg = new ArrayList<>();
+        if ( patterns != null && !patterns.isEmpty() )
+        {
+            for ( String pattern : patterns )
+            {
+                if ( pattern.startsWith( "!" ) )
+                {
+                    neg.add( pattern.substring( 1 ) );
+                }
+                else
+                {
+                    pos.add( pattern );
+                }
+            }
+        }
+
+        positivePatterns = pos;
+        negativePatterns = neg;
+    }
+
+    /** {@inheritDoc} */
+    public boolean include( final Artifact artifact )
+    {
+        final boolean shouldInclude = patternMatches( artifact );
+
+        if ( !shouldInclude )
+        {
+            addFilteredArtifactId( artifact.getId() );
+        }
+
+        return shouldInclude;
+    }
+
+    /**
+     * @param artifact to check for.
+     * @return true if the match is true false otherwise.
+     */
+    protected boolean patternMatches( final Artifact artifact )
+    {
+        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+    }
+
+    /**
+     * @param artifactId add artifact to the filtered artifacts list.
+     */
+    protected void addFilteredArtifactId( final String artifactId )
+    {
+        filteredArtifactIds.add( artifactId );
+    }
+
+    private Boolean negativeMatch( final Artifact artifact )
+    {
+        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, negativePatterns );
+        }
+    }
+
+    /**
+     * @param artifact check for positive match.
+     * @return true/false.
+     */
+    protected Boolean positiveMatch( final Artifact artifact )
+    {
+        if ( positivePatterns == null || positivePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, positivePatterns );
+        }
+    }
+
+    private boolean match( final Artifact artifact, final List<String> 
patterns )
+    {
+        final String shortId = ArtifactUtils.versionlessKey( artifact );
+        final String id = artifact.getDependencyConflictId();
+        final String wholeId = artifact.getId();
+
+        if ( matchAgainst( wholeId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( id, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( shortId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    if ( matchAgainst( trailItem, patterns, true ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean matchAgainst( final String value, final List<String> 
patterns, final boolean regionMatch )
+    {
+        final String[] tokens = value.split( ":" );
+        for ( String pattern : patterns )
+        {
+            String[] patternTokens = pattern.split( ":" );
+
+            if ( patternTokens.length == 5 && tokens.length < 5 )
+            {
+                // 4th element is the classifier
+                if ( !"*".equals( patternTokens[3] ) )
+                {
+                    // classifier required, cannot be a match
+                    return false;
+                }
+                patternTokens = new String[] { patternTokens[0], 
patternTokens[1], patternTokens[2], patternTokens[4] };
+            }
+
+            // fail immediately if pattern tokens outnumber tokens to match
+            boolean matched = patternTokens.length <= tokens.length;
+
+            for ( int i = 0; matched && i < patternTokens.length; i++ )
+            {
+                matched = matches( tokens[i], patternTokens[i] );
+            }
+
+            // case of starting '*' like '*:jar:*'
+            // This really only matches from the end instead.....
+            if ( !matched && patternTokens.length < tokens.length && 
isFirstPatternWildcard( patternTokens ) )
+            {
+                matched = true;
+                int tokenOffset = tokens.length - patternTokens.length;
+                for ( int i = 0; matched && i < patternTokens.length; i++ )
+                {
+                    matched = matches( tokens[i + tokenOffset], 
patternTokens[i] );
+                }
+            }
+
+            if ( matched )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+            if ( regionMatch && value.contains( pattern ) )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+        }
+        return false;
+
+    }
+
+    private boolean isFirstPatternWildcard( String[] patternTokens )
+    {
+        return patternTokens.length > 0 && "*".equals( patternTokens[0] );
+    }
+
+    /**
+     * Gets whether the specified token matches the specified pattern segment.
+     *
+     * @param token the token to check
+     * @param pattern the pattern segment to match, as defined above
+     * @return <code>true</code> if the specified token is matched by the 
specified pattern segment
+     */
+    private boolean matches( final String token, final String pattern )
+    {
+        boolean matches;
+
+        // support full wildcard and implied wildcard
+        if ( "*".equals( pattern ) || pattern.length() == 0 )
+        {
+            matches = true;
+        }
+        // support contains wildcard
+        else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) )
+        {
+            final String contains = pattern.substring( 1, pattern.length() - 1 
);
+
+            matches = token.contains( contains );
+        }
+        // support leading wildcard
+        else if ( pattern.startsWith( "*" ) )
+        {
+            final String suffix = pattern.substring( 1 );
+
+            matches = token.endsWith( suffix );
+        }
+        // support trailing wildcard
+        else if ( pattern.endsWith( "*" ) )
+        {
+            final String prefix = pattern.substring( 0, pattern.length() - 1 );
+
+            matches = token.startsWith( prefix );
+        }
+        // support wildcards in the middle of a pattern segment
+        else if ( pattern.indexOf( '*' ) > -1 )
+        {
+            String[] parts = pattern.split( "\\*" );
+            int lastPartEnd = -1;
+            boolean match = true;
+
+            for ( String part : parts )
+            {
+                int idx = token.indexOf( part );
+                if ( idx <= lastPartEnd )
+                {
+                    match = false;
+                    break;
+                }
+
+                lastPartEnd = idx + part.length();
+            }
+
+            matches = match;
+        }
+        // support versions range
+        else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) )
+        {
+            matches = isVersionIncludedInRange( token, pattern );
+        }
+        // support exact match
+        else
+        {
+            matches = token.equals( pattern );
+        }
+
+        return matches;
+    }
+
+    private boolean isVersionIncludedInRange( final String version, final 
String range )
+    {
+        try
+        {
+            return VersionRange.createFromVersionSpec( range 
).containsVersion( new DefaultArtifactVersion( version ) );
+        }
+        catch ( final InvalidVersionSpecificationException e )
+        {
+            return false;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
+    {
+        // if there are no patterns, there is nothing to report.
+        if ( !positivePatterns.isEmpty() || !negativePatterns.isEmpty() )
+        {
+            final List<String> missed = new ArrayList<>();
+            missed.addAll( positivePatterns );
+            missed.addAll( negativePatterns );
+
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( String pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );

Review comment:
       Same here

##########
File path: 
src/test/java/org/apache/maven/shared/artifact/filter/OldPatternIncludesArtifactFilter.java
##########
@@ -0,0 +1,428 @@
+package org.apache.maven.shared.artifact.filter;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import 
org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * TODO: include in maven-artifact in future
+ *
+ * @author <a href="mailto:br...@apache.org";>Brett Porter</a>
+ * @see StrictPatternIncludesArtifactFilter
+ */
+public class OldPatternIncludesArtifactFilter
+        implements ArtifactFilter, StatisticsReportingArtifactFilter
+{
+    private final List<String> positivePatterns;
+
+    private final List<String> negativePatterns;
+
+    private final boolean actTransitively;
+
+    private final Set<String> patternsTriggered = new HashSet<>();
+
+    private final List<String> filteredArtifactIds = new ArrayList<>();
+
+    /**
+     * @param patterns The pattern to be used.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> patterns 
)
+    {
+        this( patterns, false );
+    }
+
+    /**
+     * @param patterns The pattern to be used.
+     * @param actTransitively transitive yes/no.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> 
patterns, final boolean actTransitively )
+    {
+        this.actTransitively = actTransitively;
+        final List<String> pos = new ArrayList<>();
+        final List<String> neg = new ArrayList<>();
+        if ( patterns != null && !patterns.isEmpty() )
+        {
+            for ( String pattern : patterns )
+            {
+                if ( pattern.startsWith( "!" ) )
+                {
+                    neg.add( pattern.substring( 1 ) );
+                }
+                else
+                {
+                    pos.add( pattern );
+                }
+            }
+        }
+
+        positivePatterns = pos;
+        negativePatterns = neg;
+    }
+
+    /** {@inheritDoc} */
+    public boolean include( final Artifact artifact )
+    {
+        final boolean shouldInclude = patternMatches( artifact );
+
+        if ( !shouldInclude )
+        {
+            addFilteredArtifactId( artifact.getId() );
+        }
+
+        return shouldInclude;
+    }
+
+    /**
+     * @param artifact to check for.
+     * @return true if the match is true false otherwise.
+     */
+    protected boolean patternMatches( final Artifact artifact )
+    {
+        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+    }
+
+    /**
+     * @param artifactId add artifact to the filtered artifacts list.
+     */
+    protected void addFilteredArtifactId( final String artifactId )
+    {
+        filteredArtifactIds.add( artifactId );
+    }
+
+    private Boolean negativeMatch( final Artifact artifact )
+    {
+        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, negativePatterns );
+        }
+    }
+
+    /**
+     * @param artifact check for positive match.
+     * @return true/false.
+     */
+    protected Boolean positiveMatch( final Artifact artifact )
+    {
+        if ( positivePatterns == null || positivePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, positivePatterns );
+        }
+    }
+
+    private boolean match( final Artifact artifact, final List<String> 
patterns )
+    {
+        final String shortId = ArtifactUtils.versionlessKey( artifact );
+        final String id = artifact.getDependencyConflictId();
+        final String wholeId = artifact.getId();
+
+        if ( matchAgainst( wholeId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( id, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( shortId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    if ( matchAgainst( trailItem, patterns, true ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean matchAgainst( final String value, final List<String> 
patterns, final boolean regionMatch )
+    {
+        final String[] tokens = value.split( ":" );
+        for ( String pattern : patterns )
+        {
+            String[] patternTokens = pattern.split( ":" );
+
+            if ( patternTokens.length == 5 && tokens.length < 5 )
+            {
+                // 4th element is the classifier
+                if ( !"*".equals( patternTokens[3] ) )
+                {
+                    // classifier required, cannot be a match
+                    return false;
+                }
+                patternTokens = new String[] { patternTokens[0], 
patternTokens[1], patternTokens[2], patternTokens[4] };
+            }
+
+            // fail immediately if pattern tokens outnumber tokens to match
+            boolean matched = patternTokens.length <= tokens.length;
+
+            for ( int i = 0; matched && i < patternTokens.length; i++ )
+            {
+                matched = matches( tokens[i], patternTokens[i] );
+            }
+
+            // case of starting '*' like '*:jar:*'
+            // This really only matches from the end instead.....
+            if ( !matched && patternTokens.length < tokens.length && 
isFirstPatternWildcard( patternTokens ) )
+            {
+                matched = true;
+                int tokenOffset = tokens.length - patternTokens.length;
+                for ( int i = 0; matched && i < patternTokens.length; i++ )
+                {
+                    matched = matches( tokens[i + tokenOffset], 
patternTokens[i] );
+                }
+            }
+
+            if ( matched )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+            if ( regionMatch && value.contains( pattern ) )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+        }
+        return false;
+
+    }
+
+    private boolean isFirstPatternWildcard( String[] patternTokens )
+    {
+        return patternTokens.length > 0 && "*".equals( patternTokens[0] );
+    }
+
+    /**
+     * Gets whether the specified token matches the specified pattern segment.
+     *
+     * @param token the token to check
+     * @param pattern the pattern segment to match, as defined above
+     * @return <code>true</code> if the specified token is matched by the 
specified pattern segment
+     */
+    private boolean matches( final String token, final String pattern )
+    {
+        boolean matches;
+
+        // support full wildcard and implied wildcard
+        if ( "*".equals( pattern ) || pattern.length() == 0 )
+        {
+            matches = true;
+        }
+        // support contains wildcard
+        else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) )
+        {
+            final String contains = pattern.substring( 1, pattern.length() - 1 
);
+
+            matches = token.contains( contains );
+        }
+        // support leading wildcard
+        else if ( pattern.startsWith( "*" ) )
+        {
+            final String suffix = pattern.substring( 1 );
+
+            matches = token.endsWith( suffix );
+        }
+        // support trailing wildcard
+        else if ( pattern.endsWith( "*" ) )
+        {
+            final String prefix = pattern.substring( 0, pattern.length() - 1 );
+
+            matches = token.startsWith( prefix );
+        }
+        // support wildcards in the middle of a pattern segment
+        else if ( pattern.indexOf( '*' ) > -1 )
+        {
+            String[] parts = pattern.split( "\\*" );
+            int lastPartEnd = -1;
+            boolean match = true;
+
+            for ( String part : parts )
+            {
+                int idx = token.indexOf( part );
+                if ( idx <= lastPartEnd )
+                {
+                    match = false;
+                    break;
+                }
+
+                lastPartEnd = idx + part.length();
+            }
+
+            matches = match;
+        }
+        // support versions range
+        else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) )
+        {
+            matches = isVersionIncludedInRange( token, pattern );
+        }
+        // support exact match
+        else
+        {
+            matches = token.equals( pattern );
+        }
+
+        return matches;
+    }
+
+    private boolean isVersionIncludedInRange( final String version, final 
String range )
+    {
+        try
+        {
+            return VersionRange.createFromVersionSpec( range 
).containsVersion( new DefaultArtifactVersion( version ) );
+        }
+        catch ( final InvalidVersionSpecificationException e )
+        {
+            return false;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
+    {
+        // if there are no patterns, there is nothing to report.
+        if ( !positivePatterns.isEmpty() || !negativePatterns.isEmpty() )
+        {
+            final List<String> missed = new ArrayList<>();
+            missed.addAll( positivePatterns );
+            missed.addAll( negativePatterns );
+
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( String pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );
+                }
+
+                buffer.append( "\n" );
+
+                logger.warn( buffer.toString() );
+            }
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Includes filter:" + getPatternsAsString();
+    }
+
+    /**
+     * @return pattern as a string.
+     */
+    protected String getPatternsAsString()
+    {
+        final StringBuilder buffer = new StringBuilder();
+        for ( String pattern : positivePatterns )
+        {
+            buffer.append( "\no '" ).append( pattern ).append( "'" );
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * @return description.
+     */
+    protected String getFilterDescription()
+    {
+        return "artifact inclusion filter";
+    }
+
+    /** {@inheritDoc} */
+    public void reportFilteredArtifacts( final Logger logger )
+    {
+        if ( !filteredArtifactIds.isEmpty() && logger.isDebugEnabled() )
+        {
+            final StringBuilder buffer =
+                    new StringBuilder( "The following artifacts were removed 
by this " + getFilterDescription() + ": " );
+
+            for ( String artifactId : filteredArtifactIds )
+            {
+                buffer.append( '\n' ).append( artifactId );

Review comment:
       Same here

##########
File path: 
src/test/java/org/apache/maven/shared/artifact/filter/OldPatternIncludesArtifactFilter.java
##########
@@ -0,0 +1,428 @@
+package org.apache.maven.shared.artifact.filter;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import 
org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * TODO: include in maven-artifact in future
+ *
+ * @author <a href="mailto:br...@apache.org";>Brett Porter</a>
+ * @see StrictPatternIncludesArtifactFilter
+ */
+public class OldPatternIncludesArtifactFilter
+        implements ArtifactFilter, StatisticsReportingArtifactFilter
+{
+    private final List<String> positivePatterns;
+
+    private final List<String> negativePatterns;
+
+    private final boolean actTransitively;
+
+    private final Set<String> patternsTriggered = new HashSet<>();
+
+    private final List<String> filteredArtifactIds = new ArrayList<>();
+
+    /**
+     * @param patterns The pattern to be used.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> patterns 
)
+    {
+        this( patterns, false );
+    }
+
+    /**
+     * @param patterns The pattern to be used.
+     * @param actTransitively transitive yes/no.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> 
patterns, final boolean actTransitively )
+    {
+        this.actTransitively = actTransitively;
+        final List<String> pos = new ArrayList<>();
+        final List<String> neg = new ArrayList<>();
+        if ( patterns != null && !patterns.isEmpty() )
+        {
+            for ( String pattern : patterns )
+            {
+                if ( pattern.startsWith( "!" ) )
+                {
+                    neg.add( pattern.substring( 1 ) );
+                }
+                else
+                {
+                    pos.add( pattern );
+                }
+            }
+        }
+
+        positivePatterns = pos;
+        negativePatterns = neg;
+    }
+
+    /** {@inheritDoc} */
+    public boolean include( final Artifact artifact )
+    {
+        final boolean shouldInclude = patternMatches( artifact );
+
+        if ( !shouldInclude )
+        {
+            addFilteredArtifactId( artifact.getId() );
+        }
+
+        return shouldInclude;
+    }
+
+    /**
+     * @param artifact to check for.
+     * @return true if the match is true false otherwise.
+     */
+    protected boolean patternMatches( final Artifact artifact )
+    {
+        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+    }
+
+    /**
+     * @param artifactId add artifact to the filtered artifacts list.
+     */
+    protected void addFilteredArtifactId( final String artifactId )
+    {
+        filteredArtifactIds.add( artifactId );
+    }
+
+    private Boolean negativeMatch( final Artifact artifact )
+    {
+        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, negativePatterns );
+        }
+    }
+
+    /**
+     * @param artifact check for positive match.
+     * @return true/false.
+     */
+    protected Boolean positiveMatch( final Artifact artifact )
+    {
+        if ( positivePatterns == null || positivePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, positivePatterns );
+        }
+    }
+
+    private boolean match( final Artifact artifact, final List<String> 
patterns )
+    {
+        final String shortId = ArtifactUtils.versionlessKey( artifact );
+        final String id = artifact.getDependencyConflictId();
+        final String wholeId = artifact.getId();
+
+        if ( matchAgainst( wholeId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( id, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( shortId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    if ( matchAgainst( trailItem, patterns, true ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean matchAgainst( final String value, final List<String> 
patterns, final boolean regionMatch )
+    {
+        final String[] tokens = value.split( ":" );
+        for ( String pattern : patterns )
+        {
+            String[] patternTokens = pattern.split( ":" );
+
+            if ( patternTokens.length == 5 && tokens.length < 5 )
+            {
+                // 4th element is the classifier
+                if ( !"*".equals( patternTokens[3] ) )
+                {
+                    // classifier required, cannot be a match
+                    return false;
+                }
+                patternTokens = new String[] { patternTokens[0], 
patternTokens[1], patternTokens[2], patternTokens[4] };
+            }
+
+            // fail immediately if pattern tokens outnumber tokens to match
+            boolean matched = patternTokens.length <= tokens.length;
+
+            for ( int i = 0; matched && i < patternTokens.length; i++ )
+            {
+                matched = matches( tokens[i], patternTokens[i] );
+            }
+
+            // case of starting '*' like '*:jar:*'
+            // This really only matches from the end instead.....
+            if ( !matched && patternTokens.length < tokens.length && 
isFirstPatternWildcard( patternTokens ) )
+            {
+                matched = true;
+                int tokenOffset = tokens.length - patternTokens.length;
+                for ( int i = 0; matched && i < patternTokens.length; i++ )
+                {
+                    matched = matches( tokens[i + tokenOffset], 
patternTokens[i] );
+                }
+            }
+
+            if ( matched )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+            if ( regionMatch && value.contains( pattern ) )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+        }
+        return false;
+
+    }
+
+    private boolean isFirstPatternWildcard( String[] patternTokens )
+    {
+        return patternTokens.length > 0 && "*".equals( patternTokens[0] );
+    }
+
+    /**
+     * Gets whether the specified token matches the specified pattern segment.
+     *
+     * @param token the token to check
+     * @param pattern the pattern segment to match, as defined above
+     * @return <code>true</code> if the specified token is matched by the 
specified pattern segment
+     */
+    private boolean matches( final String token, final String pattern )
+    {
+        boolean matches;
+
+        // support full wildcard and implied wildcard
+        if ( "*".equals( pattern ) || pattern.length() == 0 )
+        {
+            matches = true;
+        }
+        // support contains wildcard
+        else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) )
+        {
+            final String contains = pattern.substring( 1, pattern.length() - 1 
);
+
+            matches = token.contains( contains );
+        }
+        // support leading wildcard
+        else if ( pattern.startsWith( "*" ) )
+        {
+            final String suffix = pattern.substring( 1 );
+
+            matches = token.endsWith( suffix );
+        }
+        // support trailing wildcard
+        else if ( pattern.endsWith( "*" ) )
+        {
+            final String prefix = pattern.substring( 0, pattern.length() - 1 );
+
+            matches = token.startsWith( prefix );
+        }
+        // support wildcards in the middle of a pattern segment
+        else if ( pattern.indexOf( '*' ) > -1 )
+        {
+            String[] parts = pattern.split( "\\*" );
+            int lastPartEnd = -1;
+            boolean match = true;
+
+            for ( String part : parts )
+            {
+                int idx = token.indexOf( part );
+                if ( idx <= lastPartEnd )
+                {
+                    match = false;
+                    break;
+                }
+
+                lastPartEnd = idx + part.length();
+            }
+
+            matches = match;
+        }
+        // support versions range
+        else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) )
+        {
+            matches = isVersionIncludedInRange( token, pattern );
+        }
+        // support exact match
+        else
+        {
+            matches = token.equals( pattern );
+        }
+
+        return matches;
+    }
+
+    private boolean isVersionIncludedInRange( final String version, final 
String range )
+    {
+        try
+        {
+            return VersionRange.createFromVersionSpec( range 
).containsVersion( new DefaultArtifactVersion( version ) );
+        }
+        catch ( final InvalidVersionSpecificationException e )
+        {
+            return false;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
+    {
+        // if there are no patterns, there is nothing to report.
+        if ( !positivePatterns.isEmpty() || !negativePatterns.isEmpty() )
+        {
+            final List<String> missed = new ArrayList<>();
+            missed.addAll( positivePatterns );
+            missed.addAll( negativePatterns );
+
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( String pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );
+                }
+
+                buffer.append( "\n" );
+
+                logger.warn( buffer.toString() );
+            }
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Includes filter:" + getPatternsAsString();

Review comment:
       Leave a space after the colon.

##########
File path: 
src/test/java/org/apache/maven/shared/artifact/filter/OldPatternIncludesArtifactFilter.java
##########
@@ -0,0 +1,428 @@
+package org.apache.maven.shared.artifact.filter;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import 
org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * TODO: include in maven-artifact in future
+ *
+ * @author <a href="mailto:br...@apache.org";>Brett Porter</a>
+ * @see StrictPatternIncludesArtifactFilter
+ */
+public class OldPatternIncludesArtifactFilter
+        implements ArtifactFilter, StatisticsReportingArtifactFilter
+{
+    private final List<String> positivePatterns;
+
+    private final List<String> negativePatterns;
+
+    private final boolean actTransitively;
+
+    private final Set<String> patternsTriggered = new HashSet<>();
+
+    private final List<String> filteredArtifactIds = new ArrayList<>();
+
+    /**
+     * @param patterns The pattern to be used.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> patterns 
)
+    {
+        this( patterns, false );
+    }
+
+    /**
+     * @param patterns The pattern to be used.
+     * @param actTransitively transitive yes/no.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> 
patterns, final boolean actTransitively )
+    {
+        this.actTransitively = actTransitively;
+        final List<String> pos = new ArrayList<>();
+        final List<String> neg = new ArrayList<>();
+        if ( patterns != null && !patterns.isEmpty() )
+        {
+            for ( String pattern : patterns )
+            {
+                if ( pattern.startsWith( "!" ) )
+                {
+                    neg.add( pattern.substring( 1 ) );
+                }
+                else
+                {
+                    pos.add( pattern );
+                }
+            }
+        }
+
+        positivePatterns = pos;
+        negativePatterns = neg;
+    }
+
+    /** {@inheritDoc} */
+    public boolean include( final Artifact artifact )
+    {
+        final boolean shouldInclude = patternMatches( artifact );
+
+        if ( !shouldInclude )
+        {
+            addFilteredArtifactId( artifact.getId() );
+        }
+
+        return shouldInclude;
+    }
+
+    /**
+     * @param artifact to check for.
+     * @return true if the match is true false otherwise.
+     */
+    protected boolean patternMatches( final Artifact artifact )
+    {
+        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+    }
+
+    /**
+     * @param artifactId add artifact to the filtered artifacts list.
+     */
+    protected void addFilteredArtifactId( final String artifactId )
+    {
+        filteredArtifactIds.add( artifactId );
+    }
+
+    private Boolean negativeMatch( final Artifact artifact )
+    {
+        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, negativePatterns );
+        }
+    }
+
+    /**
+     * @param artifact check for positive match.
+     * @return true/false.
+     */
+    protected Boolean positiveMatch( final Artifact artifact )
+    {
+        if ( positivePatterns == null || positivePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, positivePatterns );
+        }
+    }
+
+    private boolean match( final Artifact artifact, final List<String> 
patterns )
+    {
+        final String shortId = ArtifactUtils.versionlessKey( artifact );
+        final String id = artifact.getDependencyConflictId();
+        final String wholeId = artifact.getId();
+
+        if ( matchAgainst( wholeId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( id, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( shortId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    if ( matchAgainst( trailItem, patterns, true ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean matchAgainst( final String value, final List<String> 
patterns, final boolean regionMatch )
+    {
+        final String[] tokens = value.split( ":" );
+        for ( String pattern : patterns )
+        {
+            String[] patternTokens = pattern.split( ":" );
+
+            if ( patternTokens.length == 5 && tokens.length < 5 )
+            {
+                // 4th element is the classifier
+                if ( !"*".equals( patternTokens[3] ) )
+                {
+                    // classifier required, cannot be a match
+                    return false;
+                }
+                patternTokens = new String[] { patternTokens[0], 
patternTokens[1], patternTokens[2], patternTokens[4] };
+            }
+
+            // fail immediately if pattern tokens outnumber tokens to match
+            boolean matched = patternTokens.length <= tokens.length;
+
+            for ( int i = 0; matched && i < patternTokens.length; i++ )
+            {
+                matched = matches( tokens[i], patternTokens[i] );
+            }
+
+            // case of starting '*' like '*:jar:*'
+            // This really only matches from the end instead.....
+            if ( !matched && patternTokens.length < tokens.length && 
isFirstPatternWildcard( patternTokens ) )
+            {
+                matched = true;
+                int tokenOffset = tokens.length - patternTokens.length;
+                for ( int i = 0; matched && i < patternTokens.length; i++ )
+                {
+                    matched = matches( tokens[i + tokenOffset], 
patternTokens[i] );
+                }
+            }
+
+            if ( matched )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+            if ( regionMatch && value.contains( pattern ) )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+        }
+        return false;
+
+    }
+
+    private boolean isFirstPatternWildcard( String[] patternTokens )
+    {
+        return patternTokens.length > 0 && "*".equals( patternTokens[0] );
+    }
+
+    /**
+     * Gets whether the specified token matches the specified pattern segment.
+     *
+     * @param token the token to check
+     * @param pattern the pattern segment to match, as defined above
+     * @return <code>true</code> if the specified token is matched by the 
specified pattern segment
+     */
+    private boolean matches( final String token, final String pattern )
+    {
+        boolean matches;
+
+        // support full wildcard and implied wildcard
+        if ( "*".equals( pattern ) || pattern.length() == 0 )
+        {
+            matches = true;
+        }
+        // support contains wildcard
+        else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) )
+        {
+            final String contains = pattern.substring( 1, pattern.length() - 1 
);
+
+            matches = token.contains( contains );
+        }
+        // support leading wildcard
+        else if ( pattern.startsWith( "*" ) )
+        {
+            final String suffix = pattern.substring( 1 );
+
+            matches = token.endsWith( suffix );
+        }
+        // support trailing wildcard
+        else if ( pattern.endsWith( "*" ) )
+        {
+            final String prefix = pattern.substring( 0, pattern.length() - 1 );
+
+            matches = token.startsWith( prefix );
+        }
+        // support wildcards in the middle of a pattern segment
+        else if ( pattern.indexOf( '*' ) > -1 )
+        {
+            String[] parts = pattern.split( "\\*" );
+            int lastPartEnd = -1;
+            boolean match = true;
+
+            for ( String part : parts )
+            {
+                int idx = token.indexOf( part );
+                if ( idx <= lastPartEnd )
+                {
+                    match = false;
+                    break;
+                }
+
+                lastPartEnd = idx + part.length();
+            }
+
+            matches = match;
+        }
+        // support versions range
+        else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) )
+        {
+            matches = isVersionIncludedInRange( token, pattern );
+        }
+        // support exact match
+        else
+        {
+            matches = token.equals( pattern );
+        }
+
+        return matches;
+    }
+
+    private boolean isVersionIncludedInRange( final String version, final 
String range )
+    {
+        try
+        {
+            return VersionRange.createFromVersionSpec( range 
).containsVersion( new DefaultArtifactVersion( version ) );
+        }
+        catch ( final InvalidVersionSpecificationException e )
+        {
+            return false;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
+    {
+        // if there are no patterns, there is nothing to report.
+        if ( !positivePatterns.isEmpty() || !negativePatterns.isEmpty() )
+        {
+            final List<String> missed = new ArrayList<>();
+            missed.addAll( positivePatterns );
+            missed.addAll( negativePatterns );
+
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( String pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );
+                }
+
+                buffer.append( "\n" );

Review comment:
       Same here

##########
File path: 
src/test/java/org/apache/maven/shared/artifact/filter/OldPatternIncludesArtifactFilter.java
##########
@@ -0,0 +1,428 @@
+package org.apache.maven.shared.artifact.filter;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import 
org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * TODO: include in maven-artifact in future
+ *
+ * @author <a href="mailto:br...@apache.org";>Brett Porter</a>
+ * @see StrictPatternIncludesArtifactFilter
+ */
+public class OldPatternIncludesArtifactFilter
+        implements ArtifactFilter, StatisticsReportingArtifactFilter
+{
+    private final List<String> positivePatterns;
+
+    private final List<String> negativePatterns;
+
+    private final boolean actTransitively;
+
+    private final Set<String> patternsTriggered = new HashSet<>();
+
+    private final List<String> filteredArtifactIds = new ArrayList<>();
+
+    /**
+     * @param patterns The pattern to be used.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> patterns 
)
+    {
+        this( patterns, false );
+    }
+
+    /**
+     * @param patterns The pattern to be used.
+     * @param actTransitively transitive yes/no.
+     */
+    public OldPatternIncludesArtifactFilter( final Collection<String> 
patterns, final boolean actTransitively )
+    {
+        this.actTransitively = actTransitively;
+        final List<String> pos = new ArrayList<>();
+        final List<String> neg = new ArrayList<>();
+        if ( patterns != null && !patterns.isEmpty() )
+        {
+            for ( String pattern : patterns )
+            {
+                if ( pattern.startsWith( "!" ) )
+                {
+                    neg.add( pattern.substring( 1 ) );
+                }
+                else
+                {
+                    pos.add( pattern );
+                }
+            }
+        }
+
+        positivePatterns = pos;
+        negativePatterns = neg;
+    }
+
+    /** {@inheritDoc} */
+    public boolean include( final Artifact artifact )
+    {
+        final boolean shouldInclude = patternMatches( artifact );
+
+        if ( !shouldInclude )
+        {
+            addFilteredArtifactId( artifact.getId() );
+        }
+
+        return shouldInclude;
+    }
+
+    /**
+     * @param artifact to check for.
+     * @return true if the match is true false otherwise.
+     */
+    protected boolean patternMatches( final Artifact artifact )
+    {
+        return positiveMatch( artifact ) == Boolean.TRUE || negativeMatch( 
artifact ) == Boolean.FALSE;
+    }
+
+    /**
+     * @param artifactId add artifact to the filtered artifacts list.
+     */
+    protected void addFilteredArtifactId( final String artifactId )
+    {
+        filteredArtifactIds.add( artifactId );
+    }
+
+    private Boolean negativeMatch( final Artifact artifact )
+    {
+        if ( negativePatterns == null || negativePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, negativePatterns );
+        }
+    }
+
+    /**
+     * @param artifact check for positive match.
+     * @return true/false.
+     */
+    protected Boolean positiveMatch( final Artifact artifact )
+    {
+        if ( positivePatterns == null || positivePatterns.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return match( artifact, positivePatterns );
+        }
+    }
+
+    private boolean match( final Artifact artifact, final List<String> 
patterns )
+    {
+        final String shortId = ArtifactUtils.versionlessKey( artifact );
+        final String id = artifact.getDependencyConflictId();
+        final String wholeId = artifact.getId();
+
+        if ( matchAgainst( wholeId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( id, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( matchAgainst( shortId, patterns, false ) )
+        {
+            return true;
+        }
+
+        if ( actTransitively )
+        {
+            final List<String> depTrail = artifact.getDependencyTrail();
+
+            if ( depTrail != null && depTrail.size() > 1 )
+            {
+                for ( String trailItem : depTrail )
+                {
+                    if ( matchAgainst( trailItem, patterns, true ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean matchAgainst( final String value, final List<String> 
patterns, final boolean regionMatch )
+    {
+        final String[] tokens = value.split( ":" );
+        for ( String pattern : patterns )
+        {
+            String[] patternTokens = pattern.split( ":" );
+
+            if ( patternTokens.length == 5 && tokens.length < 5 )
+            {
+                // 4th element is the classifier
+                if ( !"*".equals( patternTokens[3] ) )
+                {
+                    // classifier required, cannot be a match
+                    return false;
+                }
+                patternTokens = new String[] { patternTokens[0], 
patternTokens[1], patternTokens[2], patternTokens[4] };
+            }
+
+            // fail immediately if pattern tokens outnumber tokens to match
+            boolean matched = patternTokens.length <= tokens.length;
+
+            for ( int i = 0; matched && i < patternTokens.length; i++ )
+            {
+                matched = matches( tokens[i], patternTokens[i] );
+            }
+
+            // case of starting '*' like '*:jar:*'
+            // This really only matches from the end instead.....
+            if ( !matched && patternTokens.length < tokens.length && 
isFirstPatternWildcard( patternTokens ) )
+            {
+                matched = true;
+                int tokenOffset = tokens.length - patternTokens.length;
+                for ( int i = 0; matched && i < patternTokens.length; i++ )
+                {
+                    matched = matches( tokens[i + tokenOffset], 
patternTokens[i] );
+                }
+            }
+
+            if ( matched )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+            if ( regionMatch && value.contains( pattern ) )
+            {
+                patternsTriggered.add( pattern );
+                return true;
+            }
+
+        }
+        return false;
+
+    }
+
+    private boolean isFirstPatternWildcard( String[] patternTokens )
+    {
+        return patternTokens.length > 0 && "*".equals( patternTokens[0] );
+    }
+
+    /**
+     * Gets whether the specified token matches the specified pattern segment.
+     *
+     * @param token the token to check
+     * @param pattern the pattern segment to match, as defined above
+     * @return <code>true</code> if the specified token is matched by the 
specified pattern segment
+     */
+    private boolean matches( final String token, final String pattern )
+    {
+        boolean matches;
+
+        // support full wildcard and implied wildcard
+        if ( "*".equals( pattern ) || pattern.length() == 0 )
+        {
+            matches = true;
+        }
+        // support contains wildcard
+        else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) )
+        {
+            final String contains = pattern.substring( 1, pattern.length() - 1 
);
+
+            matches = token.contains( contains );
+        }
+        // support leading wildcard
+        else if ( pattern.startsWith( "*" ) )
+        {
+            final String suffix = pattern.substring( 1 );
+
+            matches = token.endsWith( suffix );
+        }
+        // support trailing wildcard
+        else if ( pattern.endsWith( "*" ) )
+        {
+            final String prefix = pattern.substring( 0, pattern.length() - 1 );
+
+            matches = token.startsWith( prefix );
+        }
+        // support wildcards in the middle of a pattern segment
+        else if ( pattern.indexOf( '*' ) > -1 )
+        {
+            String[] parts = pattern.split( "\\*" );
+            int lastPartEnd = -1;
+            boolean match = true;
+
+            for ( String part : parts )
+            {
+                int idx = token.indexOf( part );
+                if ( idx <= lastPartEnd )
+                {
+                    match = false;
+                    break;
+                }
+
+                lastPartEnd = idx + part.length();
+            }
+
+            matches = match;
+        }
+        // support versions range
+        else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) )
+        {
+            matches = isVersionIncludedInRange( token, pattern );
+        }
+        // support exact match
+        else
+        {
+            matches = token.equals( pattern );
+        }
+
+        return matches;
+    }
+
+    private boolean isVersionIncludedInRange( final String version, final 
String range )
+    {
+        try
+        {
+            return VersionRange.createFromVersionSpec( range 
).containsVersion( new DefaultArtifactVersion( version ) );
+        }
+        catch ( final InvalidVersionSpecificationException e )
+        {
+            return false;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void reportMissedCriteria( final Logger logger )
+    {
+        // if there are no patterns, there is nothing to report.
+        if ( !positivePatterns.isEmpty() || !negativePatterns.isEmpty() )
+        {
+            final List<String> missed = new ArrayList<>();
+            missed.addAll( positivePatterns );
+            missed.addAll( negativePatterns );
+
+            missed.removeAll( patternsTriggered );
+
+            if ( !missed.isEmpty() && logger.isWarnEnabled() )
+            {
+                final StringBuilder buffer = new StringBuilder();
+
+                buffer.append( "The following patterns were never triggered in 
this " );
+                buffer.append( getFilterDescription() );
+                buffer.append( ':' );
+
+                for ( String pattern : missed )
+                {
+                    buffer.append( "\no  '" ).append( pattern ).append( "'" );
+                }
+
+                buffer.append( "\n" );
+
+                logger.warn( buffer.toString() );
+            }
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Includes filter:" + getPatternsAsString();
+    }
+
+    /**
+     * @return pattern as a string.
+     */
+    protected String getPatternsAsString()
+    {
+        final StringBuilder buffer = new StringBuilder();
+        for ( String pattern : positivePatterns )
+        {
+            buffer.append( "\no '" ).append( pattern ).append( "'" );

Review comment:
       Same here




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to