View Javadoc
1   /*
2    * Licensed under the Apache License, Version 2.0 (the "License");
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package org.basepom.inline.mojo;
16  
17  import static com.google.common.base.Preconditions.checkNotNull;
18  import static org.basepom.inline.mojo.ScopeLimitingFilter.Scope.compile;
19  import static org.basepom.inline.mojo.ScopeLimitingFilter.Scope.provided;
20  import static org.basepom.inline.mojo.ScopeLimitingFilter.Scope.runtime;
21  import static org.basepom.inline.mojo.ScopeLimitingFilter.Scope.system;
22  import static org.basepom.inline.mojo.ScopeLimitingFilter.Scope.test;
23  
24  import java.util.EnumSet;
25  import java.util.List;
26  import java.util.Set;
27  
28  import com.google.common.base.MoreObjects;
29  import com.google.common.collect.ImmutableSet;
30  import org.eclipse.aether.graph.DependencyFilter;
31  import org.eclipse.aether.graph.DependencyNode;
32  import org.eclipse.aether.util.artifact.JavaScopes;
33  
34  public final class ScopeLimitingFilter
35          implements DependencyFilter {
36  
37      public static final String COMPILE_PLUS_RUNTIME = JavaScopes.COMPILE + "+" + JavaScopes.RUNTIME;
38      public static final String RUNTIME_PLUS_SYSTEM = JavaScopes.RUNTIME + "+" + JavaScopes.SYSTEM;
39  
40      enum Scope {
41          compile, runtime, test, provided, system
42      }
43  
44      private final ImmutableSet<Scope> scopes;
45  
46      /**
47       * @param scope A maven scope name.
48       * @return A filter that matches any dependency that would be visible in the given scope.
49       */
50      public static ScopeLimitingFilter computeDependencyScope(final String scope) {
51          return new ScopeLimitingFilter(computeScopes(scope));
52      }
53  
54      /**
55       * Returns filter that matches any transitive dependency that would be visible in the given scope. This is different from the scope above, as not all scopes
56       * are fully transitive (e.g. a test dependency is not transitively visible.
57       *
58       * @param scope A maven scope name.
59       * @return A filter that matches any dependency that would be visible in the given scope.
60       */
61      public static ScopeLimitingFilter computeTransitiveScope(final String scope) {
62          return new ScopeLimitingFilter(computeScopes(computeTransitiveScopes(scope)));
63      }
64  
65      private ScopeLimitingFilter(Set<Scope> scopes) {
66          this.scopes = ImmutableSet.copyOf(scopes);
67      }
68  
69      private static EnumSet<Scope> computeScopes(final String scope) {
70          checkNotNull(scope, "scope is null");
71  
72          switch (scope) {
73              case JavaScopes.COMPILE:
74                  return EnumSet.of(compile, system, provided);
75              case JavaScopes.PROVIDED:
76                  return EnumSet.of(provided);
77              case JavaScopes.RUNTIME:
78                  return EnumSet.of(compile, runtime);
79              case COMPILE_PLUS_RUNTIME:
80                  return EnumSet.of(compile, system, provided, runtime);
81              case RUNTIME_PLUS_SYSTEM:
82                  return EnumSet.of(compile, system, runtime);
83              case JavaScopes.TEST:
84                  return EnumSet.allOf(Scope.class);
85              default:
86                  throw new IllegalStateException("Scope '" + scope + "' is unknown!");
87          }
88      }
89  
90      private static String computeTransitiveScopes(final String scope) {
91          checkNotNull(scope, "scope is null");
92  
93          switch (scope) {
94              //  runtime dependencies pull in just runtime deps
95              case JavaScopes.RUNTIME:
96                  // compile and runtime pull in compile and runtime
97              case COMPILE_PLUS_RUNTIME:
98                  // runtime and system pull in runtime and system
99              case RUNTIME_PLUS_SYSTEM:
100                 return scope;
101             // test dependencies pull in compile and runtime.
102             case JavaScopes.TEST:
103                 // compile dependencies pull in compile and runtime
104             case JavaScopes.COMPILE:
105                 // provided dependencies pull in just compile and runtime (remove test and provided)
106             case JavaScopes.PROVIDED:
107                 return COMPILE_PLUS_RUNTIME;
108             default:
109                 throw new IllegalStateException("Scope '" + scope + "' is unknown!");
110         }
111     }
112 
113     @Override
114     public boolean accept(final DependencyNode node, final List<DependencyNode> parents) {
115         checkNotNull(node, "node is null");
116 
117         if (node.getDependency() == null) {
118             return true;
119         }
120         final String scope = node.getDependency().getScope();
121         switch (scope) {
122             case JavaScopes.COMPILE:
123                 return scopes.contains(compile);
124             case JavaScopes.TEST:
125                 return scopes.contains(test);
126             case JavaScopes.RUNTIME:
127                 return scopes.contains(runtime);
128             case JavaScopes.PROVIDED:
129                 return scopes.contains(provided);
130             case JavaScopes.SYSTEM:
131                 return scopes.contains(system);
132             default:
133                 return false;
134         }
135     }
136 
137     @Override
138     public String toString() {
139         return MoreObjects.toStringHelper(this)
140                 .add("scopes", scopes)
141                 .toString();
142     }
143 }