View Javadoc

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