<commit_before>package io.domisum.lib.auxiliumlib.util.java;

import io.domisum.lib.auxiliumlib.annotations.API;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@API
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ExceptionUtil
{
	
	@API
	public static String convertToString(Throwable throwable)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(throwable.toString()).append("\n");
		
		for(StackTraceElement stackTraceElement : throwable.getStackTrace())
			stringBuilder.append("    ").append(stackTraceElement.toString()).append("\n");
		
		if(throwable.getCause() != null)
			stringBuilder.append("Caused by: ").append(convertToString(throwable.getCause()));
		
		return stringBuilder.toString();
	}
	
	@API
	public static boolean doesContain(Throwable throwable, Class<? extends Throwable> type)
	{
		if(throwable == null)
			return false;
		
		if(type.isAssignableFrom(throwable.getClass()))
			return true;
		
		return doesContain(throwable.getCause(), type);
	}
	
	@API
	public static String getSynopsis(Throwable throwable)
	{
		String causeSynopsis = throwable.getCause() == null ? null : getSynopsis(throwable.getCause());
		String synopsis = throwable.getClass().getSimpleName()+": "+throwable.getMessage();
		if(causeSynopsis != null)
			synopsis += "; caused by: ("+causeSynopsis+")";
		<commit_msg>Added ExceptionUtil#getContained method<commit_after>package io.domisum.lib.auxiliumlib.util.java;

import io.domisum.lib.auxiliumlib.annotations.API;
import io.domisum.lib.auxiliumlib.util.ValidationUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.util.Optional;

@API
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ExceptionUtil
{
	
	// CONTAINS
	@API
	@SuppressWarnings("unchecked")
	public static <T extends Throwable> Optional<T> getContained(Throwable throwable, Class<T> type)
	{
		ValidationUtil.notNull(throwable, "throwable");
		
		if(type.equals(throwable.getClass()))
			return Optional.of((T) throwable);
		
		var cause = throwable.getCause();
		if(cause == null)
			return Optional.empty();
		
		return getContained(cause, type);
	}
	
	@API
	public static boolean doesContain(Throwable throwable, Class<? extends Throwable> type)
	{
		return getContained(throwable, type).isPresent();
	}
	
	
	// TO STRING
	@API
	public static String convertToString(Throwable throwable)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(throwable.toString()).append("\n");
		
		for(StackTraceElement stackTraceElement : throwable.getStackTrace())
			stringBuilder.append("    ").append(stackTraceElement.toString()).append("\n");
		
		if(throwable.getCause() != null)
			stringBuilder.append("Caused by: ").append(convertToString(throwable.getCause()));
		
		return stringBuilder.toString();
	}
	
	@API
	public static String getSynopsis(Throwable throwable)
	{
		String causeSynopsis = throwable.getCause() == null ? null : getSynopsis(throwable.getCause());
		String synopsis = throwable.getClass().getSimpleName()+": "+throwable.getMessage();
		if(causeSynopsis != null)
			synopsis += "; caused by: ("+causeSynopsis+")";
		
{'fraction_non_alphanumeric': 0.129874213836478, 'fraction_numerical': 0.0, 'mean_word_length': 5.439271255060729, 'pattern_counts': {'":': 2, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5662189', 'n_tokens_mistral': 1065, 'n_tokens_neox': 956, 'n_words': 190}