View Javadoc
1   package org.apache.maven.shared.artifact.filter.resolve.transform;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.List;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import org.apache.maven.shared.artifact.filter.resolve.AbstractFilter;
29  import org.apache.maven.shared.artifact.filter.resolve.AndFilter;
30  import org.apache.maven.shared.artifact.filter.resolve.ExclusionsFilter;
31  import org.apache.maven.shared.artifact.filter.resolve.FilterTransformer;
32  import org.apache.maven.shared.artifact.filter.resolve.OrFilter;
33  import org.apache.maven.shared.artifact.filter.resolve.PatternExclusionsFilter;
34  import org.apache.maven.shared.artifact.filter.resolve.PatternInclusionsFilter;
35  import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
36  import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
37  import org.eclipse.aether.graph.DependencyFilter;
38  import org.eclipse.aether.graph.DependencyNode;
39  import org.eclipse.aether.util.filter.AndDependencyFilter;
40  import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
41  import org.eclipse.aether.util.filter.OrDependencyFilter;
42  import org.eclipse.aether.util.filter.PatternExclusionsDependencyFilter;
43  import org.eclipse.aether.util.filter.PatternInclusionsDependencyFilter;
44  import org.eclipse.aether.util.filter.ScopeDependencyFilter;
45  
46  /**
47   * FilterTransformer implementation for Eclipses Aether
48   * 
49   * @author Robert Scholte
50   * @since 3.0
51   */
52  public class EclipseAetherFilterTransformer
53      implements FilterTransformer<DependencyFilter>
54  {
55      /**
56       * When using as regular expression, group(1) + group(3) will be the coordinate, 
57       * group(2) will be the classifier.
58       */
59      private static final String GAE_C_V = "(.*:.*:.*):(.+)(:.*)";
60      
61      @Override
62      public AndDependencyFilter transform( AndFilter andFilter )
63      {
64          Collection<DependencyFilter> filters = new ArrayList<DependencyFilter>();
65          for ( TransformableFilter filter : andFilter.getFilters() )
66          {
67              filters.add( filter.transform( this ) );
68          }
69          return new AndDependencyFilter( filters );
70      }
71  
72      @Override
73      public ExclusionsDependencyFilter transform( ExclusionsFilter filter )
74      {
75          return new ExclusionsDependencyFilter( filter.getExcludes() );
76      }
77  
78      @Override
79      public OrDependencyFilter transform( OrFilter orFilter )
80      {
81          Collection<DependencyFilter> filters = new ArrayList<DependencyFilter>();
82          for ( TransformableFilter filter : orFilter.getFilters() )
83          {
84              filters.add( filter.transform( this ) );
85          }
86          return new OrDependencyFilter( filters );
87      }
88  
89      @Override
90      public ScopeDependencyFilter transform( ScopeFilter filter )
91      {
92          return new ScopeDependencyFilter( filter.getIncluded(), filter.getExcluded() );
93      }
94      
95      @Override
96      public DependencyFilter transform( PatternExclusionsFilter filter )
97      {
98          return new PatternExclusionsDependencyFilter( filter.getExcludes() );
99      } 
100 
101     @Override
102     public DependencyFilter transform( PatternInclusionsFilter filter )
103     {
104         // if any include contains a classifier:
105         // split all includes and make it an or-filter for every include
106         // for the classifier, add an and-filter with a classifierfilter and patterninclusionfilter
107         
108         for ( String include : filter.getIncludes() )
109         {
110             if ( include.matches( GAE_C_V ) )
111             {
112                 return newAdvancedPatternInclusionFilter( filter.getIncludes() );
113             }
114         }
115         
116         return new PatternInclusionsDependencyFilter( filter.getIncludes() );
117     }
118     
119     @Override
120     public DependencyFilter transform( final AbstractFilter filter )
121     {
122         return new DependencyFilter()
123         {
124             @Override
125             public boolean accept( DependencyNode node, List<DependencyNode> parents )
126             {
127                 return filter.accept( new EclipseAetherNode( node ), null );
128             }
129         }; 
130     }
131 
132     private DependencyFilter newAdvancedPatternInclusionFilter( Collection<String> includes )
133     {
134         List<DependencyFilter> filters = new ArrayList<DependencyFilter>( includes.size() );
135 
136         Pattern pattern = Pattern.compile( GAE_C_V );
137         for ( String include : includes )
138         {
139             Matcher matcher = pattern.matcher( include );
140             if ( matcher.matches() )
141             {
142                 DependencyFilter patternFilter =
143                     new PatternInclusionsDependencyFilter( matcher.group( 1 ) + matcher.group( 3 ) );
144 
145                 final String classifier = matcher.group( 2 );
146                 
147                 DependencyFilter classifierFilter = new DependencyFilter()
148                 {
149                     @Override
150                     public boolean accept( DependencyNode node, List<DependencyNode> parents )
151                     {
152                         String nodeClassifier = node.getArtifact().getClassifier();
153                         
154                         if ( nodeClassifier == null )
155                         {
156                             return false;
157                         }
158                         else 
159                         {
160                             return "*".equals( classifier ) || nodeClassifier.matches( classifier );
161                         }
162                     }
163                 };
164 
165                 filters.add( new AndDependencyFilter( patternFilter, classifierFilter ) );
166             }
167             else
168             {
169                 filters.add( new PatternInclusionsDependencyFilter( include ) );
170             }
171         }
172         return new OrDependencyFilter( filters );
173     }
174 }