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.List;
020    import java.util.Properties;
021    
022    import org.apache.maven.plugin.MojoExecutionException;
023    import org.apache.maven.plugin.MojoFailureException;
024    import org.kuali.common.util.CollectionUtils;
025    import org.kuali.common.util.PropertyUtils;
026    import org.kuali.common.util.property.Constants;
027    import org.springframework.util.PropertyPlaceholderHelper;
028    
029    /**
030     * Write project properties to a file.
031     *
032     * @author Jeff Caddel
033     *
034     * @goal write-project-properties
035     */
036    public class WriteProjectProperties extends AbstractWritePropertiesMojo {
037    
038            /**
039             * If true, the plugin will include system properties when writing the properties file. System properties override both environment
040             * variables and project properties.
041             *
042             * @parameter default-value="false" expression="${properties.includeSystemProperties}"
043             */
044            private boolean includeSystemProperties;
045    
046            /**
047             * If true, the plugin will include environment variables when writing the properties file. Environment variables are prefixed with
048             * "env". Environment variables override project properties.
049             *
050             * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}"
051             */
052            private boolean includeEnvironmentVariables;
053    
054            /**
055             * Comma separated set of properties to exclude when writing the properties file
056             *
057             * @parameter expression="${properties.exclude}"
058             */
059            private String exclude;
060    
061            /**
062             * Comma separated set of properties to write to the properties file. If provided, only the properties matching those supplied here will
063             * be written to the properties file.
064             *
065             * @parameter expression="${properties.include}"
066             */
067            private String include;
068    
069            /**
070             * List of properties to include
071             *
072             * @parameter
073             */
074            private List<String> includes;
075    
076            /**
077             * List of properties to exclude
078             *
079             * @parameter
080             */
081            private List<String> excludes;
082    
083            /**
084             * If true placeholders are resolved before writing properties to the file
085             *
086             * @parameter expression="${properties.resolvePlaceholders}" default-value="false"
087             */
088            private boolean resolvePlaceholders;
089    
090            /**
091             * @parameter expression="${properties.includeStandardMavenProperties}" default-value="false"
092             */
093            private boolean includeStandardMavenProperties;
094    
095            @Override
096            public void execute() throws MojoExecutionException, MojoFailureException {
097                    Properties properties = new Properties();
098    
099                    // Add project properties
100                    properties.putAll(project.getProperties());
101    
102                    if (includeStandardMavenProperties) {
103                            properties.putAll(getStandardMavenProperties(project));
104                    }
105    
106                    // Add environment variables, overriding any existing properties with the same key
107                    if (includeEnvironmentVariables) {
108                            properties.putAll(PropertyUtils.getEnvAsProperties());
109                    }
110    
111                    // Add system properties, overriding any existing properties with the same key
112                    if (includeSystemProperties) {
113                            properties.putAll(System.getProperties());
114                    }
115    
116                    List<String> includeList = getList(includes, include);
117                    List<String> excludeList = getList(excludes, exclude);
118    
119                    override(properties, includeList);
120    
121                    // Resolve placeholders
122                    if (resolvePlaceholders) {
123                            properties = getResolvedProperties(properties);
124                    }
125    
126                    // Remove properties as appropriate
127                    PropertyUtils.trim(properties, includeList, excludeList);
128    
129                    getLog().info("Creating " + outputFile);
130    
131                    // Save the properties to a file
132                    writeProperties(this.outputFile, properties, this.outputStyle, this.prefix);
133            }
134    
135            protected void override(Properties properties, List<String> includes) {
136                    List<String> keys = getKeys(properties, includes);
137                    Properties global = PropertyUtils.getGlobalProperties(properties);
138                    properties.clear();
139                    for (String key : keys) {
140                            String value = global.getProperty(key);
141                            if (value != null) {
142                                    properties.setProperty(key, value);
143                            }
144                    }
145            }
146    
147            protected List<String> getKeys(Properties properties, List<String> keys) {
148                    List<String> newKeys = PropertyUtils.getSortedKeys(properties);
149                    for (String key : keys) {
150                            if (!newKeys.contains(key)) {
151                                    newKeys.add(key);
152                            }
153                    }
154                    return newKeys;
155            }
156    
157            protected Properties getResolvedProperties(Properties props) {
158                    PropertyPlaceholderHelper pph = Constants.DEFAULT_PROPERTY_PLACEHOLDER_HELPER;
159                    List<String> keys = PropertyUtils.getSortedKeys(props);
160                    Properties newProps = new Properties();
161                    for (String key : keys) {
162                            String originalValue = props.getProperty(key);
163                            String resolvedValue = pph.replacePlaceholders(originalValue, props);
164                            newProps.setProperty(key, resolvedValue);
165                    }
166                    return newProps;
167    
168            }
169    
170            protected List<String> getList(List<String> list, String csv) {
171                    List<String> newList = new ArrayList<String>();
172                    if (!CollectionUtils.isEmpty(list)) {
173                            newList.addAll(list);
174                    }
175                    List<String> csvList = CollectionUtils.getTrimmedListFromCSV(csv);
176                    for (String element : csvList) {
177                            if (!newList.contains(element)) {
178                                    newList.add(element);
179                            }
180                    }
181                    return newList;
182            }
183    
184            public boolean isIncludeSystemProperties() {
185                    return includeSystemProperties;
186            }
187    
188            public void setIncludeSystemProperties(boolean includeSystemProperties) {
189                    this.includeSystemProperties = includeSystemProperties;
190            }
191    
192            public boolean isIncludeEnvironmentVariables() {
193                    return includeEnvironmentVariables;
194            }
195    
196            public void setIncludeEnvironmentVariables(boolean includeEnvironmentVariables) {
197                    this.includeEnvironmentVariables = includeEnvironmentVariables;
198            }
199    
200            public String getExclude() {
201                    return exclude;
202            }
203    
204            public void setExclude(String exclude) {
205                    this.exclude = exclude;
206            }
207    
208            public String getInclude() {
209                    return include;
210            }
211    
212            public void setInclude(String include) {
213                    this.include = include;
214            }
215    
216            public boolean isResolvePlaceholders() {
217                    return resolvePlaceholders;
218            }
219    
220            public void setResolvePlaceholders(boolean resolvePlaceholders) {
221                    this.resolvePlaceholders = resolvePlaceholders;
222            }
223    
224            public boolean isIncludeStandardMavenProperties() {
225                    return includeStandardMavenProperties;
226            }
227    
228            public void setIncludeStandardMavenProperties(boolean includeStandardMavenProperties) {
229                    this.includeStandardMavenProperties = includeStandardMavenProperties;
230            }
231    
232            public List<String> getIncludes() {
233                    return includes;
234            }
235    
236            public void setIncludes(List<String> includes) {
237                    this.includes = includes;
238            }
239    
240    }