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.io.OutputStream;
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.commons.io.IOUtils;
031 import org.apache.maven.plugin.MojoExecutionException;
032 import org.apache.maven.plugin.MojoFailureException;
033 import org.codehaus.plexus.util.StringUtils;
034 import org.springframework.util.PropertyPlaceholderHelper;
035
036 /**
037 * Write project properties to a file.
038 *
039 * @author Jeff Caddel
040 *
041 * @goal write-project-properties
042 */
043 public class WriteProjectProperties extends AbstractWritePropertiesMojo {
044
045 /**
046 * If true, the plugin will include system properties when writing the properties file. System properties override both environment
047 * variables and project properties.
048 *
049 * @parameter default-value="false" expression="${properties.includeSystemProperties}"
050 */
051 private boolean includeSystemProperties;
052
053 /**
054 * If true, the plugin will include environment variables when writing the properties file. Environment variables are prefixed with
055 * "env". Environment variables override project properties.
056 *
057 * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}"
058 */
059 private boolean includeEnvironmentVariables;
060
061 /**
062 * Comma separated set of properties to exclude when writing the properties file
063 *
064 * @parameter expression="${properties.exclude}"
065 */
066 private String exclude;
067
068 /**
069 * Comma separated set of properties to write to the properties file. If provided, only the properties matching those supplied here will
070 * be written to the properties file.
071 *
072 * @parameter expression="${properties.include}"
073 */
074 private String include;
075
076 /**
077 * If true placeholders are resolved before writing properties to the file
078 *
079 * @parameter expression="${properties.resolvePlaceholders}"
080 */
081 private boolean resolvePlaceholders;
082
083 @Override
084 public void execute() throws MojoExecutionException, MojoFailureException {
085 Properties properties = new Properties();
086 // Add project properties
087 properties.putAll(project.getProperties());
088 if (includeEnvironmentVariables) {
089 // Add environment variables, overriding any existing properties with the same key
090 properties.putAll(getEnvironmentVariables());
091 }
092 if (includeSystemProperties) {
093 // Add system properties, overriding any existing properties with the same key
094 properties.putAll(System.getProperties());
095 }
096
097 // Remove properties as appropriate
098 trim(properties, exclude, include);
099
100 if (resolvePlaceholders) {
101 properties = getResolvedProperties(properties);
102 }
103
104 String comment = "# " + new Date() + "\n";
105 getLog().info("Creating " + outputFile);
106 writeProperties(outputFile, comment, properties);
107 }
108
109 protected Properties getResolvedProperties(Properties props) {
110 PropertyPlaceholderHelper pph = new PropertyPlaceholderHelper("${", "}");
111 List<String> keys = new ArrayList<String>(props.stringPropertyNames());
112 Collections.sort(keys);
113 Properties newProps = new Properties();
114 for (String key : keys) {
115 String originalValue = props.getProperty(key);
116 String resolvedValue = pph.replacePlaceholders(originalValue, props);
117 newProps.setProperty(key, resolvedValue);
118 }
119 return newProps;
120
121 }
122
123 protected static Properties getEnvironmentVariables() {
124 String prefix = "env";
125 Map<String, String> map = System.getenv();
126 Properties props = new Properties();
127 for (String key : map.keySet()) {
128 String newKey = prefix + "." + key;
129 String value = map.get(key);
130 props.setProperty(newKey, value);
131 }
132 return props;
133 }
134
135 protected void trim(Properties properties, String excludeCSV, String includeCSV) {
136 List<String> omitKeys = ReadPropertiesMojo.getListFromCSV(excludeCSV);
137 for (String key : omitKeys) {
138 properties.remove(key);
139 }
140 if (StringUtils.isBlank(includeCSV)) {
141 return;
142 }
143 List<String> includeKeys = ReadPropertiesMojo.getListFromCSV(includeCSV);
144 Set<String> keys = properties.stringPropertyNames();
145 for (String key : keys) {
146 if (!includeKeys.contains(key)) {
147 properties.remove(key);
148 }
149 }
150 }
151
152 protected void writeProperties(File file, String comment, Properties properties) throws MojoExecutionException {
153 SortedProperties sp = new SortedProperties();
154 sp.putAll(properties);
155 OutputStream out = null;
156 try {
157 out = FileUtils.openOutputStream(file);
158 sp.store(out, comment);
159 } catch (IOException e) {
160 throw new MojoExecutionException("Error creating properties file", e);
161 } finally {
162 IOUtils.closeQuietly(out);
163 }
164 }
165
166 public boolean isIncludeSystemProperties() {
167 return includeSystemProperties;
168 }
169
170 public void setIncludeSystemProperties(boolean includeSystemProperties) {
171 this.includeSystemProperties = includeSystemProperties;
172 }
173
174 public boolean isIncludeEnvironmentVariables() {
175 return includeEnvironmentVariables;
176 }
177
178 public void setIncludeEnvironmentVariables(boolean includeEnvironmentVariables) {
179 this.includeEnvironmentVariables = includeEnvironmentVariables;
180 }
181
182 public String getExclude() {
183 return exclude;
184 }
185
186 public void setExclude(String exclude) {
187 this.exclude = exclude;
188 }
189
190 public String getInclude() {
191 return include;
192 }
193
194 public void setInclude(String include) {
195 this.include = include;
196 }
197
198 public boolean isResolvePlaceholders() {
199 return resolvePlaceholders;
200 }
201
202 public void setResolvePlaceholders(boolean resolvePlaceholders) {
203 this.resolvePlaceholders = resolvePlaceholders;
204 }
205 }