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.regex.Matcher;
27  import org.apache.commons.lang3.Validate;
28  import org.apache.maven.artifact.versioning.VersionRange;
29  
30  /**
31   * ArtifactUtils
32   */
33  public final class ArtifactUtils {
34  
35      public static boolean isSnapshot(String version) {
36          if (version != null) {
37              if (version.regionMatches(
38                      true,
39                      version.length() - Artifact.SNAPSHOT_VERSION.length(),
40                      Artifact.SNAPSHOT_VERSION,
41                      0,
42                      Artifact.SNAPSHOT_VERSION.length())) {
43                  return true;
44              } else {
45                  return Artifact.VERSION_FILE_PATTERN.matcher(version).matches();
46              }
47          }
48          return false;
49      }
50  
51      public static String toSnapshotVersion(String version) {
52          notBlank(version, "version can neither be null, empty nor blank");
53  
54          int lastHyphen = version.lastIndexOf('-');
55          if (lastHyphen > 0) {
56              int prevHyphen = version.lastIndexOf('-', lastHyphen - 1);
57              if (prevHyphen > 0) {
58                  Matcher m = Artifact.VERSION_FILE_PATTERN.matcher(version);
59                  if (m.matches()) {
60                      return m.group(1) + "-" + Artifact.SNAPSHOT_VERSION;
61                  }
62              }
63          }
64          return version;
65      }
66  
67      public static String versionlessKey(Artifact artifact) {
68          return versionlessKey(artifact.getGroupId(), artifact.getArtifactId());
69      }
70  
71      public static String versionlessKey(String groupId, String artifactId) {
72          notBlank(groupId, "groupId can neither be null, empty nor blank");
73          notBlank(artifactId, "artifactId can neither be null, empty nor blank");
74  
75          return groupId + ":" + artifactId;
76      }
77  
78      public static String key(Artifact artifact) {
79          return key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
80      }
81  
82      public static String key(String groupId, String artifactId, String version) {
83          notBlank(groupId, "groupId can neither be null, empty nor blank");
84          notBlank(artifactId, "artifactId can neither be null, empty nor blank");
85          notBlank(version, "version can neither be null, empty nor blank");
86  
87          return groupId + ":" + artifactId + ":" + version;
88      }
89  
90      private static void notBlank(String str, String message) {
91          int c = str != null && str.length() > 0 ? str.charAt(0) : 0;
92          if ((c < '0' || c > '9') && (c < 'a' || c > 'z')) {
93              Validate.notBlank(str, message);
94          }
95      }
96  
97      public static Map<String, Artifact> artifactMapByVersionlessId(Collection<Artifact> artifacts) {
98          Map<String, Artifact> artifactMap = new LinkedHashMap<>();
99  
100         if (artifacts != null) {
101             for (Artifact artifact : artifacts) {
102                 artifactMap.put(versionlessKey(artifact), artifact);
103             }
104         }
105 
106         return artifactMap;
107     }
108 
109     public static Artifact copyArtifactSafe(Artifact artifact) {
110         return (artifact != null) ? copyArtifact(artifact) : null;
111     }
112 
113     public static Artifact copyArtifact(Artifact artifact) {
114         VersionRange range = artifact.getVersionRange();
115 
116         // For some reason with the introduction of MNG-1577 we have the case in Yoko where a depMan section has
117         // something like the following:
118         //
119         // <dependencyManagement>
120         //     <dependencies>
121         //         <!--  Yoko modules -->
122         //         <dependency>
123         //             <groupId>org.apache.yoko</groupId>
124         //             <artifactId>yoko-core</artifactId>
125         //             <version>${version}</version>
126         //         </dependency>
127         // ...
128         //
129         // And the range is not set so we'll check here and set it. jvz.
130 
131         if (range == null) {
132             range = VersionRange.createFromVersion(artifact.getVersion());
133         }
134 
135         DefaultArtifact clone = new DefaultArtifact(
136                 artifact.getGroupId(),
137                 artifact.getArtifactId(),
138                 range,
139                 artifact.getScope(),
140                 artifact.getType(),
141                 artifact.getClassifier(),
142                 artifact.getArtifactHandler(),
143                 artifact.isOptional());
144         clone.setRelease(artifact.isRelease());
145         clone.setResolvedVersion(artifact.getVersion());
146         clone.setResolved(artifact.isResolved());
147         clone.setFile(artifact.getFile());
148 
149         clone.setAvailableVersions(copyList(artifact.getAvailableVersions()));
150         if (artifact.getVersion() != null) {
151             clone.setBaseVersion(artifact.getBaseVersion());
152         }
153         clone.setDependencyFilter(artifact.getDependencyFilter());
154         clone.setDependencyTrail(copyList(artifact.getDependencyTrail()));
155         clone.setDownloadUrl(artifact.getDownloadUrl());
156         clone.setRepository(artifact.getRepository());
157 
158         return clone;
159     }
160 
161     /**
162      * Copy artifact to a collection.
163      *
164      * @param <T> the target collection type
165      * @param from an artifact collection
166      * @param to the target artifact collection
167      * @return <code>to</code> collection
168      */
169     public static <T extends Collection<Artifact>> T copyArtifacts(Collection<Artifact> from, T to) {
170         for (Artifact artifact : from) {
171             to.add(ArtifactUtils.copyArtifact(artifact));
172         }
173         return to;
174     }
175 
176     public static <K, T extends Map<K, Artifact>> T copyArtifacts(Map<K, ? extends Artifact> from, T to) {
177         if (from != null) {
178             for (Map.Entry<K, ? extends Artifact> entry : from.entrySet()) {
179                 to.put(entry.getKey(), ArtifactUtils.copyArtifact(entry.getValue()));
180             }
181         }
182 
183         return to;
184     }
185 
186     private static <T> List<T> copyList(List<T> original) {
187         List<T> copy = null;
188 
189         if (original != null) {
190             copy = new ArrayList<>();
191 
192             if (!original.isEmpty()) {
193                 copy.addAll(original);
194             }
195         }
196 
197         return copy;
198     }
199 }