View Javadoc

1   /*
2    * $Id: PropertiesUtils.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.util;
12  
13  import org.mule.config.i18n.CoreMessages;
14  import org.mule.config.i18n.Message;
15  
16  import java.io.IOException;
17  import java.io.InputStream;
18  import java.net.URL;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Properties;
24  
25  import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
26  
27  /**
28   * <code>PropertiesHelper</code> is a utility class for manipulating and filtering
29   * property Maps.
30   */
31  // @ThreadSafe
32  public final class PropertiesUtils
33  {
34      // @GuardedBy(itself)
35      private static final List maskedProperties = new CopyOnWriteArrayList();
36  
37      static
38      {
39          // When printing property lists mask password fields
40          // Users can register their own fields to mask
41          registerMaskedPropertyName("password");
42      }
43  
44      /** Do not instanciate. */
45      protected PropertiesUtils()
46      {
47          // no-op
48      }
49  
50      /**
51       * Register a property name for masking. This will prevent certain values from
52       * leaking e.g. into debugging output or logfiles.
53       *
54       * @param name the key of the property to be masked.
55       * @throws IllegalArgumentException is name is null or empty.
56       */
57      public static void registerMaskedPropertyName(String name)
58      {
59          if (StringUtils.isNotEmpty(name))
60          {
61              maskedProperties.add(name);
62          }
63          else
64          {
65              throw new IllegalArgumentException("Cannot mask empty property name.");
66          }
67      }
68  
69      /**
70       * Returns the String representation of the property value or a masked String if
71       * the property key has been registered previously via
72       * {@link #registerMaskedPropertyName(String)}.
73       *
74       * @param property a key/value pair
75       * @return String of the property value or a "masked" String that hides the
76       *         contents, or <code>null</code> if the property, its key or its value
77       *         is <code>null</code>.
78       */
79      public static String maskedPropertyValue(Map.Entry property)
80      {
81          if (property == null)
82          {
83              return null;
84          }
85  
86          Object key = property.getKey();
87          Object value = property.getValue();
88  
89          if (key == null || value == null)
90          {
91              return null;
92          }
93  
94          if (maskedProperties.contains(key))
95          {
96              return ("*****");
97          }
98          else
99          {
100             return value.toString();
101         }
102     }
103 
104     /**
105      * Read in the properties from a properties file. The file may be on the file
106      * system or the classpath.
107      *
108      * @param fileName     - The name of the properties file
109      * @param callingClass - The Class which is calling this method. This is used to
110      *                     determine the classpath.
111      * @return a java.util.Properties object containing the properties.
112      */
113     public static synchronized Properties loadProperties(String fileName, final Class callingClass)
114             throws IOException
115     {
116         InputStream is = IOUtils.getResourceAsStream(fileName, callingClass,
117                 /* tryAsFile */true, /* tryAsUrl */false);
118         if (is == null)
119         {
120             Message error = CoreMessages.cannotLoadFromClasspath(fileName);
121             throw new IOException(error.toString());
122         }
123         
124         return loadProperties(is);
125     }
126     
127     public static Properties loadProperties(URL url) throws IOException
128     {
129         if (url == null)
130         {
131             Message error = CoreMessages.objectIsNull("url");
132             throw new IOException(error.toString());
133         }
134         
135         return loadProperties(url.openStream());
136     }
137     
138     public static Properties loadProperties(InputStream is) throws IOException
139     {
140         if (is == null)
141         {
142             Message error = CoreMessages.objectIsNull("input stream");
143             throw new IOException(error.toString());
144         }
145 
146         try
147         {
148             Properties props = new Properties();
149             props.load(is);
150             return props;
151         }
152         finally
153         {
154             is.close();
155         }
156     }
157 
158     public static String removeXmlNamespacePrefix(String eleName)
159     {
160         int i = eleName.indexOf(':');
161         return (i == -1 ? eleName : eleName.substring(i + 1, eleName.length()));
162     }
163 
164     public static String removeNamespacePrefix(String eleName)
165     {
166         int i = eleName.lastIndexOf('.');
167         return (i == -1 ? eleName : eleName.substring(i + 1, eleName.length()));
168     }
169 
170     public static Map removeNamespaces(Map properties)
171     {
172         HashMap props = new HashMap(properties.size());
173         Map.Entry entry;
174         for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();)
175         {
176             entry = (Map.Entry) iter.next();
177             props.put(removeNamespacePrefix((String) entry.getKey()), entry.getValue());
178 
179         }
180         return props;
181     }
182 
183     /**
184      * Will create a map of properties where the names have a prefix Allows the
185      * callee to supply the target map so a comparator can be set
186      *
187      * @param props    the source set of properties
188      * @param prefix   the prefix to filter on
189      * @param newProps return map containing the filtered list of properties or an
190      *                 empty map if no properties matched the prefix
191      */
192     public static void getPropertiesWithPrefix(Map props, String prefix, Map newProps)
193     {
194         if (props == null)
195         {
196             return;
197         }
198 
199         for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();)
200         {
201             Map.Entry entry = (Map.Entry) iterator.next();
202             Object key = entry.getKey();
203             if (key.toString().startsWith(prefix))
204             {
205                 newProps.put(key, entry.getValue());
206             }
207         }
208     }
209 
210     public static Map getPropertiesWithoutPrefix(Map props, String prefix)
211     {
212         Map newProps = new HashMap();
213         for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();)
214         {
215             Map.Entry entry = (Map.Entry) iterator.next();
216             Object key = entry.getKey();
217             if (!key.toString().startsWith(prefix))
218             {
219                 newProps.put(key, entry.getValue());
220             }
221         }
222         return newProps;
223     }
224 
225     public static Properties getPropertiesFromQueryString(String query)
226     {
227         Properties props = new Properties();
228 
229         if (query == null)
230         {
231             return props;
232         }
233 
234         query = new StringBuffer(query.length() + 1).append('&').append(query).toString();
235 
236         int x = 0;
237         while ((x = addProperty(query, x, '&', props)) != -1)
238         {
239             // run
240         }
241 
242         return props;
243     }
244 
245     public static Properties getPropertiesFromString(String query, char separator)
246     {
247         Properties props = new Properties();
248 
249         if (query == null)
250         {
251             return props;
252         }
253 
254         query = new StringBuffer(query.length() + 1).append(separator).append(query).toString();
255 
256         int x = 0;
257         while ((x = addProperty(query, x, separator, props)) != -1)
258         {
259             // run
260         }
261 
262         return props;
263     }
264 
265     private static int addProperty(String query, int start, char separator, Properties properties)
266     {
267         int i = query.indexOf(separator, start);
268         int i2 = query.indexOf(separator, i + 1);
269         String pair;
270         if (i > -1 && i2 > -1)
271         {
272             pair = query.substring(i + 1, i2);
273         }
274         else if (i > -1)
275         {
276             pair = query.substring(i + 1);
277         }
278         else
279         {
280             return -1;
281         }
282         int eq = pair.indexOf('=');
283 
284         if (eq <= 0)
285         {
286             String key = pair;
287             String value = StringUtils.EMPTY;
288             properties.setProperty(key, value);
289         }
290         else
291         {
292             String key = pair.substring(0, eq);
293             String value = (eq == pair.length() ? StringUtils.EMPTY : pair.substring(eq + 1));
294             properties.setProperty(key, value);
295         }
296         return i2;
297     }
298 
299     /** @deprecated Use {@link MapUtils#toString(Map, boolean)} instead */
300     public static String propertiesToString(Map props, boolean newline)
301     {
302         return MapUtils.toString(props, newline);
303     }
304 }