001package org.eclipse.aether.collection;
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.Iterator;
023import java.util.List;
024
025import org.eclipse.aether.RepositoryException;
026import org.eclipse.aether.RepositorySystemSession;
027import org.eclipse.aether.graph.Dependency;
028import org.eclipse.aether.repository.ArtifactRepository;
029import org.eclipse.aether.repository.RemoteRepository;
030import org.eclipse.aether.version.Version;
031import org.eclipse.aether.version.VersionConstraint;
032
033/**
034 * Decides which versions matching a version range should actually be considered for the dependency graph. The version
035 * filter is not invoked for dependencies that do not declare a version range but a single version.
036 * <p>
037 * <strong>Note:</strong> Implementations must be stateless.
038 * <p>
039 * <em>Warning:</em> This hook is called from a hot spot and therefore implementations should pay attention to
040 * performance. Among others, implementations should provide a semantic {@link Object#equals(Object) equals()} method.
041 * 
042 * @see org.eclipse.aether.RepositorySystemSession#getVersionFilter()
043 * @see org.eclipse.aether.RepositorySystem#collectDependencies(org.eclipse.aether.RepositorySystemSession,
044 *      CollectRequest)
045 */
046public interface VersionFilter
047{
048
049    /**
050     * A context used during version filtering to hold relevant data.
051     * 
052     * @noimplement This interface is not intended to be implemented by clients.
053     * @noextend This interface is not intended to be extended by clients.
054     */
055    interface VersionFilterContext
056        extends Iterable<Version>
057    {
058
059        /**
060         * Gets the repository system session during which the version filtering happens.
061         * 
062         * @return The repository system session, never {@code null}.
063         */
064        RepositorySystemSession getSession();
065
066        /**
067         * Gets the dependency whose version range is being filtered.
068         * 
069         * @return The dependency, never {@code null}.
070         */
071        Dependency getDependency();
072
073        /**
074         * Gets the total number of available versions. This count reflects any removals made during version filtering.
075         * 
076         * @return The total number of available versions.
077         */
078        int getCount();
079
080        /**
081         * Gets an iterator over the available versions of the dependency. The iterator returns versions in ascending
082         * order. Use {@link Iterator#remove()} to exclude a version from further consideration in the dependency graph.
083         * 
084         * @return The iterator of available versions, never {@code null}.
085         */
086        Iterator<Version> iterator();
087
088        /**
089         * Gets the version constraint that was parsed from the dependency's version string.
090         * 
091         * @return The parsed version constraint, never {@code null}.
092         */
093        VersionConstraint getVersionConstraint();
094
095        /**
096         * Gets the repository from which the specified version was resolved.
097         * 
098         * @param version The version whose source repository should be retrieved, must not be {@code null}.
099         * @return The repository from which the version was resolved or {@code null} if unknown.
100         */
101        ArtifactRepository getRepository( Version version );
102
103        /**
104         * Gets the remote repositories from which the versions were resolved.
105         * 
106         * @return The (read-only) list of repositories, never {@code null}.
107         */
108        List<RemoteRepository> getRepositories();
109
110    }
111
112    /**
113     * Filters the available versions for a given dependency. Implementations will usually call
114     * {@link VersionFilterContext#iterator() context.iterator()} to inspect the available versions and use
115     * {@link java.util.Iterator#remove()} to delete unacceptable versions. If no versions remain after all filtering
116     * has been performed, the dependency collection process will automatically fail, i.e. implementations need not
117     * handle this situation on their own.
118     * 
119     * @param context The version filter context, must not be {@code null}.
120     * @throws RepositoryException If the filtering could not be performed.
121     */
122    void filterVersions( VersionFilterContext context )
123        throws RepositoryException;
124
125    /**
126     * Derives a version filter for the specified collection context. The derived filter will be used to handle version
127     * ranges encountered in child dependencies of the current node. When calculating the child filter, implementors are
128     * strongly advised to simply return the current instance if nothing changed to help save memory.
129     * 
130     * @param context The dependency collection context, must not be {@code null}.
131     * @return The version filter for the target node or {@code null} if versions should not be filtered any more.
132     */
133    VersionFilter deriveChildFilter( DependencyCollectionContext context );
134
135}