package org.eclipse.aether.util.filter;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionRange;
import org.eclipse.aether.version.VersionScheme;

/**
 */
class AbstractPatternDependencyFilter
    implements DependencyFilter
{

    private final Set<String> patterns = new HashSet<>();

    private final VersionScheme versionScheme;

    
Creates a new filter using the specified patterns.
Params:
  • patterns – The include patterns, may be null or empty to include no artifacts.
/** * Creates a new filter using the specified patterns. * * @param patterns The include patterns, may be {@code null} or empty to include no artifacts. */
AbstractPatternDependencyFilter( final String... patterns ) { this( null, patterns ); }
Creates a new filter using the specified patterns.
Params:
  • versionScheme – To be used for parsing versions/version ranges. If null and pattern specifies a range no artifact will be included.
  • patterns – The include patterns, may be null or empty to include no artifacts.
/** * Creates a new filter using the specified patterns. * * @param versionScheme To be used for parsing versions/version ranges. If {@code null} and pattern specifies a * range no artifact will be included. * @param patterns The include patterns, may be {@code null} or empty to include no artifacts. */
AbstractPatternDependencyFilter( final VersionScheme versionScheme, final String... patterns ) { this( versionScheme, patterns == null ? null : Arrays.asList( patterns ) ); }
Creates a new filter using the specified patterns.
Params:
  • patterns – The include patterns, may be null or empty to include no artifacts.
/** * Creates a new filter using the specified patterns. * * @param patterns The include patterns, may be {@code null} or empty to include no artifacts. */
AbstractPatternDependencyFilter( final Collection<String> patterns ) { this( null, patterns ); }
Creates a new filter using the specified patterns and VersionScheme .
Params:
  • versionScheme – To be used for parsing versions/version ranges. If null and pattern specifies a range no artifact will be included.
  • patterns – The include patterns, may be null or empty to include no artifacts.
/** * Creates a new filter using the specified patterns and {@link VersionScheme} . * * @param versionScheme To be used for parsing versions/version ranges. If {@code null} and pattern specifies a * range no artifact will be included. * @param patterns The include patterns, may be {@code null} or empty to include no artifacts. */
AbstractPatternDependencyFilter( final VersionScheme versionScheme, final Collection<String> patterns ) { if ( patterns != null ) { this.patterns.addAll( patterns ); } this.versionScheme = versionScheme; } public boolean accept( final DependencyNode node, List<DependencyNode> parents ) { final Dependency dependency = node.getDependency(); if ( dependency == null ) { return true; } return accept( dependency.getArtifact() ); } protected boolean accept( final Artifact artifact ) { for ( final String pattern : patterns ) { final boolean matched = accept( artifact, pattern ); if ( matched ) { return true; } } return false; } private boolean accept( final Artifact artifact, final String pattern ) { final String[] tokens = new String[] { artifact.getGroupId(), artifact.getArtifactId(), artifact.getExtension(), artifact.getBaseVersion() }; final String[] patternTokens = pattern.split( ":" ); // fail immediately if pattern tokens outnumber tokens to match boolean matched = ( patternTokens.length <= tokens.length ); for ( int i = 0; matched && i < patternTokens.length; i++ ) { matched = matches( tokens[i], patternTokens[i] ); } return matched; } private boolean matches( final String token, final String pattern ) { boolean matches; // support full wildcard and implied wildcard if ( "*".equals( pattern ) || pattern.length() == 0 ) { matches = true; } // support contains wildcard else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) ) { final String contains = pattern.substring( 1, pattern.length() - 1 ); matches = ( token.contains( contains ) ); } // support leading wildcard else if ( pattern.startsWith( "*" ) ) { final String suffix = pattern.substring( 1 ); matches = token.endsWith( suffix ); } // support trailing wildcard else if ( pattern.endsWith( "*" ) ) { final String prefix = pattern.substring( 0, pattern.length() - 1 ); matches = token.startsWith( prefix ); } // support versions range else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) ) { matches = isVersionIncludedInRange( token, pattern ); } // support exact match else { matches = token.equals( pattern ); } return matches; } private boolean isVersionIncludedInRange( final String version, final String range ) { if ( versionScheme == null ) { return false; } else { try { final Version parsedVersion = versionScheme.parseVersion( version ); final VersionRange parsedRange = versionScheme.parseVersionRange( range ); return parsedRange.containsVersion( parsedVersion ); } catch ( final InvalidVersionSpecificationException e ) { return false; } } } @Override public boolean equals( final Object obj ) { if ( this == obj ) { return true; } if ( obj == null || !getClass().equals( obj.getClass() ) ) { return false; } final AbstractPatternDependencyFilter that = (AbstractPatternDependencyFilter) obj; return Objects.equals( this.patterns, that.patterns ) && Objects.equals( this.versionScheme, that.versionScheme ); } @Override public int hashCode() { int hash = 17; hash = hash * 31 + patterns.hashCode(); hash = hash * 31 + ( ( versionScheme == null ) ? 0 : versionScheme.hashCode() ); return hash; } }