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.artifact;
020
021import java.util.Objects;
022
023import org.eclipse.aether.artifact.Artifact;
024
025/**
026 * A utility class for artifact identifiers.
027 */
028public final class ArtifactIdUtils {
029
030    private static final char SEP = ':';
031
032    private ArtifactIdUtils() {
033        // hide constructor
034    }
035
036    /**
037     * Creates an artifact identifier of the form {@code <groupId>:<artifactId>:<extension>[:<classifier>]:<version>}.
038     *
039     * @param artifact The artifact to create an identifer for, may be {@code null}.
040     * @return The artifact identifier or {@code null} if the input was {@code null}.
041     */
042    public static String toId(Artifact artifact) {
043        String id = null;
044        if (artifact != null) {
045            id = toId(
046                    artifact.getGroupId(),
047                    artifact.getArtifactId(),
048                    artifact.getExtension(),
049                    artifact.getClassifier(),
050                    artifact.getVersion());
051        }
052        return id;
053    }
054
055    /**
056     * Creates an artifact identifier of the form {@code <groupId>:<artifactId>:<extension>[:<classifier>]:<version>}.
057     *
058     * @param groupId The group id, may be {@code null}.
059     * @param artifactId The artifact id, may be {@code null}.
060     * @param extension The file extensiion, may be {@code null}.
061     * @param classifier The classifier, may be {@code null}.
062     * @param version The version, may be {@code null}.
063     * @return The artifact identifier, never {@code null}.
064     */
065    public static String toId(String groupId, String artifactId, String extension, String classifier, String version) {
066        StringBuilder buffer = concat(groupId, artifactId, extension, classifier);
067        buffer.append(SEP);
068        if (version != null) {
069            buffer.append(version);
070        }
071        return buffer.toString();
072    }
073
074    /**
075     * Creates an artifact identifier of the form
076     * {@code <groupId>:<artifactId>:<extension>[:<classifier>]:<baseVersion>}.
077     *
078     * @param artifact The artifact to create an identifer for, may be {@code null}.
079     * @return The artifact identifier or {@code null} if the input was {@code null}.
080     */
081    public static String toBaseId(Artifact artifact) {
082        String id = null;
083        if (artifact != null) {
084            id = toId(
085                    artifact.getGroupId(),
086                    artifact.getArtifactId(),
087                    artifact.getExtension(),
088                    artifact.getClassifier(),
089                    artifact.getBaseVersion());
090        }
091        return id;
092    }
093
094    /**
095     * Creates an artifact identifier of the form {@code <groupId>:<artifactId>:<extension>[:<classifier>]}.
096     *
097     * @param artifact The artifact to create an identifer for, may be {@code null}.
098     * @return The artifact identifier or {@code null} if the input was {@code null}.
099     */
100    public static String toVersionlessId(Artifact artifact) {
101        String id = null;
102        if (artifact != null) {
103            id = toVersionlessId(
104                    artifact.getGroupId(), artifact.getArtifactId(), artifact.getExtension(), artifact.getClassifier());
105        }
106        return id;
107    }
108
109    /**
110     * Creates an artifact identifier of the form {@code <groupId>:<artifactId>:<extension>[:<classifier>]}.
111     *
112     * @param groupId The group id, may be {@code null}.
113     * @param artifactId The artifact id, may be {@code null}.
114     * @param extension The file extensiion, may be {@code null}.
115     * @param classifier The classifier, may be {@code null}.
116     * @return The artifact identifier, never {@code null}.
117     */
118    public static String toVersionlessId(String groupId, String artifactId, String extension, String classifier) {
119        return concat(groupId, artifactId, extension, classifier).toString();
120    }
121
122    private static StringBuilder concat(String groupId, String artifactId, String extension, String classifier) {
123        StringBuilder buffer = new StringBuilder(128);
124
125        if (groupId != null) {
126            buffer.append(groupId);
127        }
128        buffer.append(SEP);
129        if (artifactId != null) {
130            buffer.append(artifactId);
131        }
132        buffer.append(SEP);
133        if (extension != null) {
134            buffer.append(extension);
135        }
136        if (classifier != null && !classifier.isEmpty()) {
137            buffer.append(SEP).append(classifier);
138        }
139
140        return buffer;
141    }
142
143    /**
144     * Determines whether two artifacts have the same identifier. This method is equivalent to calling
145     * {@link String#equals(Object)} on the return values from {@link #toId(Artifact)} for the artifacts but does not
146     * incur the overhead of creating temporary strings.
147     *
148     * @param artifact1 The first artifact, may be {@code null}.
149     * @param artifact2 The second artifact, may be {@code null}.
150     * @return {@code true} if both artifacts are not {@code null} and have equal ids, {@code false} otherwise.
151     */
152    public static boolean equalsId(Artifact artifact1, Artifact artifact2) {
153        if (artifact1 == null || artifact2 == null) {
154            return false;
155        }
156        if (!Objects.equals(artifact1.getArtifactId(), artifact2.getArtifactId())) {
157            return false;
158        }
159        if (!Objects.equals(artifact1.getGroupId(), artifact2.getGroupId())) {
160            return false;
161        }
162        if (!Objects.equals(artifact1.getExtension(), artifact2.getExtension())) {
163            return false;
164        }
165        if (!Objects.equals(artifact1.getClassifier(), artifact2.getClassifier())) {
166            return false;
167        }
168        return Objects.equals(artifact1.getVersion(), artifact2.getVersion());
169    }
170
171    /**
172     * Determines whether two artifacts have the same base identifier. This method is equivalent to calling
173     * {@link String#equals(Object)} on the return values from {@link #toBaseId(Artifact)} for the artifacts but does
174     * not incur the overhead of creating temporary strings.
175     *
176     * @param artifact1 The first artifact, may be {@code null}.
177     * @param artifact2 The second artifact, may be {@code null}.
178     * @return {@code true} if both artifacts are not {@code null} and have equal base ids, {@code false} otherwise.
179     */
180    public static boolean equalsBaseId(Artifact artifact1, Artifact artifact2) {
181        if (artifact1 == null || artifact2 == null) {
182            return false;
183        }
184        if (!Objects.equals(artifact1.getArtifactId(), artifact2.getArtifactId())) {
185            return false;
186        }
187        if (!Objects.equals(artifact1.getGroupId(), artifact2.getGroupId())) {
188            return false;
189        }
190        if (!Objects.equals(artifact1.getExtension(), artifact2.getExtension())) {
191            return false;
192        }
193        if (!Objects.equals(artifact1.getClassifier(), artifact2.getClassifier())) {
194            return false;
195        }
196        return Objects.equals(artifact1.getBaseVersion(), artifact2.getBaseVersion());
197    }
198
199    /**
200     * Determines whether two artifacts have the same versionless identifier. This method is equivalent to calling
201     * {@link String#equals(Object)} on the return values from {@link #toVersionlessId(Artifact)} for the artifacts but
202     * does not incur the overhead of creating temporary strings.
203     *
204     * @param artifact1 The first artifact, may be {@code null}.
205     * @param artifact2 The second artifact, may be {@code null}.
206     * @return {@code true} if both artifacts are not {@code null} and have equal versionless ids, {@code false}
207     *         otherwise.
208     */
209    public static boolean equalsVersionlessId(Artifact artifact1, Artifact artifact2) {
210        if (artifact1 == null || artifact2 == null) {
211            return false;
212        }
213        if (!Objects.equals(artifact1.getArtifactId(), artifact2.getArtifactId())) {
214            return false;
215        }
216        if (!Objects.equals(artifact1.getGroupId(), artifact2.getGroupId())) {
217            return false;
218        }
219        if (!Objects.equals(artifact1.getExtension(), artifact2.getExtension())) {
220            return false;
221        }
222        return Objects.equals(artifact1.getClassifier(), artifact2.getClassifier());
223    }
224}