View Javadoc
1   package org.eclipse.aether.util.graph.version;
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.Arrays;
23  import java.util.Collection;
24  
25  import org.eclipse.aether.RepositoryException;
26  import org.eclipse.aether.collection.DependencyCollectionContext;
27  import org.eclipse.aether.collection.VersionFilter;
28  
29  /**
30   * A version filter that combines multiple version filters into a chain where each filter gets invoked one after the
31   * other, thereby accumulating their filtering effects.
32   */
33  public final class ChainedVersionFilter
34      implements VersionFilter
35  {
36  
37      private final VersionFilter[] filters;
38  
39      private int hashCode;
40  
41      /**
42       * Chains the specified version filters.
43       * 
44       * @param filter1 The first version filter, may be {@code null}.
45       * @param filter2 The second version filter, may be {@code null}.
46       * @return The chained version filter or {@code null} if both input filters are {@code null}.
47       */
48      public static VersionFilter newInstance( VersionFilter filter1, VersionFilter filter2 )
49      {
50          if ( filter1 == null )
51          {
52              return filter2;
53          }
54          if ( filter2 == null )
55          {
56              return filter1;
57          }
58          return new ChainedVersionFilter( new VersionFilter[] { filter1, filter2 } );
59      }
60  
61      /**
62       * Chains the specified version filters.
63       * 
64       * @param filters The version filters to chain, must not be {@code null} or contain {@code null}.
65       * @return The chained version filter or {@code null} if the input array is empty.
66       */
67      public static VersionFilter newInstance( VersionFilter... filters )
68      {
69          if ( filters.length <= 1 )
70          {
71              if ( filters.length <= 0 )
72              {
73                  return null;
74              }
75              return filters[0];
76          }
77          return new ChainedVersionFilter( filters.clone() );
78      }
79  
80      /**
81       * Chains the specified version filters.
82       * 
83       * @param filters The version filters to chain, must not be {@code null} or contain {@code null}.
84       * @return The chained version filter or {@code null} if the input collection is empty.
85       */
86      public static VersionFilter newInstance( Collection<? extends VersionFilter> filters )
87      {
88          if ( filters.size() <= 1 )
89          {
90              if ( filters.isEmpty() )
91              {
92                  return null;
93              }
94              return filters.iterator().next();
95          }
96          return new ChainedVersionFilter( filters.toArray( new VersionFilter[filters.size()] ) );
97      }
98  
99      private ChainedVersionFilter( VersionFilter[] filters )
100     {
101         this.filters = filters;
102     }
103 
104     public void filterVersions( VersionFilterContext context )
105         throws RepositoryException
106     {
107         for ( int i = 0, n = filters.length; i < n && context.getCount() > 0; i++ )
108         {
109             filters[i].filterVersions( context );
110         }
111     }
112 
113     public VersionFilter deriveChildFilter( DependencyCollectionContext context )
114     {
115         VersionFilter[] children = null;
116         int removed = 0;
117         for ( int i = 0, n = filters.length; i < n; i++ )
118         {
119             VersionFilter child = filters[i].deriveChildFilter( context );
120             if ( children != null )
121             {
122                 children[i - removed] = child;
123             }
124             else if ( child != filters[i] )
125             {
126                 children = new VersionFilter[filters.length];
127                 System.arraycopy( filters, 0, children, 0, i );
128                 children[i - removed] = child;
129             }
130             if ( child == null )
131             {
132                 removed++;
133             }
134         }
135         if ( children == null )
136         {
137             return this;
138         }
139         if ( removed > 0 )
140         {
141             int count = filters.length - removed;
142             if ( count <= 0 )
143             {
144                 return null;
145             }
146             if ( count == 1 )
147             {
148                 return children[0];
149             }
150             VersionFilter[] tmp = new VersionFilter[count];
151             System.arraycopy( children, 0, tmp, 0, count );
152             children = tmp;
153         }
154         return new ChainedVersionFilter( children );
155     }
156 
157     @Override
158     public boolean equals( Object obj )
159     {
160         if ( this == obj )
161         {
162             return true;
163         }
164         else if ( null == obj || !getClass().equals( obj.getClass() ) )
165         {
166             return false;
167         }
168 
169         ChainedVersionFilter that = (ChainedVersionFilter) obj;
170         return Arrays.equals( filters, that.filters );
171     }
172 
173     @Override
174     public int hashCode()
175     {
176         if ( hashCode == 0 )
177         {
178             int hash = getClass().hashCode();
179             hash = hash * 31 + Arrays.hashCode( filters );
180             hashCode = hash;
181         }
182         return hashCode;
183     }
184 
185 }