View Javadoc

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