diff options
Diffstat (limited to 'src/main/java/org/apache/commons/lang3/exception/DefaultExceptionContext.java')
-rw-r--r-- | src/main/java/org/apache/commons/lang3/exception/DefaultExceptionContext.java | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/lang3/exception/DefaultExceptionContext.java b/src/main/java/org/apache/commons/lang3/exception/DefaultExceptionContext.java new file mode 100644 index 000000000..51bde8b50 --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/exception/DefaultExceptionContext.java @@ -0,0 +1,149 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.commons.lang3.exception; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +/** + * Default implementation of the context storing the label-value pairs for contexted exceptions. + * <p> + * This implementation is serializable, however this is dependent on the values that + * are added also being serializable. + * </p> + * + * @see ContextedException + * @see ContextedRuntimeException + * @since 3.0 + */ +public class DefaultExceptionContext implements ExceptionContext, Serializable { + + /** The serialization version. */ + private static final long serialVersionUID = 20110706L; + + /** The list storing the label-data pairs. */ + private final List<Pair<String, Object>> contextValues = new ArrayList<>(); + + /** + * {@inheritDoc} + */ + @Override + public DefaultExceptionContext addContextValue(final String label, final Object value) { + contextValues.add(new ImmutablePair<>(label, value)); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Pair<String, Object>> getContextEntries() { + return contextValues; + } + + /** + * {@inheritDoc} + */ + @Override + public Set<String> getContextLabels() { + return stream().map(Pair::getKey).collect(Collectors.toSet()); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Object> getContextValues(final String label) { + return stream().filter(pair -> StringUtils.equals(label, pair.getKey())).map(Pair::getValue).collect(Collectors.toList()); + } + + /** + * {@inheritDoc} + */ + @Override + public Object getFirstContextValue(final String label) { + return stream().filter(pair -> StringUtils.equals(label, pair.getKey())).findFirst().map(Pair::getValue).orElse(null); + } + + /** + * Builds the message containing the contextual information. + * + * @param baseMessage the base exception message <b>without</b> context information appended + * @return the exception message <b>with</b> context information appended, never null + */ + @Override + public String getFormattedExceptionMessage(final String baseMessage) { + final StringBuilder buffer = new StringBuilder(256); + if (baseMessage != null) { + buffer.append(baseMessage); + } + + if (!contextValues.isEmpty()) { + if (buffer.length() > 0) { + buffer.append('\n'); + } + buffer.append("Exception Context:\n"); + + int i = 0; + for (final Pair<String, Object> pair : contextValues) { + buffer.append("\t["); + buffer.append(++i); + buffer.append(':'); + buffer.append(pair.getKey()); + buffer.append("="); + final Object value = pair.getValue(); + if (value == null) { + buffer.append("null"); + } else { + String valueStr; + try { + valueStr = value.toString(); + } catch (final Exception e) { + valueStr = "Exception thrown on toString(): " + ExceptionUtils.getStackTrace(e); + } + buffer.append(valueStr); + } + buffer.append("]\n"); + } + buffer.append("---------------------------------"); + } + return buffer.toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public DefaultExceptionContext setContextValue(final String label, final Object value) { + contextValues.removeIf(p -> StringUtils.equals(label, p.getKey())); + addContextValue(label, value); + return this; + } + + private Stream<Pair<String, Object>> stream() { + return contextValues.stream(); + } + +} |