View Javadoc

1   /**
2    * Copyright 2009-2012 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.io.InputStream;
35  import java.util.Enumeration;
36  import java.util.Properties;
37  
38  import org.apache.commons.io.IOUtils;
39  import org.apache.maven.plugin.AbstractMojo;
40  import org.apache.maven.plugin.MojoExecutionException;
41  import org.apache.maven.project.MavenProject;
42  import org.codehaus.plexus.util.cli.CommandLineUtils;
43  
44  /**
45   * The read-project-properties goal reads property files and stores the properties as project properties. It serves as
46   * an alternate to specifying properties in pom.xml.
47   *
48   * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
49   * @author <a href="mailto:Krystian.Nowak@gmail.com">Krystian Nowak</a>
50   * @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $
51   * @goal read-project-properties
52   */
53  public class ReadPropertiesMojo extends AbstractMojo {
54  
55      /**
56       * @parameter default-value="${project}"
57       * @required
58       * @readonly
59       */
60      private MavenProject project;
61  
62      /**
63       * The properties files that will be used when reading properties. Can use both .properties and .xml files
64       *
65       * @parameter
66       * @required
67       */
68      private File[] files;
69  
70      /**
71       * If true, the plugin will ignore any non-existent properties files
72       *
73       * @parameter default-value="false"
74       */
75      private boolean quiet;
76  
77      public void execute() throws MojoExecutionException {
78          Properties projectProperties = project.getProperties();
79          for (int i = 0; i < files.length; i++) {
80              File file = files[i];
81              if (validate(file)) {
82                  load(file, projectProperties);
83              }
84          }
85  
86          boolean useEnvVariables = false;
87          for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
88              String k = (String) n.nextElement();
89              String p = (String) projectProperties.get(k);
90              if (p.indexOf("${env.") != -1) {
91                  useEnvVariables = true;
92                  break;
93              }
94          }
95          Properties environment = null;
96          if (useEnvVariables) {
97              try {
98                  environment = CommandLineUtils.getSystemEnvVars();
99              } 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 }