View Javadoc

1   /**
2    * Copyright 2009-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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  package org.codehaus.mojo.properties;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.text.SimpleDateFormat;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Date;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Properties;
27  import java.util.Set;
28  
29  import org.apache.commons.io.FileUtils;
30  import org.apache.maven.plugin.MojoExecutionException;
31  import org.apache.maven.plugin.MojoFailureException;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  /**
35   * Writes project properties to a file.
36   * 
37   * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
38   * @version $Id: WriteProjectProperties.java 9747 2009-05-20 13:27:44Z mark $
39   * @goal write-project-properties
40   */
41  public class WriteProjectProperties extends AbstractWritePropertiesMojo {
42      private static final String[] ESCAPE_CHARS = { "\n", "\r", "\t", ":", "#", "=" };
43  
44      /**
45       * If true, the plugin will create the properties file formatted the same way Ant formats properties files using the
46       * <code>echoproperties</code> task. This mode adds 3 custom properties at the top of the file, DSTAMP, TODAY, and
47       * TSTAMP
48       * 
49       * @parameter default-value="false" expression="${properties.antEchoPropertiesMode}"
50       */
51      private boolean antEchoPropertiesMode;
52  
53      /**
54       * If true, the plugin will include system properties when writing the properties file. System properties override
55       * both environment variables and project properties.
56       * 
57       * @parameter default-value="false" expression="${properties.includeSystemProperties}"
58       */
59      private boolean includeSystemProperties;
60  
61      /**
62       * If true, the plugin will include environment variables when writing the properties file. Environment variables
63       * are prefixed with "env". Environment variables override project properties.
64       * 
65       * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}"
66       */
67      private boolean includeEnvironmentVariables;
68  
69      /**
70       * Comma separated set of properties to exclude when writing the properties file
71       * 
72       * @parameter expression="${properties.exclude}"
73       */
74      private String exclude;
75  
76      /**
77       * Comma separated set of properties to write to the properties file. If provided, only the properties matching
78       * those supplied here will be written to the properties file.
79       * 
80       * @parameter expression="${properties.include}"
81       */
82      private String include;
83  
84      @Override
85      public void execute() throws MojoExecutionException, MojoFailureException {
86          Properties properties = new Properties();
87          // Add project properties
88          properties.putAll(project.getProperties());
89          if (includeEnvironmentVariables) {
90              // Add environment variables, overriding any properties with the same key
91              properties.putAll(getEnvironmentVariables());
92          }
93          if (includeSystemProperties) {
94              // Add system properties, overriding any properties with the same key
95              properties.putAll(System.getProperties());
96          }
97  
98          // Remove properties as appropriate
99          trim(properties, exclude, include);
100 
101         String comment = "# " + new Date() + "\n";
102         if (antEchoPropertiesMode) {
103             comment = getAntHeader();
104             properties.remove("DSTAMP");
105             properties.remove("TODAY");
106             properties.remove("TSTAMP");
107         }
108 
109         getLog().info("Creating " + outputFile);
110         writeProperties(outputFile, comment, properties);
111     }
112 
113     protected Properties getEnvironmentVariables() {
114         String prefix = "env";
115         Map<String, String> map = System.getenv();
116         Properties props = new Properties();
117         for (String key : map.keySet()) {
118             String newKey = prefix + "." + key;
119             String value = map.get(key);
120             props.setProperty(newKey, value);
121         }
122         return props;
123     }
124 
125     protected void trim(Properties properties, String omitCSV, String includeCSV) {
126         List<String> omitKeys = ReadPropertiesMojo.getListFromCSV(omitCSV);
127         for (String key : omitKeys) {
128             properties.remove(key);
129         }
130         if (StringUtils.isBlank(includeCSV)) {
131             return;
132         }
133         List<String> includeKeys = ReadPropertiesMojo.getListFromCSV(includeCSV);
134         Set<String> keys = properties.stringPropertyNames();
135         for (String key : keys) {
136             if (!includeKeys.contains(key)) {
137                 properties.remove(key);
138             }
139         }
140     }
141 
142     protected String getAntHeader() throws MojoExecutionException {
143         SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd");
144         SimpleDateFormat today = new SimpleDateFormat("MMMM d yyyy");
145         SimpleDateFormat tstamp = new SimpleDateFormat("HHmm");
146         Date now = new Date();
147         StringBuilder sb = new StringBuilder();
148         sb.append("# Ant properties\n");
149         sb.append("# " + now + "\n");
150         sb.append("DSTAMP=" + dstamp.format(now) + "\n");
151         sb.append("TODAY=" + today.format(now) + "\n");
152         sb.append("TSTAMP=" + tstamp.format(now) + "\n");
153         return sb.toString();
154     }
155 
156     protected void writeProperties(File file, String comment, Properties properties) throws MojoExecutionException {
157         List<String> names = new ArrayList<String>(properties.stringPropertyNames());
158         Collections.sort(names);
159         StringBuilder sb = new StringBuilder();
160         if (!StringUtils.isBlank(comment)) {
161             sb.append(comment);
162         }
163         for (String name : names) {
164             String value = properties.getProperty(name);
165             String escapedValue = escape(value, ESCAPE_CHARS);
166             sb.append(name + "=" + escapedValue + "\n");
167         }
168         try {
169             FileUtils.writeStringToFile(file, sb.toString());
170         } catch (IOException e) {
171             throw new MojoExecutionException("Error creating properties file", e);
172         }
173     }
174 
175     protected String escape(String s, String[] escapeChars) {
176         for (String escapeChar : escapeChars) {
177             s = s.replace(escapeChar, "\\" + escapeChar);
178         }
179         return s;
180 
181     }
182 
183     public boolean isAntEchoPropertiesMode() {
184         return antEchoPropertiesMode;
185     }
186 
187     public void setAntEchoPropertiesMode(boolean antEchoPropertiesMode) {
188         this.antEchoPropertiesMode = antEchoPropertiesMode;
189     }
190 
191     public boolean isIncludeSystemProperties() {
192         return includeSystemProperties;
193     }
194 
195     public void setIncludeSystemProperties(boolean includeSystemProperties) {
196         this.includeSystemProperties = includeSystemProperties;
197     }
198 }