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