View Javadoc

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