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;
020
021import java.util.Map;
022
023import org.eclipse.aether.artifact.Artifact;
024import org.eclipse.aether.artifact.ArtifactProperties;
025import org.eclipse.aether.graph.Dependency;
026import org.eclipse.aether.graph.DependencyNode;
027
028/**
029 * In Resolver 1.x line, the "system" scope represented special artifacts. In 2.x resolver testing for this scope
030 * is now delegated to consumer application. Class or component that wants to test for this special dependency scope
031 * should use this interface, with implementation provided by consumer application.
032 * <p>
033 * System is a special scope that tells resolver that dependency is not to be found in any regular repository, so it
034 * should not even try to resolve the artifact from them. Dependency in this scope does not have artifact descriptor
035 * either. Artifacts in this scope should have the "local path" property set, pointing to a file on local system, where
036 * the backing file should reside. Resolution of artifacts in this scope fails, if backing file does not exist
037 * (no property set, or property contains invalid path, or the path points to a non-existent file).
038 *
039 * @since 2.0.0
040 */
041public interface SystemScopeHandler {
042    /**
043     * Returns {@code true} only, if passed in scope label represents "system" scope (as consumer project defines it).
044     */
045    boolean isSystemScope(String scope);
046
047    /**
048     * Returns {@code true} if given dependency is in "system" scope.
049     */
050    default boolean isSystemScope(Dependency dependency) {
051        return dependency != null && isSystemScope(dependency.getScope());
052    }
053
054    /**
055     * Returns {@code true} if given dependency node dependency is in "system" scope.
056     */
057    default boolean isSystemScope(DependencyNode dependencyNode) {
058        return dependencyNode != null
059                && dependencyNode.getDependency() != null
060                && isSystemScope(dependencyNode.getDependency());
061    }
062
063    /**
064     * Returns system path string of provided artifact, or {@code null}.
065     *
066     * @param artifact The artifact that we want system path from, must not be {@code null}.
067     * @return the system path from passed in properties, or {@code null} if not present.
068     */
069    String getSystemPath(Artifact artifact);
070
071    /**
072     * Sets system path in properties. The passed in {@code systemPath} can be {@code null}, in which case expected
073     * operation is "remove" (or "unset").
074     *
075     * @param properties the properties map, must not be {@code null}.
076     * @param systemPath the system path to set (if not {@code null}) or unset (if {@code null}).
077     */
078    void setSystemPath(Map<String, String> properties, String systemPath);
079
080    /**
081     * The equivalent of Resolver 1.x "system" scope.
082     */
083    SystemScopeHandler LEGACY = new SystemScopeHandler() {
084        @Override
085        public boolean isSystemScope(String scope) {
086            return "system".equals(scope);
087        }
088
089        @Override
090        public String getSystemPath(Artifact artifact) {
091            return artifact.getProperty(ArtifactProperties.LOCAL_PATH, null);
092        }
093
094        @Override
095        public void setSystemPath(Map<String, String> properties, String systemPath) {
096            if (systemPath == null) {
097                properties.remove(ArtifactProperties.LOCAL_PATH);
098            } else {
099                properties.put(ArtifactProperties.LOCAL_PATH, systemPath);
100            }
101        }
102    };
103}