001 /**
002 * Copyright 2009-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.codehaus.mojo.properties;
017
018 import java.io.File;
019 import java.io.IOException;
020 import java.text.SimpleDateFormat;
021 import java.util.ArrayList;
022 import java.util.Collections;
023 import java.util.Date;
024 import java.util.List;
025 import java.util.Map;
026 import java.util.Properties;
027 import java.util.Set;
028
029 import org.apache.commons.io.FileUtils;
030 import org.apache.maven.plugin.MojoExecutionException;
031 import org.apache.maven.plugin.MojoFailureException;
032 import org.codehaus.plexus.util.StringUtils;
033
034 /**
035 * Writes project properties to a file.
036 *
037 * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
038 * @version $Id: WriteProjectProperties.java 9747 2009-05-20 13:27:44Z mark $
039 * @goal write-project-properties
040 */
041 public class WriteProjectProperties extends AbstractWritePropertiesMojo {
042 private static final String[] ESCAPE_CHARS = { "\n", "\r", "\t", ":", "#", "=" };
043
044 /**
045 * If true, the plugin will create the properties file formatted the same way Ant formats properties files using the
046 * <code>echoproperties</code> task. This mode adds 3 custom properties at the top of the file, DSTAMP, TODAY, and
047 * TSTAMP
048 *
049 * @parameter default-value="false" expression="${properties.antEchoPropertiesMode}"
050 */
051 private boolean antEchoPropertiesMode;
052
053 /**
054 * If true, the plugin will include system properties when writing the properties file. System properties override
055 * both environment variables and project properties.
056 *
057 * @parameter default-value="false" expression="${properties.includeSystemProperties}"
058 */
059 private boolean includeSystemProperties;
060
061 /**
062 * If true, the plugin will include environment variables when writing the properties file. Environment variables
063 * are prefixed with "env". Environment variables override project properties.
064 *
065 * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}"
066 */
067 private boolean includeEnvironmentVariables;
068
069 /**
070 * Comma separated set of properties to exclude when writing the properties file
071 *
072 * @parameter expression="${properties.exclude}"
073 */
074 private String exclude;
075
076 /**
077 * Comma separated set of properties to write to the properties file. If provided, only the properties matching
078 * those supplied here will be written to the properties file.
079 *
080 * @parameter expression="${properties.include}"
081 */
082 private String include;
083
084 @Override
085 public void execute() throws MojoExecutionException, MojoFailureException {
086 Properties properties = new Properties();
087 // Add project properties
088 properties.putAll(project.getProperties());
089 if (includeEnvironmentVariables) {
090 // Add environment variables, overriding any properties with the same key
091 properties.putAll(getEnvironmentVariables());
092 }
093 if (includeSystemProperties) {
094 // Add system properties, overriding any properties with the same key
095 properties.putAll(System.getProperties());
096 }
097
098 // Remove properties as appropriate
099 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 }