001package org.eclipse.aether.util.filter;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 * 
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 * 
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.Collection;
023import java.util.Collections;
024import java.util.LinkedHashSet;
025import java.util.List;
026import java.util.Set;
027
028import org.eclipse.aether.graph.DependencyFilter;
029import org.eclipse.aether.graph.DependencyNode;
030
031/**
032 * A dependency filter that combines zero or more other filters using a logical {@code AND}. The resulting filter
033 * accepts a given dependency node if and only if all constituent filters accept it.
034 */
035public final class AndDependencyFilter
036    implements DependencyFilter
037{
038
039    private final Set<DependencyFilter> filters = new LinkedHashSet<DependencyFilter>();
040
041    /**
042     * Creates a new filter from the specified filters. Prefer {@link #newInstance(DependencyFilter, DependencyFilter)}
043     * if any of the input filters might be {@code null}.
044     * 
045     * @param filters The filters to combine, may be {@code null} but must not contain {@code null} elements.
046     */
047    public AndDependencyFilter( DependencyFilter... filters )
048    {
049        if ( filters != null )
050        {
051            Collections.addAll( this.filters, filters );
052        }
053    }
054
055    /**
056     * Creates a new filter from the specified filters.
057     * 
058     * @param filters The filters to combine, may be {@code null} but must not contain {@code null} elements.
059     */
060    public AndDependencyFilter( Collection<DependencyFilter> filters )
061    {
062        if ( filters != null )
063        {
064            this.filters.addAll( filters );
065        }
066    }
067
068    /**
069     * Creates a new filter from the specified filters.
070     * 
071     * @param filter1 The first filter to combine, may be {@code null}.
072     * @param filter2 The second filter to combine, may be {@code null}.
073     * @return The combined filter or {@code null} if both filter were {@code null}.
074     */
075    public static DependencyFilter newInstance( DependencyFilter filter1, DependencyFilter filter2 )
076    {
077        if ( filter1 == null )
078        {
079            return filter2;
080        }
081        else if ( filter2 == null )
082        {
083            return filter1;
084        }
085        return new AndDependencyFilter( filter1, filter2 );
086    }
087
088    public boolean accept( DependencyNode node, List<DependencyNode> parents )
089    {
090        for ( DependencyFilter filter : filters )
091        {
092            if ( !filter.accept( node, parents ) )
093            {
094                return false;
095            }
096        }
097        return true;
098    }
099
100    @Override
101    public boolean equals( Object obj )
102    {
103        if ( this == obj )
104        {
105            return true;
106        }
107
108        if ( obj == null || !getClass().equals( obj.getClass() ) )
109        {
110            return false;
111        }
112
113        AndDependencyFilter that = (AndDependencyFilter) obj;
114
115        return this.filters.equals( that.filters );
116    }
117
118    @Override
119    public int hashCode()
120    {
121        int hash = getClass().hashCode();
122        hash = hash * 31 + filters.hashCode();
123        return hash;
124    }
125
126}