View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.artifact;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.LinkedHashMap;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Objects;
27  import java.util.regex.Matcher;
28  
29  import org.apache.maven.artifact.versioning.VersionRange;
30  
31  /**
32   * ArtifactUtils
33   */
34  public final class ArtifactUtils {
35  
36      public static boolean isSnapshot(String version) {
37          if (version != null) {
38              if (version.regionMatches(
39                      true,
40                      version.length() - Artifact.SNAPSHOT_VERSION.length(),
41                      Artifact.SNAPSHOT_VERSION,
42                      0,
43                      Artifact.SNAPSHOT_VERSION.length())) {
44                  return true;
45              } else if (Artifact.VERSION_FILE_PATTERN.matcher(version).matches()) {
46                  return true;
47              }
48          }
49          return false;
50      }
51  
52      public static String toSnapshotVersion(String version) {
53          notBlank(version, "version can neither be null, empty nor blank");
54  
55          int lastHyphen = version.lastIndexOf('-');
56          if (lastHyphen > 0) {
57              int prevHyphen = version.lastIndexOf('-', lastHyphen - 1);
58              if (prevHyphen > 0) {
59                  Matcher m = Artifact.VERSION_FILE_PATTERN.matcher(version);
60                  if (m.matches()) {
61                      return m.group(1) + "-" + Artifact.SNAPSHOT_VERSION;
62                  }
63              }
64          }
65          return version;
66      }
67  
68      public static String versionlessKey(Artifact artifact) {
69          return versionlessKey(artifact.getGroupId(), artifact.getArtifactId());
70      }
71  
72      public static String versionlessKey(String groupId, String artifactId) {
73          notBlank(groupId, "groupId can neither be null, empty nor blank");
74          notBlank(artifactId, "artifactId can neither be null, empty nor blank");
75  
76          return groupId + ":" + artifactId;
77      }
78  
79      public static String key(Artifact artifact) {
80          return key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
81      }
82  
83      public static String key(String groupId, String artifactId, String version) {
84          notBlank(groupId, "groupId can neither be null, empty nor blank");
85          notBlank(artifactId, "artifactId can neither be null, empty nor blank");
86          notBlank(version, "version can neither be null, empty nor blank");
87  
88          return groupId + ":" + artifactId + ":" + version;
89      }
90  
91      private static void notBlank(String str, String message) {
92          int c = str != null && !str.isEmpty() ? str.charAt(0) : 0;
93          if ((c < '0' || c > '9') && (c < 'a' || c > 'z')) {
94              if (Objects.requireNonNull(str, message).trim().isEmpty()) {
95                  throw new IllegalArgumentException(message);
96              }
97          }
98      }
99  
100     public static Map<String, Artifact> artifactMapByVersionlessId(Collection<Artifact> artifacts) {
101         Map<String, Artifact> artifactMap = new LinkedHashMap<>();
102 
103         if (artifacts != null) {
104             for (Artifact artifact : artifacts) {
105                 artifactMap.put(versionlessKey(artifact), artifact);
106             }
107         }
108 
109         return artifactMap;
110     }
111 
112     public static Artifact copyArtifactSafe(Artifact artifact) {
113         return (artifact != null) ? copyArtifact(artifact) : null;
114     }
115 
116     public static Artifact copyArtifact(Artifact artifact) {
117         VersionRange range = artifact.getVersionRange();
118 
119         // For some reason with the introduction of MNG-1577 we have the case in Yoko where a depMan section has
120         // something like the following:
121         //
122         // <dependencyManagement>
123         //     <dependencies>
124         //         <!--  Yoko modules -->
125         //         <dependency>
126         //             <groupId>org.apache.yoko</groupId>
127         //             <artifactId>yoko-core</artifactId>
128         //             <version>${version}</version>
129         //         </dependency>
130         // ...
131         //
132         // And the range is not set so we'll check here and set it. jvz.
133 
134         if (range == null) {
135             range = VersionRange.createFromVersion(artifact.getVersion());
136         }
137 
138         DefaultArtifact clone = new DefaultArtifact(
139                 artifact.getGroupId(),
140                 artifact.getArtifactId(),
141                 range,
142                 artifact.getScope(),
143                 artifact.getType(),
144                 artifact.getClassifier(),
145                 artifact.getArtifactHandler(),
146                 artifact.isOptional());
147         clone.setRelease(artifact.isRelease());
148         clone.setResolvedVersion(artifact.getVersion());
149         clone.setResolved(artifact.isResolved());
150         clone.setFile(artifact.getFile());
151 
152         clone.setAvailableVersions(copyList(artifact.getAvailableVersions()));
153         if (artifact.getVersion() != null) {
154             clone.setBaseVersion(artifact.getBaseVersion());
155         }
156         clone.setDependencyFilter(artifact.getDependencyFilter());
157         clone.setDependencyTrail(copyList(artifact.getDependencyTrail()));
158         clone.setDownloadUrl(artifact.getDownloadUrl());
159         clone.setRepository(artifact.getRepository());
160 
161         return clone;
162     }
163 
164     /** Returns <code>to</code> collection */
165     public static <T extends Collection<Artifact>> T copyArtifacts(Collection<Artifact> from, T to) {
166         for (Artifact artifact : from) {
167             to.add(ArtifactUtils.copyArtifact(artifact));
168         }
169         return to;
170     }
171 
172     public static <K, T extends Map<K, Artifact>> T copyArtifacts(Map<K, ? extends Artifact> from, T to) {
173         if (from != null) {
174             for (Map.Entry<K, ? extends Artifact> entry : from.entrySet()) {
175                 to.put(entry.getKey(), ArtifactUtils.copyArtifact(entry.getValue()));
176             }
177         }
178 
179         return to;
180     }
181 
182     private static <T> List<T> copyList(List<T> original) {
183         List<T> copy = null;
184 
185         if (original != null) {
186             copy = new ArrayList<>();
187 
188             if (!original.isEmpty()) {
189                 copy.addAll(original);
190             }
191         }
192 
193         return copy;
194     }
195 }