View Javadoc

1   /*
2    * Copyright 2008-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.issues.util;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.apache.maven.artifact.versioning.ArtifactVersion;
23  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
24  import org.apache.maven.artifact.versioning.Restriction;
25  import org.apache.maven.artifact.versioning.VersionRange;
26  import org.codehaus.plexus.util.StringUtils;
27  
28  /**
29   * Utilities for this package.
30   *
31   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
32   * @version $Revision:591 $
33   */
34  public final class Utils
35  {
36    // ********************************* Fields *********************************
37  
38    // --- constants ------------------------------------------------------------
39  
40    // --- members --------------------------------------------------------------
41  
42    // ****************************** Initializer *******************************
43  
44    // ****************************** Constructors ******************************
45  
46    /**
47     * Utility class pattern.
48     */
49    private Utils()
50    {
51    }
52  
53    // ****************************** Inner Classes *****************************
54  
55    // ********************************* Methods ********************************
56  
57    // --- init -----------------------------------------------------------------
58  
59    // --- get&set --------------------------------------------------------------
60  
61    // --- business -------------------------------------------------------------
62  
63    /**
64     * Normalizes the key to an issue information to be a valid key element to
65     * select a value in a resource bundle.
66     *
67     * @param key the key to normalize.
68     * @return the normalized key.
69     */
70    public static String normalizeKey(final String key)
71    {
72      if (key == null || "".equals(key))
73      {
74        return key;
75      }
76  
77      final char[] trimmed = key.trim().toCharArray();
78      boolean uppercase = false;
79      int currentPos = 0;
80      for (int i = 0; i < trimmed.length; i++, currentPos++)
81      {
82        final char c = trimmed[i];
83        if (Character.isWhitespace(c))
84        {
85          uppercase = true;
86          --currentPos;
87        }
88        else if (uppercase)
89        {
90          trimmed[currentPos] = Character.toUpperCase(c);
91          uppercase = false;
92        }
93        else
94        {
95          trimmed[currentPos] = c;
96        }
97      }
98  
99      return new String(trimmed).substring(0, currentPos);
100   }
101 
102   /**
103    * Splits a comma separated list of values from a {@link String} into a list
104    * of {@link String}s.
105    *
106    * @param commaSeparatedValues the {@link String} value containing comma
107    *          separated values. Blanks in front or after the items are trimmed.
108    * @return the list of {@link String}s or the empty list if the given value
109    *         was blank.
110    */
111   public static List<String> splitToList(final String commaSeparatedValues)
112   {
113     if (StringUtils.isNotBlank(commaSeparatedValues))
114     {
115       final String[] items = commaSeparatedValues.split(",");
116       final List<String> list = new ArrayList<String>(items.length);
117       for (String item : items)
118       {
119         list.add(item.trim());
120       }
121       return list;
122     }
123     else
124     {
125       return Collections.emptyList();
126     }
127   }
128 
129   /**
130    * Returns a representative from within the version range.
131    * <p>
132    * It is expected that the restrictions are ordered by the version numbers
133    * they define ascending.
134    * </p>
135    *
136    * @param range the range of version where the lowest version is requested.
137    * @return the version representative within the given range or a version
138    *         instance representing <code>0.0.0</code> if the range has no lower
139    *         bound.
140    * @throws NullPointerException if the given <code>range</code> is
141    *           <code>null</code>.
142    * @throws IllegalArgumentException if no bound is inclusive and the upper
143    *           bound is <code>null</code> and the lower bound is not
144    *           <code>null</code>.
145    */
146   @SuppressWarnings("unchecked")
147   public static ArtifactVersion findVersionRepresentative(
148       final VersionRange range) throws NullPointerException,
149     IllegalArgumentException
150   {
151     final List<Restriction> restrictions = range.getRestrictions();
152     final ArtifactVersion currentLowerBound;
153     final ArtifactVersion recommendedVersion = range.getRecommendedVersion();
154     if (recommendedVersion != null)
155     {
156       currentLowerBound = recommendedVersion;
157     }
158     else if (!restrictions.isEmpty())
159     {
160       currentLowerBound = handleRestriction(restrictions);
161     }
162     else
163     {
164       currentLowerBound = new DefaultArtifactVersion("0.0.0");
165     }
166 
167     return currentLowerBound;
168   }
169 
170   /**
171    * Handles restrictions for {@link #findVersionRepresentative(VersionRange)}.
172    *
173    * @param restrictions the restrictions to find a representative for.
174    * @return the representative of the restrictions.
175    * @throws IllegalArgumentException if no bound of the first restriction is
176    *           inclusive and the upper bound is <code>null</code> and the lower
177    *           bound is not <code>null</code>.
178    */
179   private static ArtifactVersion handleRestriction(
180       final List<Restriction> restrictions) throws IllegalArgumentException
181   {
182     final ArtifactVersion currentLowerBound;
183     final Restriction restriction = restrictions.get(0);
184     final ArtifactVersion lowerBound = restriction.getLowerBound();
185     if (lowerBound == null)
186     {
187       currentLowerBound = new DefaultArtifactVersion("0.0.0");
188     }
189     else if (restriction.isLowerBoundInclusive())
190     {
191       currentLowerBound = lowerBound;
192     }
193     else
194     {
195       currentLowerBound = handleUpperBound(restriction);
196     }
197     return currentLowerBound;
198   }
199 
200   /**
201    * Tries to find a version representative derived from the upper bound.
202    *
203    * @param restriction the restriction with the upper bound information.
204    * @return the derived version representative.
205    * @throws IllegalArgumentException if no bound of the first restriction is
206    *           inclusive and the upper bound is <code>null</code> and the lower
207    *           bound is not <code>null</code>.
208    */
209   private static ArtifactVersion handleUpperBound(final Restriction restriction)
210     throws IllegalArgumentException
211   {
212     assert !restriction.isLowerBoundInclusive();
213     final ArtifactVersion upperBound = restriction.getUpperBound();
214     if (restriction.isUpperBoundInclusive() && upperBound != null)
215     {
216       return upperBound;
217     }
218     else
219     {
220       throw new IllegalArgumentException(
221           "At least one bound is required to be inclusive and not 'null'.");
222     }
223   }
224 
225   // --- object basics --------------------------------------------------------
226 
227 }