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.Collection;
022import java.util.Collections;
023import java.util.LinkedHashSet;
024import java.util.List;
025import java.util.Set;
026
027import org.eclipse.aether.graph.DependencyFilter;
028import org.eclipse.aether.graph.DependencyNode;
029
030/**
031 * A dependency filter that combines zero or more other filters using a logical {@code OR}.
032 */
033public final class OrDependencyFilter implements DependencyFilter {
034
035    private final Set<DependencyFilter> filters = new LinkedHashSet<>();
036
037    /**
038     * Creates a new filter from the specified filters.
039     *
040     * @param filters The filters to combine, may be {@code null}.
041     */
042    public OrDependencyFilter(DependencyFilter... filters) {
043        if (filters != null) {
044            Collections.addAll(this.filters, filters);
045        }
046    }
047
048    /**
049     * Creates a new filter from the specified filters.
050     *
051     * @param filters The filters to combine, may be {@code null}.
052     */
053    public OrDependencyFilter(Collection<DependencyFilter> filters) {
054        if (filters != null) {
055            this.filters.addAll(filters);
056        }
057    }
058
059    /**
060     * Creates a new filter from the specified filters.
061     *
062     * @param filter1 The first filter to combine, may be {@code null}.
063     * @param filter2 The first filter to combine, may be {@code null}.
064     * @return The combined filter or {@code null} if both filter were {@code null}.
065     */
066    public static DependencyFilter newInstance(DependencyFilter filter1, DependencyFilter filter2) {
067        if (filter1 == null) {
068            return filter2;
069        } else if (filter2 == null) {
070            return filter1;
071        }
072        return new OrDependencyFilter(filter1, filter2);
073    }
074
075    public boolean accept(DependencyNode node, List<DependencyNode> parents) {
076        for (DependencyFilter filter : filters) {
077            if (filter.accept(node, parents)) {
078                return true;
079            }
080        }
081        return false;
082    }
083
084    @Override
085    public boolean equals(Object obj) {
086        if (this == obj) {
087            return true;
088        }
089
090        if (obj == null || !getClass().equals(obj.getClass())) {
091            return false;
092        }
093
094        OrDependencyFilter that = (OrDependencyFilter) obj;
095
096        return this.filters.equals(that.filters);
097    }
098
099    @Override
100    public int hashCode() {
101        int hash = getClass().hashCode();
102        hash = hash * 31 + filters.hashCode();
103        return hash;
104    }
105}