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.repository.internal;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.util.regex.Pattern;
26  
27  import org.apache.maven.api.Version;
28  import org.apache.maven.api.VersionConstraint;
29  import org.apache.maven.api.VersionRange;
30  import org.apache.maven.api.services.VersionParserException;
31  import org.apache.maven.api.services.model.ModelVersionParser;
32  import org.eclipse.aether.version.InvalidVersionSpecificationException;
33  import org.eclipse.aether.version.VersionScheme;
34  
35  import static java.util.Objects.requireNonNull;
36  
37  @Named
38  @Singleton
39  public class DefaultModelVersionParser implements ModelVersionParser {
40      private static final String SNAPSHOT = "SNAPSHOT";
41      private static final Pattern SNAPSHOT_TIMESTAMP = Pattern.compile("^(.*-)?([0-9]{8}\\.[0-9]{6}-[0-9]+)$");
42      private final VersionScheme versionScheme;
43  
44      @Inject
45      public DefaultModelVersionParser(VersionScheme versionScheme) {
46          this.versionScheme = requireNonNull(versionScheme, "versionScheme");
47      }
48  
49      @Override
50      public Version parseVersion(String version) {
51          requireNonNull(version, "version");
52          return new DefaultVersion(versionScheme, version);
53      }
54  
55      @Override
56      public VersionRange parseVersionRange(String range) {
57          requireNonNull(range, "range");
58          return new DefaultVersionRange(versionScheme, range);
59      }
60  
61      @Override
62      public boolean isSnapshot(String version) {
63          return checkSnapshot(version);
64      }
65  
66      public static boolean checkSnapshot(String version) {
67          return version.endsWith(SNAPSHOT) || SNAPSHOT_TIMESTAMP.matcher(version).matches();
68      }
69  
70      @Override
71      public VersionConstraint parseVersionConstraint(String constraint) {
72          requireNonNull(constraint, "constraint");
73          return new DefaultVersionConstraint(versionScheme, constraint);
74      }
75  
76      static class DefaultVersion implements Version {
77          private final VersionScheme versionScheme;
78          private final org.eclipse.aether.version.Version delegate;
79  
80          DefaultVersion(VersionScheme versionScheme, org.eclipse.aether.version.Version delegate) {
81              this.versionScheme = versionScheme;
82              this.delegate = delegate;
83          }
84  
85          DefaultVersion(VersionScheme versionScheme, String delegateValue) {
86              this.versionScheme = versionScheme;
87              try {
88                  this.delegate = versionScheme.parseVersion(delegateValue);
89              } catch (InvalidVersionSpecificationException e) {
90                  throw new VersionParserException("Unable to parse version: " + delegateValue, e);
91              }
92          }
93  
94          @Override
95          public int compareTo(Version o) {
96              if (o instanceof DefaultVersion) {
97                  return delegate.compareTo(((DefaultVersion) o).delegate);
98              } else {
99                  return compareTo(new DefaultVersion(versionScheme, o.asString()));
100             }
101         }
102 
103         @Override
104         public boolean equals(Object o) {
105             if (this == o) {
106                 return true;
107             }
108             if (o == null || getClass() != o.getClass()) {
109                 return false;
110             }
111             DefaultVersion that = (DefaultVersion) o;
112             return delegate.equals(that.delegate);
113         }
114 
115         @Override
116         public int hashCode() {
117             return delegate.hashCode();
118         }
119 
120         @Override
121         public String asString() {
122             return delegate.toString();
123         }
124 
125         @Override
126         public String toString() {
127             return asString();
128         }
129     }
130 
131     static class DefaultVersionRange implements VersionRange {
132         private final VersionScheme versionScheme;
133         private final org.eclipse.aether.version.VersionRange delegate;
134 
135         DefaultVersionRange(VersionScheme versionScheme, org.eclipse.aether.version.VersionRange delegate) {
136             this.versionScheme = versionScheme;
137             this.delegate = delegate;
138         }
139 
140         DefaultVersionRange(VersionScheme versionScheme, String delegateValue) {
141             this.versionScheme = versionScheme;
142             try {
143                 this.delegate = versionScheme.parseVersionRange(delegateValue);
144             } catch (InvalidVersionSpecificationException e) {
145                 throw new VersionParserException("Unable to parse version range: " + delegateValue, e);
146             }
147         }
148 
149         @Override
150         public boolean contains(Version version) {
151             if (version instanceof DefaultVersion) {
152                 return delegate.containsVersion(((DefaultVersion) version).delegate);
153             } else {
154                 return contains(new DefaultVersion(versionScheme, version.asString()));
155             }
156         }
157 
158         @Override
159         public Boundary getUpperBoundary() {
160             org.eclipse.aether.version.VersionRange.Bound bound = delegate.getUpperBound();
161             if (bound == null) {
162                 return null;
163             }
164             return new Boundary() {
165                 @Override
166                 public Version getVersion() {
167                     return new DefaultVersion(versionScheme, bound.getVersion());
168                 }
169 
170                 @Override
171                 public boolean isInclusive() {
172                     return bound.isInclusive();
173                 }
174             };
175         }
176 
177         @Override
178         public Boundary getLowerBoundary() {
179             org.eclipse.aether.version.VersionRange.Bound bound = delegate.getLowerBound();
180             if (bound == null) {
181                 return null;
182             }
183             return new Boundary() {
184                 @Override
185                 public Version getVersion() {
186                     return new DefaultVersion(versionScheme, bound.getVersion());
187                 }
188 
189                 @Override
190                 public boolean isInclusive() {
191                     return bound.isInclusive();
192                 }
193             };
194         }
195 
196         @Override
197         public String asString() {
198             return delegate.toString();
199         }
200 
201         @Override
202         public String toString() {
203             return asString();
204         }
205 
206         @Override
207         public boolean equals(Object o) {
208             if (this == o) {
209                 return true;
210             }
211             if (o == null || getClass() != o.getClass()) {
212                 return false;
213             }
214             DefaultVersionRange that = (DefaultVersionRange) o;
215             return delegate.equals(that.delegate);
216         }
217 
218         @Override
219         public int hashCode() {
220             return delegate.hashCode();
221         }
222     }
223 
224     static class DefaultVersionConstraint implements VersionConstraint {
225         private final VersionScheme versionScheme;
226         private final org.eclipse.aether.version.VersionConstraint delegate;
227 
228         DefaultVersionConstraint(VersionScheme versionScheme, String delegateValue) {
229             this.versionScheme = versionScheme;
230             try {
231                 this.delegate = versionScheme.parseVersionConstraint(delegateValue);
232             } catch (InvalidVersionSpecificationException e) {
233                 throw new VersionParserException("Unable to parse version constraint: " + delegateValue, e);
234             }
235         }
236 
237         @Override
238         public boolean contains(Version version) {
239             if (version instanceof DefaultVersion) {
240                 return delegate.containsVersion(((DefaultVersion) version).delegate);
241             } else {
242                 return contains(new DefaultVersion(versionScheme, version.asString()));
243             }
244         }
245 
246         @Override
247         public String asString() {
248             return delegate.toString();
249         }
250 
251         @Override
252         public VersionRange getVersionRange() {
253             if (delegate.getRange() == null) {
254                 return null;
255             }
256             return new DefaultVersionRange(versionScheme, delegate.getRange());
257         }
258 
259         @Override
260         public Version getRecommendedVersion() {
261             if (delegate.getVersion() == null) {
262                 return null;
263             }
264             return new DefaultVersion(versionScheme, delegate.getVersion());
265         }
266 
267         @Override
268         public String toString() {
269             return asString();
270         }
271 
272         @Override
273         public boolean equals(Object o) {
274             if (this == o) {
275                 return true;
276             }
277             if (o == null || getClass() != o.getClass()) {
278                 return false;
279             }
280             DefaultVersionConstraint that = (DefaultVersionConstraint) o;
281             return delegate.equals(that.delegate);
282         }
283 
284         @Override
285         public int hashCode() {
286             return delegate.hashCode();
287         }
288     }
289 }