[MSHARED-599] Allow classifier in PatternInclusionsFilter

git-svn-id: https://svn.apache.org/repos/asf/maven/shared/trunk@1748472 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformer.java b/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformer.java
index 743e31c..bcb585f 100644
--- a/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformer.java
+++ b/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformer.java
@@ -22,6 +22,8 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.maven.shared.artifact.filter.resolve.AbstractFilter;
 import org.apache.maven.shared.artifact.filter.resolve.AndFilter;
@@ -93,6 +95,18 @@
     @Override
     public DependencyFilter transform( PatternInclusionsFilter filter )
     {
+        // if any include contains a classifier:
+        // split all includes and make it an or-filter for every include
+        // for the classifier, add an and-filter with a classifierfilter and patterninclusionfilter
+        
+        for ( String include : filter.getIncludes() )
+        {
+            if ( include.matches( ".*:.*:.*:.*:.*" ) )
+            {
+                return newAdvancedPatternInclusionFilter( filter.getIncludes() );
+            }
+        }
+        
         return new PatternInclusionsDependencyFilter( filter.getIncludes() );
     }
     
@@ -108,4 +122,47 @@
             }
         }; 
     }
+
+    private DependencyFilter newAdvancedPatternInclusionFilter( Collection<String> includes )
+    {
+        List<DependencyFilter> filters = new ArrayList<DependencyFilter>( includes.size() );
+
+        Pattern pattern = Pattern.compile( "(.*:.*:.*):(.+)(:.*)" );
+        for ( String include : includes )
+        {
+            Matcher matcher = pattern.matcher( include );
+            if ( matcher.matches() )
+            {
+                DependencyFilter patternFilter =
+                    new PatternInclusionsDependencyFilter( matcher.group( 1 ) + matcher.group( 3 ) );
+
+                final String classifier = matcher.group( 2 );
+                
+                DependencyFilter classifierFilter = new DependencyFilter()
+                {
+                    @Override
+                    public boolean accept( DependencyNode node, List<DependencyNode> parents )
+                    {
+                        String nodeClassifier = node.getArtifact().getClassifier();
+                        
+                        if ( nodeClassifier == null )
+                        {
+                            return false;
+                        }
+                        else 
+                        {
+                            return "*".equals( classifier ) || nodeClassifier.matches( classifier );
+                        }
+                    }
+                };
+
+                filters.add( new AndDependencyFilter( patternFilter, classifierFilter ) );
+            }
+            else
+            {
+                filters.add( new PatternInclusionsDependencyFilter( include ) );
+            }
+        }
+        return new OrDependencyFilter( filters );
+    }
 }
diff --git a/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformer.java b/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformer.java
index 7696b75..42184e9 100644
--- a/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformer.java
+++ b/src/main/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformer.java
@@ -22,6 +22,8 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.maven.shared.artifact.filter.resolve.AbstractFilter;
 import org.apache.maven.shared.artifact.filter.resolve.AndFilter;
@@ -93,6 +95,18 @@
     @Override
     public DependencyFilter transform( PatternInclusionsFilter filter )
     {
+     // if any include contains a classifier:
+        // split all includes and make it an or-filter for every include
+        // for the classifier, add an and-filter with a classifierfilter and patterninclusionfilter
+        
+        for ( String include : filter.getIncludes() )
+        {
+            if ( include.matches( ".*:.*:.*:.*:.*" ) )
+            {
+                return newAdvancedPatternInclusionFilter( filter.getIncludes() );
+            }
+        }
+        
         return new PatternInclusionsDependencyFilter( filter.getIncludes() );
     }
     
@@ -108,4 +122,47 @@
             }
         };
     }
+    
+    private DependencyFilter newAdvancedPatternInclusionFilter( Collection<String> includes )
+    {
+        List<DependencyFilter> filters = new ArrayList<DependencyFilter>( includes.size() );
+
+        Pattern pattern = Pattern.compile( "(.*:.*:.*):(.+)(:.*)" );
+        for ( String include : includes )
+        {
+            Matcher matcher = pattern.matcher( include );
+            if ( matcher.matches() )
+            {
+                DependencyFilter patternFilter =
+                    new PatternInclusionsDependencyFilter( matcher.group( 1 ) + matcher.group( 3 ) );
+
+                final String classifier = matcher.group( 2 );
+                
+                DependencyFilter classifierFilter = new DependencyFilter()
+                {
+                    @Override
+                    public boolean accept( DependencyNode node, List<DependencyNode> parents )
+                    {
+                        String nodeClassifier = node.getDependency().getArtifact().getClassifier();
+                        
+                        if ( nodeClassifier == null )
+                        {
+                            return false;
+                        }
+                        else 
+                        {
+                            return "*".equals( classifier ) || nodeClassifier.matches( classifier );
+                        }
+                    }
+                };
+
+                filters.add( new AndDependencyFilter( patternFilter, classifierFilter ) );
+            }
+            else
+            {
+                filters.add( new PatternInclusionsDependencyFilter( include ) );
+            }
+        }
+        return new OrDependencyFilter( filters );
+    }
 }
diff --git a/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformerTest.java b/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformerTest.java
index 910b089..b125b80 100644
--- a/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformerTest.java
+++ b/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/EclipseAetherFilterTransformerTest.java
@@ -139,7 +139,22 @@
 
         assertFalse( dependencyFilter.accept( newDependencyNode( "x:a:v", "runtime" ), null ) );
     }
-    
+
+    @Test
+    public void testTransformClassifierPatternInclusionsFilter()
+    {
+        PatternInclusionsFilter filter =
+            new PatternInclusionsFilter( Collections.singletonList( "g:*:*:c:*" ) );
+
+        DependencyFilter dependencyFilter = filter.transform( transformer );
+
+        assertTrue( dependencyFilter.accept( newDependencyNode( "g:a:v:c:*", "runtime" ), null ) );
+
+        assertFalse( dependencyFilter.accept( newDependencyNode( "g:a:v", "runtime" ), null ) );
+        
+        assertFalse( dependencyFilter.accept( newDependencyNode( "x:a:v:c:*", "runtime" ), null ) );
+    }
+
     @Test
     public void testTransformAbstractFilter() throws Exception
     {
diff --git a/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformerTest.java b/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformerTest.java
index 8ff930a..d759bc0 100644
--- a/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformerTest.java
+++ b/src/test/java/org/apache/maven/shared/artifact/filter/resolve/transform/SonatypeAetherFilterTransformerTest.java
@@ -141,6 +141,22 @@
         assertFalse( dependencyFilter.accept( newDependencyNode( "x:a:v", "runtime" ), null ) );
     }
     
+
+    @Test
+    public void testTransformClassifierPatternInclusionsFilter()
+    {
+        PatternInclusionsFilter filter =
+            new PatternInclusionsFilter( Collections.singletonList( "g:*:*:c:*" ) );
+
+        DependencyFilter dependencyFilter = filter.transform( transformer );
+
+        assertTrue( dependencyFilter.accept( newDependencyNode( "g:a:v:c:*", "runtime" ), null ) );
+
+        assertFalse( dependencyFilter.accept( newDependencyNode( "g:a:v", "runtime" ), null ) );
+        
+        assertFalse( dependencyFilter.accept( newDependencyNode( "x:a:v:c:*", "runtime" ), null ) );
+    }
+    
     @Test
     public void testTransformAbstractFilter() throws Exception
     {