1 /**
2 * Copyright 2009-2011 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.codehaus.mojo.properties;
17
18 /*
19 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
20 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
21 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
22 * License. You may obtain a copy of the License at
23 *
24 * http://www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
27 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
28 * specific language governing permissions and limitations under the License.
29 */
30
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.IOException;
34 import java.util.Enumeration;
35 import java.util.Properties;
36
37 import org.apache.maven.plugin.AbstractMojo;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.project.MavenProject;
40 import org.codehaus.plexus.util.cli.CommandLineUtils;
41
42 /**
43 * The read-project-properties goal reads property files and stores the properties as project properties. It serves as
44 * an alternate to specifying properties in pom.xml.
45 *
46 * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
47 * @author <a href="mailto:Krystian.Nowak@gmail.com">Krystian Nowak</a>
48 * @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $
49 * @goal read-project-properties
50 */
51 public class ReadPropertiesMojo extends AbstractMojo {
52 /**
53 * @parameter default-value="${project}"
54 * @required
55 * @readonly
56 */
57 private MavenProject project;
58
59 /**
60 * The properties files that will be used when reading properties. Can use both .properties and .xml files
61 *
62 * @parameter
63 * @required
64 */
65 private File[] files;
66
67 /**
68 * If the plugin should be quiet if any of the files was not found
69 *
70 * @parameter default-value="false"
71 */
72 private boolean quiet;
73
74 public void execute() throws MojoExecutionException {
75 Properties projectProperties = new Properties();
76 for (int i = 0; i < files.length; i++) {
77 File file = files[i];
78
79 if (file.exists()) {
80 try {
81 getLog().debug("Loading property file: " + file);
82
83 FileInputStream stream = new FileInputStream(file);
84 projectProperties = project.getProperties();
85
86 try {
87 String filename = file.getName().toLowerCase();
88 if (filename.endsWith(".xml")) {
89 projectProperties.loadFromXML(stream);
90 } else {
91 projectProperties.load(stream);
92 }
93 } finally {
94 if (stream != null) {
95 stream.close();
96 }
97 }
98 } catch (IOException e) {
99 throw new MojoExecutionException("Error reading properties file " + file.getAbsolutePath(), e);
100 }
101 } else {
102 if (quiet) {
103 getLog().warn("Ignoring missing properties file: " + file.getAbsolutePath());
104 } else {
105 throw new MojoExecutionException("Properties file not found: " + file.getAbsolutePath());
106 }
107 }
108 }
109
110 boolean useEnvVariables = false;
111 for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
112 String k = (String) n.nextElement();
113 String p = (String) projectProperties.get(k);
114 if (p.indexOf("${env.") != -1) {
115 useEnvVariables = true;
116 break;
117 }
118 }
119 Properties environment = null;
120 if (useEnvVariables) {
121 try {
122 environment = CommandLineUtils.getSystemEnvVars();
123 } catch (IOException e) {
124 throw new MojoExecutionException("Error getting system envorinment variables: ", e);
125 }
126 }
127 for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
128 String k = (String) n.nextElement();
129 projectProperties.setProperty(k, getPropertyValue(k, projectProperties, environment));
130 }
131 }
132
133 /**
134 * Retrieves a property value, replacing values like ${token} using the Properties to look them up. Shamelessly
135 * adapted from:
136 * http://maven.apache.org/plugins/maven-war-plugin/xref/org/apache/maven/plugin/war/PropertyUtils.html
137 *
138 * It will leave unresolved properties alone, trying for System properties, and environment variables and implements
139 * reparsing (in the case that the value of a property contains a key), and will not loop endlessly on a pair like
140 * test = ${test}
141 *
142 * @param k
143 * property key
144 * @param p
145 * project properties
146 * @param environment
147 * environment variables
148 * @return resolved property value
149 */
150 private String getPropertyValue(String k, Properties p, Properties environment) {
151 String v = p.getProperty(k);
152 String ret = "";
153 int idx, idx2;
154
155 while ((idx = v.indexOf("${")) >= 0) {
156 // append prefix to result
157 ret += v.substring(0, idx);
158
159 // strip prefix from original
160 v = v.substring(idx + 2);
161
162 idx2 = v.indexOf("}");
163
164 // if no matching } then bail
165 if (idx2 < 0) {
166 break;
167 }
168
169 // strip out the key and resolve it
170 // resolve the key/value for the ${statement}
171 String nk = v.substring(0, idx2);
172 v = v.substring(idx2 + 1);
173 String nv = p.getProperty(nk);
174
175 // try global environment
176 if (nv == null) {
177 nv = System.getProperty(nk);
178 }
179
180 // try environment variable
181 if (nv == null && nk.startsWith("env.") && environment != null) {
182 nv = environment.getProperty(nk.substring(4));
183 }
184
185 // if the key cannot be resolved,
186 // leave it alone ( and don't parse again )
187 // else prefix the original string with the
188 // resolved property ( so it can be parsed further )
189 // taking recursion into account.
190 if (nv == null || nv.equals(nk)) {
191 ret += "${" + nk + "}";
192 } else {
193 v = nv + v;
194 }
195 }
196 return ret + v;
197 }
198 }