All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.management.internal.cli.util.CauseFinder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You
 * may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.management.internal.cli.util;

/**
 * Helper class to navigate through the nested causes of an exception. 
 * Provides method to
 * 
    *
  • find index of an Exception of a specific type *
  • find Root Cause of the Exception *
  • retrieve a nested cause at a specific index/depth *
  • find a cause by specific type *
* * @author Abhishek Chaudhari * @since 7.0 */ public class CauseFinder { private static final int START_INDEX = 0; /** * Returns the index of a first nested cause which is of the given Throwable * type or its sub-type depending on isSubtypeOk value.

* NOTE: It looks for the "nested" causes & doesn't try to match the * causeClass of the parent.

* * Returns -1 if a cause with the given Throwable type is not found. * * @param parent * parent Throwable instance * @param causeClass * type of the nested Throwable cause * @param isSubtypeOk * whether any matching sub-type is required or exact match is * required * @return index/depth of the cause starting from the 'top most' Throwable in * the stack. -1 if can't find it. */ public static int indexOfCause(Throwable parent, Class causeClass, final boolean isSubtypeOk) { return indexOfCause(parent, causeClass, START_INDEX, isSubtypeOk); } /** * Returns the index of a first nested cause which is of the given Throwable * type or its sub-type depending on isSubtypeOk value.

* NOTE: It looks for the "nested" causes & doesn't try to match the * causeClass of the parent.

* * Returns -1 if a cause with the given Throwable type is not found. * * @param parent * parent Throwable instance * @param causeClass * type of the nested Throwable cause * @param cindex * variable to store current index/depth of the cause * @param isSubtypeOk * whether any matching sub-type is required or exact match is * required * @return index/depth of the cause starting from the 'top most' Throwable * in the stack. -1 if can't find it. */ private static int indexOfCause(Throwable parent, Class causeClass, final int cindex, final boolean isSubtypeOk) { int resultIndex = cindex; Throwable cause = parent.getCause(); //(cause is not null & cause is not of type causeClass) if (cause != null && !isMatching(cause, causeClass, isSubtypeOk)) { //recurse deeper resultIndex = indexOfCause(cause, causeClass, cindex + 1, isSubtypeOk); } else if (cause != null && isMatching(cause, causeClass, isSubtypeOk)) { resultIndex = cindex != -1 ? cindex + 1 : cindex; } else if (cause == null) { resultIndex = -1; } return resultIndex; } /** * Returns whether the given cause is assignable or has same * type as that of causeClass depending on * isSubtypeOk value. * * @param cause * parent Throwable instance * @param causeClass * type of the nested Throwable cause * @param isSubtypeOk * whether any matching sub-type is required or exact match is * required * @return true if cause is assignable or has same type as that * of causeClass. false otherwise */ //Note: No not null check on 'Throwable cause' - currently called after null check private static boolean isMatching(Throwable cause, Class causeClass, final boolean isSubtypeOk) { return isSubtypeOk ? causeClass.isInstance(cause) : causeClass == cause.getClass(); } /** * Returns nested 'root' cause of the given parent Throwable. Will return the * same Throwable if it has no 'cause'. * * @param parent * Throwable whose root cause is to be found * @return nested root cause. * @throws IllegalArgumentException * when parent is null */ public static Throwable getRootCause(Throwable parent) { return getRootCause(parent, 0); } /** * Returns nested 'root' cause of the given parent Throwable. Will return the * same Throwable if it has no 'cause'. If depth is 0, does a * null check on the given parent Throwable & if * parent is null, throws * {@link IllegalArgumentException}. * * @param parent * Throwable whose root cause is to be found * @param depth * recurse depth indicator * @return nested root cause. * @throws IllegalArgumentException * when parent is null at depth = 0 */ //Note: private method private static Throwable getRootCause(Throwable parent, int depth) { if (depth == 0) { if (parent == null) { throw new IllegalArgumentException("Given parent Throwable is null."); } } Throwable theCause = parent.getCause(); if (theCause != null) { //recurse deeper return getRootCause(theCause, depth + 1); } return parent; } /** * Returns cause at the specified depth/index starting from the 'top most' * Throwable parent in the stack. Returns null if * it can't find it. * * @param parent * Throwable to use to find the cause at given index/depth * @param requiredIndex * index/depth of nesting the cause * @return cause at the specified index starting from the 'top most' * Throwable in the stack. null if it can't find it. */ public static Throwable causeAt(Throwable parent, final int requiredIndex) { // // TODO: // NEED TO CHECK WHETHER RIGHT PARENT CAUSE RETRUNED // if (parent != null && requiredIndex > 0) { //recurse deeper return causeAt(parent.getCause(), requiredIndex - 1); } //when there isn't required depth if (requiredIndex > 0) { return null; } return parent; } /** * Returns the first occurrence of nested cause of parent which * matches the specified causeType or its sub-type depending on * isSubtypeOk value. * * @param parent * Throwable to use to find the cause of given type * @param causeType * type of the nested Throwable cause * @param isSubtypeOk * whether any matching sub-type is required or exact match is * required * @return the first occurrence of nested cause which matches the specified * causeType or its sub-type. null if it * can't find it. */ public static Throwable causeByType(Throwable parent, Class causeType, boolean isSubtypeOk) { Throwable cause = null; int foundAtIndex = indexOfCause(parent, causeType, isSubtypeOk); if (foundAtIndex != -1) { cause = causeAt(parent, foundAtIndex); } return cause; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy