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.internal.test.util;
020
021import org.eclipse.aether.RepositorySystemSession;
022import org.eclipse.aether.artifact.Artifact;
023import org.eclipse.aether.resolution.ArtifactDescriptorException;
024import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
025import org.eclipse.aether.resolution.ArtifactDescriptorResult;
026
027import static java.util.Objects.requireNonNull;
028
029/**
030 * An artifact descriptor reader that gets data from a simple text file on the classpath. The data file for an artifact
031 * with the coordinates {@code gid:aid:ext:ver} is expected to be named {@code gid_aid_ver.ini} and can optionally have
032 * some prefix. The data file can have the following sections:
033 * <ul>
034 * <li>relocation</li>
035 * <li>dependencies</li>
036 * <li>managedDependencies</li>
037 * <li>repositories</li>
038 * </ul>
039 * The relocation and dependency sections contain artifact coordinates of the form:
040 *
041 * <pre>
042 * gid:aid:ext:ver[:scope][:optional]
043 * </pre>
044 *
045 * The dependency sections may also specify exclusions:
046 *
047 * <pre>
048 * -gid:aid
049 * </pre>
050 *
051 * A repository definition is of the form:
052 *
053 * <pre>
054 * id:type:url
055 * </pre>
056 *
057 * <h2>Example</h2>
058 *
059 * <pre>
060 * [relocation]
061 * gid:aid:ext:ver
062 *
063 * [dependencies]
064 * gid:aid:ext:ver:scope
065 * -exclusion:aid
066 * gid:aid2:ext:ver:scope:optional
067 *
068 * [managed-dependencies]
069 * gid:aid2:ext:ver2:scope
070 * -gid:aid
071 * -gid:aid
072 *
073 * [repositories]
074 * id:type:file:///test-repo
075 * </pre>
076 */
077public class IniArtifactDescriptorReader {
078    private final IniArtifactDataReader reader;
079
080    /**
081     * Use the given prefix to load the artifact descriptions from the classpath.
082     */
083    public IniArtifactDescriptorReader(String prefix) {
084        reader = new IniArtifactDataReader(prefix);
085    }
086
087    /**
088     * Parses the resource {@code $prefix/gid_aid_ver.ini} from the request artifact as an artifact description and
089     * wraps it into an ArtifactDescriptorResult.
090     */
091    public ArtifactDescriptorResult readArtifactDescriptor(
092            RepositorySystemSession session, ArtifactDescriptorRequest request) throws ArtifactDescriptorException {
093        requireNonNull(session, "session cannot be null");
094        requireNonNull(request, "request cannot be null");
095        ArtifactDescriptorResult result = new ArtifactDescriptorResult(request);
096        for (Artifact artifact = request.getArtifact(); ; ) {
097            String resourceName = String.format(
098                    "%s_%s_%s.ini", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
099            try {
100                ArtifactDescription data = reader.parse(resourceName);
101                if (data.getRelocation() != null) {
102                    result.addRelocation(artifact);
103                    result.setArtifact(data.getRelocation());
104                    artifact = data.getRelocation();
105                } else {
106                    result.setArtifact(artifact);
107                    result.setDependencies(data.getDependencies());
108                    result.setManagedDependencies(data.getManagedDependencies());
109                    result.setRepositories(data.getRepositories());
110                    return result;
111                }
112            } catch (Exception e) {
113                throw new ArtifactDescriptorException(result, e.getMessage(), e);
114            }
115        }
116    }
117}