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 java.util.Iterator;
23  
24  import org.apache.maven.enforcer.rule.api.EnforcerRule;
25  import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
26  import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
27  import org.apache.maven.model.Activation;
28  import org.apache.maven.model.ActivationOS;
29  import org.apache.maven.model.Profile;
30  import org.apache.maven.plugin.logging.Log;
31  import org.apache.maven.profiles.activation.OperatingSystemProfileActivator;
32  import org.codehaus.plexus.util.Os;
33  import org.codehaus.plexus.util.StringUtils;
34  
35  /**
36   * This rule checks that the OS is allowed by combinations of family, name, version and cpu architecture. The behavior
37   * is exactly the same as the Maven Os profile activation so the same values are allowed here.
38   *
39   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
40   * @version $Id: RequireOS.java 1345332 2012-06-01 20:14:13Z rfscholte $
41   */
42  public class RequireOS
43      extends AbstractStandardEnforcerRule
44  {
45  
46      /**
47       * The OS family type desired<br />
48       * Possible values:
49       * <ul>
50       * <li>dos</li>
51       * <li>mac</li>
52       * <li>netware</li>
53       * <li>os/2</li>
54       * <li>tandem</li>
55       * <li>unix</li>
56       * <li>windows</li>
57       * <li>win9x</li>
58       * <li>z/os</li>
59       * <li>os/400</li>
60       * </ul>
61       */
62      public String family = null;
63  
64      /** The OS name desired. */
65      public String name = null;
66  
67      /** The OS version desired. */
68      public String version = null;
69  
70      /** The OS architecture desired. */
71      public String arch = null;
72  
73      /** Specify an optional message to the user if the rule fails. */
74      public String message = "";
75  
76      /** Display detected OS information. */
77      public boolean display = false;
78  
79      /**
80       * Instantiates a new RequireOS.
81       */
82      public RequireOS()
83      {
84  
85      }
86  
87      /*
88       * (non-Javadoc)
89       *
90       * @see org.apache.maven.enforcer.rule.api.EnforcerRule#execute(org.apache.maven.enforcer.rule.api.EnforcerRuleHelper)
91       */
92      public void execute( EnforcerRuleHelper helper )
93          throws EnforcerRuleException
94      {
95  
96          displayOSInfo( helper.getLog(), display );
97  
98          if ( allParamsEmpty() )
99          {
100             throw new EnforcerRuleException( "All parameters can not be empty. You must pick at least one of (family, name, version, arch) or use -Denforcer.os.display=true to see the current OS information." );
101         }
102 
103         if ( isValidFamily( this.family ) )
104         {
105             if ( !isAllowed() )
106             {
107                 if ( StringUtils.isEmpty( message ) )
108                 {
109                     message =
110                         ( "OS Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME +
111                             " Version: " + Os.OS_VERSION + " is not allowed by" +
112                             ( arch != null ? " Arch=" + arch : "" ) + ( family != null ? " Family=" + family : "" ) +
113                             ( name != null ? " Name=" + name : "" ) + ( version != null ? " Version=" + version : "" ) );
114                 }
115                 throw new EnforcerRuleException( message );
116             }
117         }
118         else
119         {
120             StringBuilder buffer = new StringBuilder( 50 );
121             Iterator iter = Os.getValidFamilies().iterator();
122             while ( iter.hasNext() )
123             {
124                 buffer.append( iter.next() );
125                 buffer.append( ", " );
126             }
127             String help = StringUtils.stripEnd( buffer.toString().trim(), "." );
128             throw new EnforcerRuleException( "Invalid Family type used. Valid family types are: " + help );
129         }
130     }
131 
132     /**
133      * Log the current OS information.
134      *
135      * @param log the log
136      * @param info the info
137      */
138     public void displayOSInfo( Log log, boolean info )
139     {
140         String string =
141             "OS Info: Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME + " Version: " +
142                 Os.OS_VERSION;
143 
144         if ( !info )
145         {
146             log.debug( string );
147         }
148         else
149         {
150             log.info( string );
151         }
152     }
153 
154     /**
155      * Helper method to determine if the current OS is allowed based on the injected values for family, name, version
156      * and arch.
157      *
158      * @return true if the version is allowed.
159      */
160     public boolean isAllowed()
161     {
162         OperatingSystemProfileActivator activator = new OperatingSystemProfileActivator();
163 
164         return activator.isActive( createProfile() );
165     }
166 
167     /**
168      * Helper method to check that at least one of family, name, version or arch is set.
169      *
170      * @return true if all parameters are empty.
171      */
172     public boolean allParamsEmpty()
173     {
174         return ( StringUtils.isEmpty( family ) && StringUtils.isEmpty( arch ) && StringUtils.isEmpty( name ) && StringUtils.isEmpty( version ) );
175 
176     }
177 
178     /**
179      * Creates a Profile object that contains the activation information.
180      *
181      * @return a properly populated profile to be used for OS validation.
182      */
183     private Profile createProfile()
184     {
185         Profile profile = new Profile();
186         profile.setActivation( createActivation() );
187         return profile;
188     }
189 
190     /**
191      * Creates an Activation object that contains the ActivationOS information.
192      *
193      * @return a properly populated Activation object.
194      */
195     private Activation createActivation()
196     {
197         Activation activation = new Activation();
198         activation.setActiveByDefault( false );
199         activation.setOs( createOsBean() );
200         return activation;
201     }
202 
203     /**
204      * Creates an ActivationOS object containing family, name, version and arch.
205      *
206      * @return a properly populated ActivationOS object.
207      */
208     private ActivationOS createOsBean()
209     {
210         ActivationOS os = new ActivationOS();
211 
212         os.setArch( arch );
213         os.setFamily( family );
214         os.setName( name );
215         os.setVersion( version );
216 
217         return os;
218     }
219 
220     /**
221      * Helper method to check if the given family is in the following list:
222      * <ul>
223      * <li>dos</li>
224      * <li>mac</li>
225      * <li>netware</li>
226      * <li>os/2</li>
227      * <li>tandem</li>
228      * <li>unix</li>
229      * <li>windows</li>
230      * <li>win9x</li>
231      * <li>z/os</li>
232      * <li>os/400</li>
233      * </ul>
234      * Note: '!' is allowed at the beginning of the string and still considered valid.
235      *
236      * @param theFamily the family to check.
237      * @return true if one of the valid families.
238      */
239     public boolean isValidFamily( String theFamily )
240     {
241 
242         // in case they are checking !family
243         theFamily = StringUtils.stripStart( theFamily, "!" );
244 
245         return ( StringUtils.isEmpty( theFamily ) || Os.getValidFamilies().contains( theFamily ) );
246     }
247 
248     /**
249      * Gets the arch.
250      *
251      * @return the arch
252      */
253     public String getArch()
254     {
255         return this.arch;
256     }
257 
258     /**
259      * Sets the arch.
260      *
261      * @param theArch the arch to set
262      */
263     public void setArch( String theArch )
264     {
265         this.arch = theArch;
266     }
267 
268     /**
269      * Gets the family.
270      *
271      * @return the family
272      */
273     public String getFamily()
274     {
275         return this.family;
276     }
277 
278     /**
279      * Sets the family.
280      *
281      * @param theFamily the family to set
282      */
283     public void setFamily( String theFamily )
284     {
285         this.family = theFamily;
286     }
287 
288     /**
289      * Gets the name.
290      *
291      * @return the name
292      */
293     public String getName()
294     {
295         return this.name;
296     }
297 
298     /**
299      * Sets the name.
300      *
301      * @param theName the name to set
302      */
303     public void setName( String theName )
304     {
305         this.name = theName;
306     }
307 
308     /**
309      * Gets the version.
310      *
311      * @return the version
312      */
313     public String getVersion()
314     {
315         return this.version;
316     }
317 
318     /**
319      * Sets the version.
320      *
321      * @param theVersion the version to set
322      */
323     public void setVersion( String theVersion )
324     {
325         this.version = theVersion;
326     }
327 
328     /*
329      * (non-Javadoc)
330      *
331      * @see org.apache.maven.enforcer.rule.api.EnforcerRule#getCacheId()
332      */
333     public String getCacheId()
334     {
335         // return the hashcodes of all the parameters
336         StringBuffer b = new StringBuffer();
337         if ( StringUtils.isNotEmpty( version ) )
338         {
339             b.append( version.hashCode() );
340         }
341         if ( StringUtils.isNotEmpty( name ) )
342         {
343             b.append( name.hashCode() );
344         }
345         if ( StringUtils.isNotEmpty( arch ) )
346         {
347             b.append( arch.hashCode() );
348         }
349         if ( StringUtils.isNotEmpty( family ) )
350         {
351             b.append( family.hashCode() );
352         }
353         return b.toString();
354     }
355 
356     /*
357      * (non-Javadoc)
358      *
359      * @see org.apache.maven.enforcer.rule.api.EnforcerRule#isCacheable()
360      */
361     public boolean isCacheable()
362     {
363         // the os is not going to change between projects in the same build.
364         return true;
365     }
366 
367     /*
368      * (non-Javadoc)
369      *
370      * @see org.apache.maven.enforcer.rule.api.EnforcerRule#isResultValid(org.apache.maven.enforcer.rule.api.EnforcerRule)
371      */
372     public boolean isResultValid( EnforcerRule theCachedRule )
373     {
374         // i will always return the hash of the parameters as my id. If my parameters are the same, this
375         // rule must always have the same result.
376         return true;
377     }
378 }