View Javadoc
1   package org.codehaus.mojo.jaxb2.shared.environment.sysprops;
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.plugin.logging.Log;
23  import org.codehaus.mojo.jaxb2.AbstractJaxbMojo;
24  import org.codehaus.mojo.jaxb2.shared.Validate;
25  import org.codehaus.mojo.jaxb2.shared.environment.AbstractLogAwareFacet;
26  
27  import java.util.ArrayList;
28  import java.util.List;
29  
30  /**
31   * EnvironmentFacet which changes
32   * system property key and two values (original and new values).
33   *
34   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>, jGuru Europe AB
35   * @since 2.1
36   */
37  public class SystemPropertyChangeEnvironmentFacet extends AbstractLogAwareFacet {
38  
39      /**
40       * Operation definitions indicating how a System property should be changed by this EnvironmentFacet.
41       */
42      public enum ChangeType {
43  
44          /**
45           * Indicates that a System property should be added during {@code setup()}
46           * and removed during {@code restore()}. If the property was already present,
47           * this behaves like {@code #CHANGE}.
48           */
49          ADD,
50  
51          /**
52           * Indicates that a System property should be removed during {@code setup()}
53           * and restored/re-added during {@code restore()}
54           */
55          REMOVE,
56  
57          /**
58           * Indicates that a System property should be altered during {@code setup()}
59           * and restored during {@code restore()}
60           */
61          CHANGE
62      }
63  
64      // Internal state
65      private ChangeType type;
66      private String key;
67      private String newValue;
68      private String originalValue;
69  
70      /**
71       * Creates a SystemPropertyChange which will remove the supplied system property for the
72       * duration of this SystemPropertyChange. No exception will be thrown if the supplied System property
73       * key is not found in the present System.properties.
74       *
75       * @param log The active Maven Log.
76       * @param key A non-null key.
77       * @see SystemPropertyChangeEnvironmentFacet.ChangeType#REMOVE
78       */
79      private SystemPropertyChangeEnvironmentFacet(final Log log, final String key) {
80  
81          // Delegate
82          super(log);
83  
84          // Assign internal state
85          this.key = key;
86          this.type = ChangeType.REMOVE;
87      }
88  
89      /**
90       * Creates a SystemPropertyChange which stores the current
91       *
92       * @param log      The active Maven Log.
93       * @param key      The key of the System property managed by this SystemPropertyChange.
94       * @param newValue The new value of this SystemPropertyChange.
95       */
96      private SystemPropertyChangeEnvironmentFacet(final Log log, final String key, final String newValue) {
97  
98          // Delegate
99          super(log);
100 
101         // Assign internal state
102         this.key = key;
103         this.originalValue = System.getProperty(key);
104         this.newValue = newValue;
105         this.type = existsAsSystemProperty(key) ? ChangeType.CHANGE : ChangeType.ADD;
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     @Override
112     public void setup() {
113 
114         if (type == ChangeType.REMOVE) {
115             System.clearProperty(key);
116         } else {
117             System.setProperty(key, newValue);
118         }
119 
120         if(log.isDebugEnabled()) {
121             log.debug("Setup " + toString());
122         }
123     }
124 
125     /**
126      * {@inheritDoc}
127      */
128     @Override
129     public void restore() {
130 
131         if (type == ChangeType.ADD) {
132             System.clearProperty(key);
133         } else {
134             System.setProperty(key, originalValue);
135         }
136 
137         if(log.isDebugEnabled()) {
138             log.debug("Restored " + toString());
139         }
140     }
141 
142     /**
143      * @return A Debug string representation of this SystemPropertyChangeEnvironmentFacet.
144      */
145     @Override
146     public String toString() {
147         final String toReturn = "SysProp key [" + key + "]\n"
148                 + "  ... Original value: [" + originalValue + "]\n"
149                 + "  ... Changed value : [" + newValue + "]";
150         return toReturn.replace("\n", AbstractJaxbMojo.NEWLINE);
151     }
152 
153     /**
154      * Creates a SystemPropertyChangesBuilder which uses the supplied active Maven Log.
155      *
156      * @param mavenLog The active Maven Log to be used by all SystemPropertyChange objects created
157      *                 by this SystemPropertyChangesBuilder.
158      * @return A SystemPropertyChangesBuilder ready for use.
159      */
160     public static SystemPropertyChangesBuilder getBuilder(final Log mavenLog) {
161         return new SystemPropertyChangesBuilder(mavenLog);
162     }
163 
164     /**
165      * Builder class intended to simplify creating SystemPropertyChange EnvironmentFacets.
166      */
167     public static class SystemPropertyChangesBuilder {
168 
169         // Internal state
170         private List<SystemPropertyChangeEnvironmentFacet> toReturn;
171         private Log mavenLog;
172 
173         private SystemPropertyChangesBuilder(final Log mavenLog) {
174 
175             // Check sanity
176             Validate.notNull(mavenLog, "mavenLog");
177 
178             // Assign internal state
179             this.toReturn = new ArrayList<SystemPropertyChangeEnvironmentFacet>();
180             this.mavenLog = mavenLog;
181         }
182 
183         /**
184          * Adds a SystemPropertyChange which removes the named System property.
185          *
186          * @param propertyName The name of the system property for which to create a REMOVE-type SystemPropertyChange.
187          * @return This builder, for chaining.
188          * @see SystemPropertyChangeEnvironmentFacet.ChangeType#REMOVE
189          */
190         public SystemPropertyChangesBuilder remove(final String propertyName) {
191 
192             // Check sanity
193             checkSanity(propertyName);
194 
195             // Add the SystemPropertyChange.
196             toReturn.add(new SystemPropertyChangeEnvironmentFacet(mavenLog, propertyName));
197 
198             // All done.
199             return this;
200         }
201 
202         /**
203          * Adds a SystemPropertyChange which adds or changes the named System property.
204          *
205          * @param propertyName The name of the system property for which to create an
206          *                     ADD- or CREATE-type SystemPropertyChange.
207          * @return This builder, for chaining.
208          * @see SystemPropertyChangeEnvironmentFacet.ChangeType#ADD
209          * @see SystemPropertyChangeEnvironmentFacet.ChangeType#CHANGE
210          */
211         public SystemPropertyChangesBuilder addOrChange(final String propertyName, final String value) {
212 
213             // Check sanity
214             checkSanity(propertyName);
215 
216             // Add the SystemPropertyChange.
217             toReturn.add(new SystemPropertyChangeEnvironmentFacet(mavenLog, propertyName, value));
218 
219             // All done.
220             return this;
221 
222         }
223 
224         /**
225          * @return A List of SystemPropertyChange EnvironmentFacets which can be included as required into the
226          * ToolExecutionEnvironment.
227          */
228         public List<SystemPropertyChangeEnvironmentFacet> build() {
229             return toReturn;
230         }
231 
232         //
233         // Private helpers
234         //
235 
236         private void checkSanity(final String propertyName) {
237 
238             // Check sanity
239             Validate.notEmpty(propertyName, "propertyName");
240 
241             // Validate that the property name is not already present as a SystemPropertyChange.
242             for (SystemPropertyChangeEnvironmentFacet current : toReturn) {
243                 if (current.key.equals(propertyName)) {
244                     throw new IllegalArgumentException("A SystemPropertyChange for propertyName '" + propertyName +
245                             "' is already present. Only one SystemPropertyChange per propertyName should be supplied.");
246                 }
247             }
248         }
249     }
250 
251     //
252     // Private helpers
253     //
254 
255     private boolean existsAsSystemProperty(final String key) {
256         return System.getProperties().keySet().contains(key);
257     }
258 }