View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the 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
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   *
17   */
18  
19  package org.apache.commons.dbcp2;
20  
21  import java.sql.Connection;
22  import java.sql.ResultSet;
23  import java.sql.Statement;
24  import java.text.MessageFormat;
25  import java.util.HashSet;
26  import java.util.Properties;
27  import java.util.ResourceBundle;
28  import java.util.Set;
29  
30  /**
31   * Utility methods.
32   *
33   * @since 2.0
34   */
35  public final class Utils {
36  
37      private static final ResourceBundle messages = ResourceBundle
38          .getBundle(Utils.class.getPackage().getName() + ".LocalStrings");
39  
40      /**
41       * Whether the security manager is enabled.
42       * 
43       * @deprecated No replacement.
44       */
45      @Deprecated
46      public static final boolean IS_SECURITY_ENABLED = isSecurityEnabled();
47  
48      /** Any SQL_STATE starting with this value is considered a fatal disconnect */
49      public static final String DISCONNECTION_SQL_CODE_PREFIX = "08";
50  
51      /**
52       * SQL codes of fatal connection errors.
53       * <ul>
54       * <li>57P01 (Admin shutdown)</li>
55       * <li>57P02 (Crash shutdown)</li>
56       * <li>57P03 (Cannot connect now)</li>
57       * <li>01002 (SQL92 disconnect error)</li>
58       * <li>JZ0C0 (Sybase disconnect error)</li>
59       * <li>JZ0C1 (Sybase disconnect error)</li>
60       * </ul>
61       */
62      public static final Set<String> DISCONNECTION_SQL_CODES;
63  
64      static final ResultSet[] EMPTY_RESULT_SET_ARRAY = {};
65  
66      static final String[] EMPTY_STRING_ARRAY = {};
67      static {
68          DISCONNECTION_SQL_CODES = new HashSet<>();
69          DISCONNECTION_SQL_CODES.add("57P01"); // Admin shutdown
70          DISCONNECTION_SQL_CODES.add("57P02"); // Crash shutdown
71          DISCONNECTION_SQL_CODES.add("57P03"); // Cannot connect now
72          DISCONNECTION_SQL_CODES.add("01002"); // SQL92 disconnect error
73          DISCONNECTION_SQL_CODES.add("JZ0C0"); // Sybase disconnect error
74          DISCONNECTION_SQL_CODES.add("JZ0C1"); // Sybase disconnect error
75      }
76  
77      /**
78       * Clones the given char[] if not null.
79       *
80       * @param value may be null.
81       * @return a cloned char[] or null.
82       */
83      public static char[] clone(final char[] value) {
84          return value == null ? null : value.clone();
85      }
86  
87      /**
88       * Clones the given {@link Properties} without the standard "user" or "password" entries.
89       *
90       * @param properties may be null
91       * @return a clone of the input without the standard "user" or "password" entries.
92       * @since 2.8.0
93       */
94      public static Properties cloneWithoutCredentials(final Properties properties) {
95          if (properties != null) {
96              final Properties temp = (Properties) properties.clone();
97              temp.remove(Constants.KEY_USER);
98              temp.remove(Constants.KEY_PASSWORD);
99              return temp;
100         }
101         return properties;
102     }
103 
104     /**
105      * Closes the AutoCloseable (which may be null).
106      *
107      * @param autoCloseable an AutoCloseable, may be {@code null}
108      * @since 2.6.0
109      */
110     public static void closeQuietly(final AutoCloseable autoCloseable) {
111         if (autoCloseable != null) {
112             try {
113                 autoCloseable.close();
114             } catch (final Exception e) {
115                 // ignored
116             }
117         }
118     }
119 
120     /**
121      * Closes the Connection (which may be null).
122      *
123      * @param connection a Connection, may be {@code null}
124      * @deprecated Use {@link #closeQuietly(AutoCloseable)}.
125      */
126     @Deprecated
127     public static void closeQuietly(final Connection connection) {
128         if (connection != null) {
129             try {
130                 connection.close();
131             } catch (final Exception e) {
132                 // ignored
133             }
134         }
135     }
136 
137     /**
138      * Closes the ResultSet (which may be null).
139      *
140      * @param resultSet a ResultSet, may be {@code null}
141      * @deprecated Use {@link #closeQuietly(AutoCloseable)}.
142      */
143     @Deprecated
144     public static void closeQuietly(final ResultSet resultSet) {
145         if (resultSet != null) {
146             try {
147                 resultSet.close();
148             } catch (final Exception e) {
149                 // ignored
150             }
151         }
152     }
153 
154     /**
155      * Closes the Statement (which may be null).
156      *
157      * @param statement a Statement, may be {@code null}.
158      * @deprecated Use {@link #closeQuietly(AutoCloseable)}.
159      */
160     @Deprecated
161     public static void closeQuietly(final Statement statement) {
162         if (statement != null) {
163             try {
164                 statement.close();
165             } catch (final Exception e) {
166                 // ignored
167             }
168         }
169     }
170 
171     /**
172      * Gets the correct i18n message for the given key.
173      *
174      * @param key The key to look up an i18n message.
175      * @return The i18n message.
176      */
177     public static String getMessage(final String key) {
178         return getMessage(key, (Object[]) null);
179     }
180 
181     /**
182      * Gets the correct i18n message for the given key with placeholders replaced by the supplied arguments.
183      *
184      * @param key A message key.
185      * @param args The message arguments.
186      * @return An i18n message.
187      */
188     public static String getMessage(final String key, final Object... args) {
189         final String msg = messages.getString(key);
190         if (args == null || args.length == 0) {
191             return msg;
192         }
193         final MessageFormat mf = new MessageFormat(msg);
194         return mf.format(args, new StringBuffer(), null).toString();
195     }
196 
197     static boolean isSecurityEnabled() {
198         return System.getSecurityManager() != null;
199     }
200 
201     /**
202      * Converts the given String to a char[].
203      *
204      * @param value may be null.
205      * @return a char[] or null.
206      */
207     public static char[] toCharArray(final String value) {
208         return value != null ? value.toCharArray() : null;
209     }
210 
211     /**
212      * Converts the given char[] to a String.
213      *
214      * @param value may be null.
215      * @return a String or null.
216      */
217     public static String toString(final char[] value) {
218         return value == null ? null : String.valueOf(value);
219     }
220 
221     private Utils() {
222         // not instantiable
223     }
224 
225 }