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.Properties;
026    
027    import org.apache.commons.io.FileUtils;
028    import org.apache.maven.plugin.MojoExecutionException;
029    import org.apache.maven.plugin.MojoFailureException;
030    
031    /**
032     * Writes project properties to a file.
033     *
034     * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
035     * @version $Id: WriteProjectProperties.java 9747 2009-05-20 13:27:44Z mark $
036     * @goal write-project-properties
037     */
038    public class WriteProjectProperties extends AbstractWritePropertiesMojo {
039    
040        /**
041         * If true, the plugin will create the properties file formatted the same way Ant formats properties files using the
042         * &lt;echoproperties&gt; task. The properties will be sorted by name with the ':', '#', '=', CR, LF, and TAB
043         * characters escaped with a backslash
044         *
045         * @parameter default-value="false" expression="${properties.antEchoPropertiesMode}"
046         */
047        private boolean antEchoPropertiesMode;
048    
049        /**
050         * If true, the plugin will include system properties when writing the properties file
051         *
052         * @parameter default-value="false" expression="${properties.includeSystemProperties}"
053         */
054        private boolean includeSystemProperties;
055    
056        /**
057         * Comma separated set of properties to omit from writing to the properties file
058         *
059         * @parameter expression="${properties.omit}"
060         */
061        private String omit;
062    
063        @Override
064        public void execute() throws MojoExecutionException, MojoFailureException {
065            validateOutputFile();
066            Properties properties = new Properties();
067            properties.putAll(project.getProperties());
068    
069            Properties systemProperties = System.getProperties();
070    
071            // Make sure system properties override Maven project properties
072            for (String key : systemProperties.stringPropertyNames()) {
073                String mavenValue = properties.getProperty(key);
074                String systemValue = systemProperties.getProperty(key);
075                // If we are including system properties, always put the system property
076                if (includeSystemProperties) {
077                    properties.put(key, systemValue);
078                } else if (mavenValue != null) {
079                    // Otherwise only update our properties object if the System property overrides a Maven project property
080                    properties.put(key, systemValue);
081                }
082            }
083    
084            remove(properties, omit);
085    
086            getLog().info("Creating " + outputFile);
087            if (antEchoPropertiesMode) {
088                echoPropertiesMode(outputFile, properties);
089            } else {
090                writeProperties(properties, outputFile);
091            }
092        }
093    
094        protected void remove(Properties properties, String csv) {
095            List<String> keys = ReadPropertiesMojo.getListFromCSV(csv);
096            for (String key : keys) {
097                properties.remove(key);
098            }
099    
100        }
101    
102        protected void echoPropertiesMode(File file, Properties properties) throws MojoExecutionException {
103            // DSTAMP=20120304
104            // TODAY=March 4 2012
105            // TSTAMP=1651
106            SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd");
107            SimpleDateFormat today = new SimpleDateFormat("MMMM d yyyy");
108            SimpleDateFormat tstamp = new SimpleDateFormat("HHmm");
109            List<String> names = new ArrayList<String>(properties.stringPropertyNames());
110            Collections.sort(names);
111            Date now = new Date();
112            StringBuilder sb = new StringBuilder();
113            sb.append("#Ant properties\n");
114            sb.append("#" + now + "\n");
115            sb.append("DSTAMP=" + dstamp.format(now) + "\n");
116            sb.append("TODAY=" + today.format(now) + "\n");
117            sb.append("TSTAMP=" + tstamp.format(now) + "\n");
118            for (String name : names) {
119                String value = properties.getProperty(name);
120                value = value.replace("\n", "\\n");
121                value = value.replace("\r", "\\r");
122                value = value.replace("\t", "\\t");
123                value = value.replace(":", "\\:");
124                value = value.replace("#", "\\#");
125                value = value.replace("=", "\\=");
126                sb.append(name + "=" + value + "\n");
127            }
128            try {
129                FileUtils.writeByteArrayToFile(file, sb.toString().getBytes());
130            } catch (IOException e) {
131                throw new MojoExecutionException("Error creating properties file", e);
132            }
133        }
134    
135        public boolean isAntEchoPropertiesMode() {
136            return antEchoPropertiesMode;
137        }
138    
139        public void setAntEchoPropertiesMode(boolean antEchoPropertiesMode) {
140            this.antEchoPropertiesMode = antEchoPropertiesMode;
141        }
142    
143        public boolean isIncludeSystemProperties() {
144            return includeSystemProperties;
145        }
146    
147        public void setIncludeSystemProperties(boolean includeSystemProperties) {
148            this.includeSystemProperties = includeSystemProperties;
149        }
150    }