View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.util.internal;
17  
18  import io.netty.util.internal.logging.InternalLogger;
19  import io.netty.util.internal.logging.InternalLoggerFactory;
20  
21  import java.security.AccessController;
22  import java.security.PrivilegedAction;
23  import java.util.logging.Level;
24  import java.util.logging.Logger;
25  import java.util.regex.Pattern;
26  
27  /**
28   * A collection of utility methods to retrieve and parse the values of the Java system properties.
29   */
30  public final class SystemPropertyUtil {
31  
32      private static boolean initializedLogger;
33      private static final InternalLogger logger;
34      private static boolean loggedException;
35  
36      static {
37          initializedLogger = false;
38          logger = InternalLoggerFactory.getInstance(SystemPropertyUtil.class);
39          initializedLogger = true;
40      }
41  
42      /**
43       * Returns {@code true} if and only if the system property with the specified {@code key}
44       * exists.
45       */
46      public static boolean contains(String key) {
47          return get(key) != null;
48      }
49  
50      /**
51       * Returns the value of the Java system property with the specified
52       * {@code key}, while falling back to {@code null} if the property access fails.
53       *
54       * @return the property value or {@code null}
55       */
56      public static String get(String key) {
57          return get(key, null);
58      }
59  
60      /**
61       * Returns the value of the Java system property with the specified
62       * {@code key}, while falling back to the specified default value if
63       * the property access fails.
64       *
65       * @return the property value.
66       *         {@code def} if there's no such property or if an access to the
67       *         specified property is not allowed.
68       */
69      public static String get(final String key, String def) {
70          if (key == null) {
71              throw new NullPointerException("key");
72          }
73          if (key.isEmpty()) {
74              throw new IllegalArgumentException("key must not be empty.");
75          }
76  
77          String value = null;
78          try {
79              if (System.getSecurityManager() == null) {
80                  value = System.getProperty(key);
81              } else {
82                  value = AccessController.doPrivileged(new PrivilegedAction<String>() {
83                      @Override
84                      public String run() {
85                          return System.getProperty(key);
86                      }
87                  });
88              }
89          } catch (Exception e) {
90              if (!loggedException) {
91                  log("Unable to retrieve a system property '" + key + "'; default values will be used.", e);
92                  loggedException = true;
93              }
94          }
95  
96          if (value == null) {
97              return def;
98          }
99  
100         return value;
101     }
102 
103     /**
104      * Returns the value of the Java system property with the specified
105      * {@code key}, while falling back to the specified default value if
106      * the property access fails.
107      *
108      * @return the property value.
109      *         {@code def} if there's no such property or if an access to the
110      *         specified property is not allowed.
111      */
112     public static boolean getBoolean(String key, boolean def) {
113         String value = get(key);
114         if (value == null) {
115             return def;
116         }
117 
118         value = value.trim().toLowerCase();
119         if (value.isEmpty()) {
120             return true;
121         }
122 
123         if ("true".equals(value) || "yes".equals(value) || "1".equals(value)) {
124             return true;
125         }
126 
127         if ("false".equals(value) || "no".equals(value) || "0".equals(value)) {
128             return false;
129         }
130 
131         log(
132                 "Unable to parse the boolean system property '" + key + "':" + value + " - " +
133                         "using the default value: " + def);
134 
135         return def;
136     }
137 
138     private static final Pattern INTEGER_PATTERN = Pattern.compile("-?[0-9]+");
139 
140     /**
141      * Returns the value of the Java system property with the specified
142      * {@code key}, while falling back to the specified default value if
143      * the property access fails.
144      *
145      * @return the property value.
146      *         {@code def} if there's no such property or if an access to the
147      *         specified property is not allowed.
148      */
149     public static int getInt(String key, int def) {
150         String value = get(key);
151         if (value == null) {
152             return def;
153         }
154 
155         value = value.trim().toLowerCase();
156         if (INTEGER_PATTERN.matcher(value).matches()) {
157             try {
158                 return Integer.parseInt(value);
159             } catch (Exception e) {
160                 // Ignore
161             }
162         }
163 
164         log(
165                 "Unable to parse the integer system property '" + key + "':" + value + " - " +
166                         "using the default value: " + def);
167 
168         return def;
169     }
170 
171     /**
172      * Returns the value of the Java system property with the specified
173      * {@code key}, while falling back to the specified default value if
174      * the property access fails.
175      *
176      * @return the property value.
177      *         {@code def} if there's no such property or if an access to the
178      *         specified property is not allowed.
179      */
180     public static long getLong(String key, long def) {
181         String value = get(key);
182         if (value == null) {
183             return def;
184         }
185 
186         value = value.trim().toLowerCase();
187         if (INTEGER_PATTERN.matcher(value).matches()) {
188             try {
189                 return Long.parseLong(value);
190             } catch (Exception e) {
191                 // Ignore
192             }
193         }
194 
195         log(
196                 "Unable to parse the long integer system property '" + key + "':" + value + " - " +
197                         "using the default value: " + def);
198 
199         return def;
200     }
201 
202     private static void log(String msg) {
203         if (initializedLogger) {
204             logger.warn(msg);
205         } else {
206             // Use JDK logging if logger was not initialized yet.
207             Logger.getLogger(SystemPropertyUtil.class.getName()).log(Level.WARNING, msg);
208         }
209     }
210 
211     private static void log(String msg, Exception e) {
212         if (initializedLogger) {
213             logger.warn(msg, e);
214         } else {
215             // Use JDK logging if logger was not initialized yet.
216             Logger.getLogger(SystemPropertyUtil.class.getName()).log(Level.WARNING, msg, e);
217         }
218     }
219 
220     private SystemPropertyUtil() {
221         // Unused
222     }
223 }