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 /*
019 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
020 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
021 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
022 * License. You may obtain a copy of the License at
023 *
024 * http://www.apache.org/licenses/LICENSE-2.0
025 *
026 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
027 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
028 * specific language governing permissions and limitations under the License.
029 */
030
031 import java.io.File;
032 import java.io.FileInputStream;
033 import java.io.IOException;
034 import java.io.InputStream;
035 import java.util.Enumeration;
036 import java.util.Properties;
037
038 import org.apache.commons.io.IOUtils;
039 import org.apache.maven.plugin.AbstractMojo;
040 import org.apache.maven.plugin.MojoExecutionException;
041 import org.apache.maven.project.MavenProject;
042 import org.codehaus.plexus.util.cli.CommandLineUtils;
043
044 /**
045 * The read-project-properties goal reads property files and stores the properties as project properties. It serves as
046 * an alternate to specifying properties in pom.xml.
047 *
048 * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
049 * @author <a href="mailto:Krystian.Nowak@gmail.com">Krystian Nowak</a>
050 * @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $
051 * @goal read-project-properties
052 */
053 public class ReadPropertiesMojo extends AbstractMojo {
054
055 /**
056 * @parameter default-value="${project}"
057 * @required
058 * @readonly
059 */
060 private MavenProject project;
061
062 /**
063 * The properties files that will be used when reading properties. Can use both .properties and .xml files
064 *
065 * @parameter
066 * @required
067 */
068 private File[] files;
069
070 /**
071 * If true, the plugin will ignore any non-existent properties files
072 *
073 * @parameter default-value="false"
074 */
075 private boolean quiet;
076
077 public void execute() throws MojoExecutionException {
078 Properties projectProperties = project.getProperties();
079 for (int i = 0; i < files.length; i++) {
080 File file = files[i];
081 if (validate(file)) {
082 load(file, projectProperties);
083 }
084 }
085
086 boolean useEnvVariables = false;
087 for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
088 String k = (String) n.nextElement();
089 String p = (String) projectProperties.get(k);
090 if (p.indexOf("${env.") != -1) {
091 useEnvVariables = true;
092 break;
093 }
094 }
095 Properties environment = null;
096 if (useEnvVariables) {
097 try {
098 environment = CommandLineUtils.getSystemEnvVars();
099 } catch (IOException e) {
100 throw new MojoExecutionException("Error getting system envorinment variables: ", e);
101 }
102 }
103 for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
104 String k = (String) n.nextElement();
105 projectProperties.setProperty(k, getPropertyValue(k, projectProperties, environment));
106 }
107 }
108
109 /**
110 * Retrieves a property value, replacing values like ${token} using the Properties to look them up. Shamelessly
111 * adapted from:
112 * http://maven.apache.org/plugins/maven-war-plugin/xref/org/apache/maven/plugin/war/PropertyUtils.html
113 *
114 * It will leave unresolved properties alone, trying for System properties, and environment variables and implements
115 * reparsing (in the case that the value of a property contains a key), and will not loop endlessly on a pair like
116 * test = ${test}
117 *
118 * @param k
119 * property key
120 * @param p
121 * project properties
122 * @param environment
123 * environment variables
124 * @return resolved property value
125 */
126 protected String getPropertyValue(String k, Properties p, Properties environment) {
127 String v = p.getProperty(k);
128 String ret = "";
129 int idx, idx2;
130
131 while ((idx = v.indexOf("${")) >= 0) {
132 // append prefix to result
133 ret += v.substring(0, idx);
134
135 // strip prefix from original
136 v = v.substring(idx + 2);
137
138 idx2 = v.indexOf("}");
139
140 // if no matching } then bail
141 if (idx2 < 0) {
142 break;
143 }
144
145 // strip out the key and resolve it
146 // resolve the key/value for the ${statement}
147 String nk = v.substring(0, idx2);
148 v = v.substring(idx2 + 1);
149 String nv = p.getProperty(nk);
150
151 // try global environment
152 if (nv == null) {
153 nv = System.getProperty(nk);
154 }
155
156 // try environment variable
157 if (nv == null && nk.startsWith("env.") && environment != null) {
158 nv = environment.getProperty(nk.substring(4));
159 }
160
161 // if the key cannot be resolved,
162 // leave it alone ( and don't parse again )
163 // else prefix the original string with the
164 // resolved property ( so it can be parsed further )
165 // taking recursion into account.
166 if (nv == null || nv.equals(nk)) {
167 ret += "${" + nk + "}";
168 } else {
169 v = nv + v;
170 }
171 }
172 return ret + v;
173 }
174
175 protected boolean validate(File file) throws MojoExecutionException {
176 boolean exists = file != null && file.exists();
177 if (exists) {
178 return true;
179 }
180 if (quiet) {
181 getLog().info("Ignoring non-existent properties file '" + file + "'");
182 return false;
183 } else {
184 throw new MojoExecutionException("Non-existent properties file '" + file + "'");
185 }
186 }
187
188 protected void load(File file, Properties properties) throws MojoExecutionException {
189 InputStream in = null;
190 try {
191 getLog().info("Loading " + file);
192 in = new FileInputStream(file);
193 String filename = file.getName().toLowerCase();
194 if (filename.endsWith(".xml")) {
195 properties.loadFromXML(in);
196 } else {
197 properties.load(in);
198 }
199 } catch (IOException e) {
200 throw new MojoExecutionException("Error reading properties file " + file.getAbsolutePath(), e);
201 } finally {
202 IOUtils.closeQuietly(in);
203 }
204 }
205
206 }