View Javadoc
1   package org.apache.maven.plugins.enforcer;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.versioning.ArtifactVersion;
23  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
24  import org.apache.maven.artifact.versioning.VersionRange;
25  import org.apache.maven.enforcer.rule.api.EnforcerRule;
26  import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
27  import org.apache.maven.plugin.logging.Log;
28  import org.codehaus.plexus.util.StringUtils;
29  
30  /**
31   * Contains the common code to compare a version against a version range.
32   *
33   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
34   */
35  public abstract class AbstractVersionEnforcer
36      extends AbstractStandardEnforcerRule
37  {
38  
39      /**
40       * Specify the required version. Some examples are:
41       * <ul>
42       * <li><code>2.0.4</code> Version 2.0.4 and higher (different from Maven meaning)</li>
43       * <li><code>[2.0,2.1)</code> Versions 2.0 (included) to 2.1 (not included)</li>
44       * <li><code>[2.0,2.1]</code> Versions 2.0 to 2.1 (both included)</li>
45       * <li><code>[2.0.5,)</code> Versions 2.0.5 and higher</li>
46       * <li><code>(,2.0.5],[2.1.1,)</code> Versions up to 2.0.5 (included) and 2.1.1 or higher</li>
47       * </ul>
48       * 
49       * @see {@link #setVersion(String)}
50       * @see {@link #getVersion()}
51       */
52      private String version;
53  
54      /**
55       * Compares the specified version to see if it is allowed by the defined version range.
56       *
57       * @param log the log
58       * @param variableName name of variable to use in messages (Example: "Maven" or "Java" etc).
59       * @param requiredVersionRange range of allowed versions.
60       * @param actualVersion the version to be checked.
61       * @throws EnforcerRuleException the enforcer rule exception
62       */
63      // CHECKSTYLE_OFF: LineLength
64      public void enforceVersion( Log log, String variableName, String requiredVersionRange, ArtifactVersion actualVersion )
65          throws EnforcerRuleException
66      // CHECKSTYLE_ON: LineLength
67      {
68          if ( StringUtils.isEmpty( requiredVersionRange ) )
69          {
70              throw new EnforcerRuleException( variableName + " version can't be empty." );
71          }
72          else
73          {
74  
75              VersionRange vr;
76              String msg = "Detected " + variableName + " Version: " + actualVersion;
77  
78              // short circuit check if the strings are exactly equal
79              if ( actualVersion.toString().equals( requiredVersionRange ) )
80              {
81                  log.debug( msg + " is allowed in the range " + requiredVersionRange + "." );
82              }
83              else
84              {
85                  try
86                  {
87                      vr = VersionRange.createFromVersionSpec( requiredVersionRange );
88  
89                      if ( containsVersion( vr, actualVersion ) )
90                      {
91                          log.debug( msg + " is allowed in the range " + requiredVersionRange + "." );
92                      }
93                      else
94                      {
95                          String message = getMessage();
96  
97                          if ( StringUtils.isEmpty( message ) )
98                          {
99                              message = msg + " is not in the allowed range " + vr + ".";
100                         }
101 
102                         throw new EnforcerRuleException( message );
103                     }
104                 }
105                 catch ( InvalidVersionSpecificationException e )
106                 {
107                     throw new EnforcerRuleException( "The requested " + variableName + " version "
108                         + requiredVersionRange + " is invalid.", e );
109                 }
110             }
111         }
112     }
113 
114     /**
115      * Copied from Artifact.VersionRange. This is tweaked to handle singular ranges properly. Currently the default
116      * containsVersion method assumes a singular version means allow everything. This method assumes that "2.0.4" ==
117      * "[2.0.4,)"
118      *
119      * @param allowedRange range of allowed versions.
120      * @param theVersion the version to be checked.
121      * @return true if the version is contained by the range.
122      */
123     public static boolean containsVersion( VersionRange allowedRange, ArtifactVersion theVersion )
124     {
125         ArtifactVersion recommendedVersion = allowedRange.getRecommendedVersion();
126         if ( recommendedVersion == null )
127         {
128             return allowedRange.containsVersion( theVersion );
129         }
130         else
131         {
132             // only singular versions ever have a recommendedVersion
133             int compareTo = recommendedVersion.compareTo( theVersion );
134             return ( compareTo <= 0 );
135         }
136     }
137 
138     @Override
139     public String getCacheId()
140     {
141         if ( StringUtils.isNotEmpty( version ) )
142         {
143             // return the hashcodes of the parameter that matters
144             return "" + version.hashCode();
145         }
146         else
147         {
148             return "0";
149         }
150 
151     }
152 
153     @Override
154     public boolean isCacheable()
155     {
156         // the maven version is not going to change between projects in the same build.
157         return true;
158     }
159 
160     @Override
161     public boolean isResultValid( EnforcerRule theCachedRule )
162     {
163         // i will always return the hash of the parameters as my id. If my parameters are the same, this
164         // rule must always have the same result.
165         return true;
166     }
167 
168     /**
169      * Gets the required version.
170      *
171      * @return the required version
172      */
173     public final String getVersion()
174     {
175         return this.version;
176     }
177 
178     /**
179      * Specify the required version. Some examples are:
180      * <ul>
181      * <li><code>2.0.4</code> Version 2.0.4 and higher (different from Maven meaning)</li>
182      * <li><code>[2.0,2.1)</code> Versions 2.0 (included) to 2.1 (not included)</li>
183      * <li><code>[2.0,2.1]</code> Versions 2.0 to 2.1 (both included)</li>
184      * <li><code>[2.0.5,)</code> Versions 2.0.5 and higher</li>
185      * <li><code>(,2.0.5],[2.1.1,)</code> Versions up to 2.0.5 (included) and 2.1.1 or higher</li>
186      * </ul>
187      *
188      * @param theVersion the required version to set
189      */
190     public final void setVersion( String theVersion )
191     {
192         this.version = theVersion;
193     }
194 
195 }