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