1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.extension.version.internal

File DefaultVersionRangeCollection.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

28
59
14
1
271
151
33
0.56
4.21
14
2.36

Classes

Class Line # Actions
DefaultVersionRangeCollection 46 59 0% 33 23
0.7722772477.2%
 

Contributing tests

This file is covered by 58 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.extension.version.internal;
21   
22    import java.io.IOException;
23    import java.io.ObjectInputStream;
24    import java.io.ObjectOutputStream;
25    import java.util.ArrayList;
26    import java.util.Collection;
27    import java.util.List;
28   
29    import org.apache.commons.lang3.StringUtils;
30    import org.xwiki.extension.version.InvalidVersionRangeException;
31    import org.xwiki.extension.version.Version;
32    import org.xwiki.extension.version.VersionRange;
33    import org.xwiki.extension.version.VersionRangeCollection;
34   
35    /**
36    * A collection of {@link VersionRange} linked with OR logic operation.
37    * <p>
38    * Mostly based on AETHER implementation which is itself based on Maven specifications.
39    * <p>
40    * (,1.0],[2.0,)
41    *
42    * @see org.sonatype.aether.util.version.GenericVersionScheme#parseVersionConstraint(String)
43    * @version $Id: 8374b02d660424e6ab22aa829e8fd77e6739d5f6 $
44    * @since 4.0M1
45    */
 
46    public class DefaultVersionRangeCollection implements VersionRangeCollection
47    {
48    /**
49    * Serialization identifier.
50    */
51    private static final long serialVersionUID = 1L;
52   
53    /**
54    * The character used to separated version ranges.
55    */
56    private static final char RANGE_SEPARATOR = ',';
57   
58    /**
59    * @see #getRanges()
60    */
61    private List<VersionRange> ranges = new ArrayList<VersionRange>();
62   
63    /**
64    * String representation of this range.
65    */
66    private String value;
67   
68    /**
69    * @param rawRanges the version ranges to parse
70    * @throws InvalidVersionRangeException error when parsing version range
71    */
 
72  734769 toggle public DefaultVersionRangeCollection(String rawRanges) throws InvalidVersionRangeException
73    {
74  734769 setRanges(rawRanges);
75    }
76   
77    /**
78    * @param ranges the ranges
79    */
 
80  0 toggle public DefaultVersionRangeCollection(Collection<? extends VersionRange> ranges)
81    {
82  0 for (VersionRange range : ranges) {
83  0 this.ranges.add(range);
84    }
85    }
86   
87    /**
88    * @param rawRanges the range collection string representation
89    * @throws InvalidVersionRangeException error when parsing version range
90    */
 
91  734769 toggle private void setRanges(String rawRanges) throws InvalidVersionRangeException
92    {
93  734769 this.value = rawRanges;
94   
95    // Parse
96   
97  734769 if (StringUtils.isEmpty(rawRanges)) {
98  0 throw new InvalidVersionRangeException("Range can't be empty");
99    }
100   
101  734769 parseRanges(this.value);
102    }
103   
104    /**
105    * @param rawRanges the ranges to parse
106    * @throws InvalidVersionRangeException invalid ranges syntax
107    */
 
108  734769 toggle private void parseRanges(String rawRanges) throws InvalidVersionRangeException
109    {
110  734769 String currentRanges = rawRanges;
111   
112  734797 while (VersionUtils.startsWith(currentRanges, '[') || VersionUtils.startsWith(currentRanges, '(')) {
113  29 int index1 = currentRanges.indexOf(')');
114  29 int index2 = currentRanges.indexOf(']');
115   
116  29 int index = index2;
117  29 if (index2 < 0 || (index1 >= 0 && index1 < index2)) {
118  13 index = index1;
119    }
120   
121  29 if (index < 0) {
122  1 throw new InvalidVersionRangeException("Unbounded version range [" + rawRanges + "]");
123    }
124   
125  28 currentRanges = parseRange(currentRanges, index, rawRanges);
126   
127  28 if (VersionUtils.startsWith(currentRanges, RANGE_SEPARATOR)) {
128  3 currentRanges = currentRanges.substring(1).trim();
129    }
130    }
131   
132  734768 if (!currentRanges.isEmpty()) {
133  734743 throw new InvalidVersionRangeException(String.format(
134    "Invalid version range [%s], expected [ or ( but got [%s]", rawRanges, currentRanges));
135    }
136    }
137   
138    /**
139    * @param currentRanges the current ranges string representation
140    * @param index the index of the end of the range in currentRanges
141    * @param rawRanges the full string representation
142    * @return the new currentRanges
143    * @throws InvalidVersionRangeException syntax error in the range
144    */
 
145  28 toggle private String parseRange(String currentRanges, int index, String rawRanges) throws InvalidVersionRangeException
146    {
147  28 String range = currentRanges.substring(0, index + 1);
148  28 try {
149  28 this.ranges.add(new DefaultVersionRange(range));
150    } catch (InvalidVersionRangeException e) {
151  0 throw new InvalidVersionRangeException(String.format(
152    "Failed to parse version range [%s] in constraint [%s]", range, rawRanges), e);
153    }
154   
155  28 return currentRanges.substring(index + 1).trim();
156    }
157   
 
158  30 toggle @Override
159    public Collection<VersionRange> getRanges()
160    {
161  30 return this.ranges;
162    }
163   
 
164  22 toggle @Override
165    public boolean containsVersion(Version version)
166    {
167  22 for (VersionRange range : getRanges()) {
168  26 if (range.containsVersion(version)) {
169  18 return true;
170    }
171    }
172   
173  4 return false;
174    }
175   
 
176  5 toggle @Override
177    public String getValue()
178    {
179  5 if (this.value == null) {
180  0 StringBuilder buffer = new StringBuilder();
181   
182  0 for (VersionRange range : this.ranges) {
183  0 if (buffer.length() > 0) {
184  0 buffer.append(RANGE_SEPARATOR);
185    }
186  0 buffer.append(range);
187    }
188   
189  0 this.value = buffer.toString();
190    }
191   
192  5 return this.value;
193    }
194   
 
195  4 toggle @Override
196    public boolean isCompatible(VersionRange otherRange)
197    {
198  4 if (equals(otherRange)) {
199  0 return true;
200    }
201   
202  4 for (VersionRange versionRange : this.ranges) {
203  4 boolean compatible;
204   
205  4 if (otherRange instanceof VersionRangeCollection) {
206  2 compatible = ((VersionRangeCollection) otherRange).isCompatible(versionRange);
207    } else {
208  2 compatible = versionRange.isCompatible(otherRange);
209    }
210   
211  4 if (compatible) {
212  2 return true;
213    }
214    }
215   
216  2 return false;
217    }
218   
219    // Object
220   
 
221  2 toggle @Override
222    public String toString()
223    {
224  2 return getValue();
225    }
226   
 
227  10 toggle @Override
228    public boolean equals(Object obj)
229    {
230  10 if (this == obj) {
231  0 return true;
232    }
233   
234  10 if (obj == null || !(obj instanceof DefaultVersionRangeCollection)) {
235  2 return false;
236    }
237   
238  8 DefaultVersionRangeCollection versionConstraint = (DefaultVersionRangeCollection) obj;
239   
240  8 return this.ranges.equals(versionConstraint.getRanges());
241    }
242   
 
243  1 toggle @Override
244    public int hashCode()
245    {
246  1 return this.ranges.hashCode();
247    }
248   
249    // Serializable
250   
251    /**
252    * @param out the stream
253    * @throws IOException error when serializing the version
254    */
 
255  0 toggle private void writeObject(ObjectOutputStream out) throws IOException
256    {
257  0 out.writeObject(getValue());
258    }
259   
260    /**
261    * @param in the stream
262    * @throws IOException error when unserializing the version range collection
263    * @throws ClassNotFoundException error when unserializing the version range collection
264    * @throws InvalidVersionRangeException error when unserializing the version range collection
265    */
 
266  0 toggle private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException,
267    InvalidVersionRangeException
268    {
269  0 setRanges((String) in.readObject());
270    }
271    }