/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.depgraph; import java.util.Map; import org.apache.commons.lang.ObjectUtils; /** * Wraps an exception thrown by the graph building (e.g. from a function) in a way that allows them to be collated. * <p> * Exception equality is defined based on the top frame of the stack trace, message and the wrapped cause of the exception. */ /* package */final class ExceptionWrapper { private final Throwable _exception; private final String _message; private final StackTraceElement _topStackFrame; private final ExceptionWrapper _cause; private int _count; private ExceptionWrapper(final Throwable exception, final ExceptionWrapper cause) { _exception = exception; _message = exception.getMessage(); final StackTraceElement[] trace = exception.getStackTrace(); if (trace.length > 0) { _topStackFrame = trace[0]; } else { _topStackFrame = null; } _cause = cause; _count = 1; } /** * Create a new wrapper instance and add it to the canonical map. * * @param exception exception to wrap * @param canon the canonical map to add to */ public static ExceptionWrapper createAndPut(final Throwable exception, final Map<ExceptionWrapper, ExceptionWrapper> canon) { final ExceptionWrapper instance; final Throwable cause = exception.getCause(); if (cause != null) { instance = new ExceptionWrapper(exception, createAndPut(cause, canon)); } else { instance = new ExceptionWrapper(exception, null); } final ExceptionWrapper existing = canon.get(instance); if (existing != null) { existing.incrementCount(); return existing; } else { canon.put(instance, instance); return instance; } } public Throwable getException() { return _exception; } public int getCount() { return _count; } public void incrementCount() { _count++; } public void incrementCount(final int amount) { _count += amount; } @Override public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof ExceptionWrapper)) { return false; } final ExceptionWrapper other = (ExceptionWrapper) o; return ObjectUtils.equals(other._message, _message) && ObjectUtils.equals(other._topStackFrame, _topStackFrame) && ObjectUtils.equals(other._cause, _cause); } @Override public int hashCode() { return (ObjectUtils.hashCode(_message) * 17 + ObjectUtils.hashCode(_topStackFrame)) * 17 + ObjectUtils.hashCode(_cause); } }