    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 *      https://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 */
    017package org.apache.commons.pool2.impl;
    018
    019import java.security.AccessControlException;
    020
    021/**
    022 * Utility methods for {@link CallStack}.
    023 *
    024 * @since 2.4.3
    025 */
    026public final class CallStackUtils {
    027
    028    /**
    029     * Tests whether the caller can create a security manager in the current environment.
    030     *
    031     * @return {@code true} if it is able to create a security manager in the current environment, {@code false}
    032     *         otherwise.
    033     */
    034    private static boolean canCreateSecurityManager() {
    035        final SecurityManager manager = System.getSecurityManager();
    036        if (manager == null) {
    037            return true;
    038        }
    039        try {
    040            manager.checkPermission(new RuntimePermission("createSecurityManager"));
    041            return true;
    042        } catch (final AccessControlException ignored) {
    043            return false;
    044        }
    045    }
    046
    047    /**
    048     * Constructs a new {@link CallStack} using the fastest allowed strategy.
    049     *
    050     * @param messageFormat message (or format) to print first in stack traces
    051     * @param useTimestamp  if true, interpret message as a SimpleDateFormat and print the created timestamp; otherwise,
    052     *                      print message format literally
    053     * @return a new CallStack
    054     * @deprecated Use {@link #newCallStack(String, boolean, boolean)}
    055     */
    056    @Deprecated
    057    public static CallStack newCallStack(final String messageFormat, final boolean useTimestamp) {
    058        return newCallStack(messageFormat, useTimestamp, false);
    059    }
    060
    061    /**
    062     * Constructs a new {@link CallStack} using the fasted allowed strategy.
    063     *
    064     * @param messageFormat         message (or format) to print first in stack traces
    065     * @param useTimestamp          if true, interpret message as a SimpleDateFormat and print the created timestamp;
    066     *                              otherwise, print message format literally
    067     * @param requireFullStackTrace if true, forces the use of a stack walking mechanism that includes full stack trace
    068     *                              information; otherwise, uses a faster implementation if possible
    069     * @return a new CallStack
    070     * @since 2.5
    071     */
    072    public static CallStack newCallStack(final String messageFormat,
    073                                         final boolean useTimestamp,
    074                                         final boolean requireFullStackTrace) {
    075        return canCreateSecurityManager() && !requireFullStackTrace ?
    076            new SecurityManagerCallStack(messageFormat, useTimestamp) :
    077            new ThrowableCallStack(messageFormat, useTimestamp);
    078    }
    079
    080    /**
    081     * Hidden constructor.
    082     */
    083    private CallStackUtils() {
    084    }
    085}