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