    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *   http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 *
    017 */
    018
    019package org.apache.commons.dbcp2;
    020
    021import java.sql.Connection;
    022import java.sql.ResultSet;
    023import java.sql.Statement;
    024import java.text.MessageFormat;
    025import java.util.HashSet;
    026import java.util.ResourceBundle;
    027import java.util.Set;
    028
    029/**
    030 * Utility methods.
    031 *
    032 * @since 2.0
    033 */
    034public final class Utils {
    035
    036    private static final ResourceBundle messages = ResourceBundle
    037            .getBundle(Utils.class.getPackage().getName() + ".LocalStrings");
    038
    039    /**
    040     * Whether the security manager is enabled.
    041     */
    042    public static final boolean IS_SECURITY_ENABLED = System.getSecurityManager() != null;
    043
    044    /** Any SQL_STATE starting with this value is considered a fatal disconnect */
    045    public static final String DISCONNECTION_SQL_CODE_PREFIX = "08";
    046
    047    /**
    048     * SQL codes of fatal connection errors.
    049     * <ul>
    050     * <li>57P01 (Admin shutdown)</li>
    051     * <li>57P02 (Crash shutdown)</li>
    052     * <li>57P03 (Cannot connect now)</li>
    053     * <li>01002 (SQL92 disconnect error)</li>
    054     * <li>JZ0C0 (Sybase disconnect error)</li>
    055     * <li>JZ0C1 (Sybase disconnect error)</li>
    056     * </ul>
    057     */
    058    public static final Set<String> DISCONNECTION_SQL_CODES;
    059
    060    static {
    061        DISCONNECTION_SQL_CODES = new HashSet<>();
    062        DISCONNECTION_SQL_CODES.add("57P01"); // Admin shutdown
    063        DISCONNECTION_SQL_CODES.add("57P02"); // Crash shutdown
    064        DISCONNECTION_SQL_CODES.add("57P03"); // Cannot connect now
    065        DISCONNECTION_SQL_CODES.add("01002"); // SQL92 disconnect error
    066        DISCONNECTION_SQL_CODES.add("JZ0C0"); // Sybase disconnect error
    067        DISCONNECTION_SQL_CODES.add("JZ0C1"); // Sybase disconnect error
    068    }
    069
    070    /**
    071     * Clones the given char[] if not null.
    072     *
    073     * @param value
    074     *            may be null.
    075     * @return a cloned char[] or null.
    076     */
    077    public static char[] clone(final char[] value) {
    078        return value == null ? null : value.clone();
    079    }
    080
    081    /**
    082     * Closes the AutoCloseable (which may be null).
    083     *
    084     * @param autoCloseable
    085     *            an AutoCloseable, may be {@code null}
    086     * @since 2.6.0
    087     */
    088    public static void closeQuietly(final AutoCloseable autoCloseable) {
    089        if (autoCloseable != null) {
    090            try {
    091                autoCloseable.close();
    092            } catch (final Exception e) {
    093                // ignored
    094            }
    095        }
    096    }
    097
    098    /**
    099     * Closes the Connection (which may be null).
    100     *
    101     * @param connection
    102     *            a Connection, may be {@code null}
    103     * @deprecated Use {@link #closeQuietly(AutoCloseable)}.
    104     */
    105    @Deprecated
    106    public static void closeQuietly(final Connection connection) {
    107        if (connection != null) {
    108            try {
    109                connection.close();
    110            } catch (final Exception e) {
    111                // ignored
    112            }
    113        }
    114    }
    115
    116    /**
    117     * Closes the ResultSet (which may be null).
    118     *
    119     * @param resultSet
    120     *            a ResultSet, may be {@code null}
    121     * @deprecated Use {@link #closeQuietly(AutoCloseable)}.
    122     */
    123    @Deprecated
    124    public static void closeQuietly(final ResultSet resultSet) {
    125        if (resultSet != null) {
    126            try {
    127                resultSet.close();
    128            } catch (final Exception e) {
    129                // ignored
    130            }
    131        }
    132    }
    133
    134    /**
    135     * Closes the Statement (which may be null).
    136     *
    137     * @param statement
    138     *            a Statement, may be {@code null}.
    139     * @deprecated Use {@link #closeQuietly(AutoCloseable)}.
    140     */
    141    @Deprecated
    142    public static void closeQuietly(final Statement statement) {
    143        if (statement != null) {
    144            try {
    145                statement.close();
    146            } catch (final Exception e) {
    147                // ignored
    148            }
    149        }
    150    }
    151
    152    /**
    153     * Gets the correct i18n message for the given key.
    154     *
    155     * @param key
    156     *            The key to look up an i18n message.
    157     * @return The i18n message.
    158     */
    159    public static String getMessage(final String key) {
    160        return getMessage(key, (Object[]) null);
    161    }
    162
    163    /**
    164     * Gets the correct i18n message for the given key with placeholders replaced by the supplied arguments.
    165     *
    166     * @param key
    167     *            A message key.
    168     * @param args
    169     *            The message arguments.
    170     * @return An i18n message.
    171     */
    172    public static String getMessage(final String key, final Object... args) {
    173        final String msg = messages.getString(key);
    174        if (args == null || args.length == 0) {
    175            return msg;
    176        }
    177        final MessageFormat mf = new MessageFormat(msg);
    178        return mf.format(args, new StringBuffer(), null).toString();
    179    }
    180
    181    /**
    182     * Converts the given String to a char[].
    183     *
    184     * @param value
    185     *            may be null.
    186     * @return a char[] or null.
    187     */
    188    public static char[] toCharArray(final String value) {
    189        return value != null ? value.toCharArray() : null;
    190    }
    191
    192    /**
    193     * Converts the given char[] to a String.
    194     *
    195     * @param value
    196     *            may be null.
    197     * @return a String or null.
    198     */
    199    public static String toString(final char[] value) {
    200        return value == null ? null : String.valueOf(value);
    201    }
    202
    203    private Utils() {
    204        // not instantiable
    205    }
    206
    207}