001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.util.filter; 020 021import java.util.Arrays; 022import java.util.Collection; 023import java.util.Collections; 024import java.util.HashSet; 025 026import org.eclipse.aether.graph.DependencyFilter; 027import org.eclipse.aether.util.artifact.JavaScopes; 028 029/** 030 * A utility class assisting in the creation of dependency node filters. 031 */ 032public final class DependencyFilterUtils { 033 034 private DependencyFilterUtils() { 035 // hide constructor 036 } 037 038 /** 039 * Creates a new filter that negates the specified filter. 040 * 041 * @param filter The filter to negate, must not be {@code null}. 042 * @return The new filter, never {@code null}. 043 */ 044 public static DependencyFilter notFilter(DependencyFilter filter) { 045 return new NotDependencyFilter(filter); 046 } 047 048 /** 049 * Creates a new filter that combines the specified filters using a logical {@code AND}. If no filters are 050 * specified, the resulting filter accepts everything. 051 * 052 * @param filters The filters to combine, may be {@code null}. 053 * @return The new filter, never {@code null}. 054 */ 055 public static DependencyFilter andFilter(DependencyFilter... filters) { 056 if (filters != null && filters.length == 1) { 057 return filters[0]; 058 } else { 059 return new AndDependencyFilter(filters); 060 } 061 } 062 063 /** 064 * Creates a new filter that combines the specified filters using a logical {@code AND}. If no filters are 065 * specified, the resulting filter accepts everything. 066 * 067 * @param filters The filters to combine, may be {@code null}. 068 * @return The new filter, never {@code null}. 069 */ 070 public static DependencyFilter andFilter(Collection<DependencyFilter> filters) { 071 if (filters != null && filters.size() == 1) { 072 return filters.iterator().next(); 073 } else { 074 return new AndDependencyFilter(filters); 075 } 076 } 077 078 /** 079 * Creates a new filter that combines the specified filters using a logical {@code OR}. If no filters are specified, 080 * the resulting filter accepts nothing. 081 * 082 * @param filters The filters to combine, may be {@code null}. 083 * @return The new filter, never {@code null}. 084 */ 085 public static DependencyFilter orFilter(DependencyFilter... filters) { 086 if (filters != null && filters.length == 1) { 087 return filters[0]; 088 } else { 089 return new OrDependencyFilter(filters); 090 } 091 } 092 093 /** 094 * Creates a new filter that combines the specified filters using a logical {@code OR}. If no filters are specified, 095 * the resulting filter accepts nothing. 096 * 097 * @param filters The filters to combine, may be {@code null}. 098 * @return The new filter, never {@code null}. 099 */ 100 public static DependencyFilter orFilter(Collection<DependencyFilter> filters) { 101 if (filters != null && filters.size() == 1) { 102 return filters.iterator().next(); 103 } else { 104 return new OrDependencyFilter(filters); 105 } 106 } 107 108 /** 109 * Creates a new filter that selects dependencies whose scope matches one or more of the specified classpath types. 110 * A classpath type is a set of scopes separated by either {@code ','} or {@code '+'}. 111 * 112 * @param classpathTypes The classpath types, may be {@code null} or empty to match no dependency. 113 * @return The new filter, never {@code null}. 114 * @see JavaScopes 115 */ 116 public static DependencyFilter classpathFilter(String... classpathTypes) { 117 return classpathFilter((classpathTypes != null) ? Arrays.asList(classpathTypes) : null); 118 } 119 120 /** 121 * Creates a new filter that selects dependencies whose scope matches one or more of the specified classpath types. 122 * A classpath type is a set of scopes separated by either {@code ','} or {@code '+'}. 123 * 124 * @param classpathTypes The classpath types, may be {@code null} or empty to match no dependency. 125 * @return The new filter, never {@code null}. 126 * @see JavaScopes 127 */ 128 public static DependencyFilter classpathFilter(Collection<String> classpathTypes) { 129 Collection<String> types = new HashSet<>(); 130 131 if (classpathTypes != null) { 132 for (String classpathType : classpathTypes) { 133 String[] tokens = classpathType.split("[+,]"); 134 for (String token : tokens) { 135 token = token.trim(); 136 if (token.length() > 0) { 137 types.add(token); 138 } 139 } 140 } 141 } 142 143 Collection<String> included = new HashSet<>(); 144 for (String type : types) { 145 if (JavaScopes.COMPILE.equals(type)) { 146 Collections.addAll(included, JavaScopes.COMPILE, JavaScopes.PROVIDED, JavaScopes.SYSTEM); 147 } else if (JavaScopes.RUNTIME.equals(type)) { 148 Collections.addAll(included, JavaScopes.COMPILE, JavaScopes.RUNTIME); 149 } else if (JavaScopes.TEST.equals(type)) { 150 Collections.addAll( 151 included, 152 JavaScopes.COMPILE, 153 JavaScopes.PROVIDED, 154 JavaScopes.SYSTEM, 155 JavaScopes.RUNTIME, 156 JavaScopes.TEST); 157 } else { 158 included.add(type); 159 } 160 } 161 162 Collection<String> excluded = new HashSet<>(); 163 Collections.addAll( 164 excluded, 165 JavaScopes.COMPILE, 166 JavaScopes.PROVIDED, 167 JavaScopes.SYSTEM, 168 JavaScopes.RUNTIME, 169 JavaScopes.TEST); 170 excluded.removeAll(included); 171 172 return new ScopeDependencyFilter(null, excluded); 173 } 174}