Add CompositeAppender.compose(:Appender[]) and CompositeAppender.compose(:Iterable<Appender>) methods to compose an array or Iterable of Appenders.

Resolves gh-73.
This commit is contained in:
John Blum
2020-02-19 19:12:18 -08:00
parent 7fe4c41fc9
commit f5918498c9
2 changed files with 125 additions and 0 deletions

View File

@@ -15,6 +15,10 @@
*/
package org.springframework.geode.logging.slf4j.logback;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Context;
@@ -54,6 +58,52 @@ public class CompositeAppender<T> extends AppenderBase<T> {
return one == null ? two : two == null ? one : new CompositeAppender<>(one, two);
}
/**
* Composes an array of {@link Appender Appenders} into a {@link CompositeAppender}.
*
* This operation is null-safe.
*
* @param <T> {@link Class type} of the logging events processed by the {@link Appender Appenders}.
* @param appenders array of {@link Appender Appenders} to compose; may be {@literal null}.
* @return a composition of the array of {@link Appender Appenders}; returns {@literal null} if the array is empty.
* @see #compose(Iterable)
*/
@SuppressWarnings("unchecked")
public static <T> Appender<T> compose(Appender<T>... appenders) {
List<Appender<T>> resolvedAppenders = appenders != null
? Arrays.asList(appenders)
: Collections.emptyList();
return compose(resolvedAppenders);
}
/**
* Composes the {@link Iterable} of {@link Appender Appenders} into a {@link CompositeAppender}.
*
* This operation is null-safe.
*
* @param <T> {@link Class type} of the logging events processed by the {@link Appender Appenders}.
* @param appenders {@link Iterable} of {@link Appender Appenders} to compose; may be {@literal null}.
* @return a composition of the {@link Iterable} of {@link Appender Appenders}; returns {@literal null}
* if the {@link Iterable} is {@literal null} or empty.
* @see #compose(Appender, Appender)
* @see java.lang.Iterable
*/
public static <T> Appender<T> compose(Iterable<Appender<T>> appenders) {
Appender<T> currentAppender = null;
appenders = appenders != null ? appenders : Collections::emptyIterator;
for (Appender<T> appender : appenders) {
currentAppender = compose(currentAppender, appender);
}
return currentAppender;
}
/**
* Constructs a new instance of {@link CompositeAppender} composed of {@link Appender} one and {@link Appender} two.
*

View File

@@ -23,6 +23,9 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.Arrays;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -77,6 +80,78 @@ public class CompositeAppenderUnitTests {
assertThat(composite.isStarted()).isTrue();
}
@Test
public void composeAppenderArray() {
Appender mockAppenderOne = mock(Appender.class);
Appender mockAppenderTwo = mock(Appender.class);
Appender mockAppenderThree = mock(Appender.class);
Appender composite = CompositeAppender.compose(mockAppenderOne, mockAppenderTwo, mockAppenderThree);
assertThat(composite).isInstanceOf(CompositeAppender.class);
Appender appenderOne = ((CompositeAppender) composite).getAppenderOne();
Appender appenderTwo = ((CompositeAppender) composite).getAppenderTwo();
assertThat(appenderOne).isInstanceOf(CompositeAppender.class);
assertThat(appenderTwo).isEqualTo(mockAppenderThree);
assertThat(((CompositeAppender) appenderOne).getAppenderOne()).isEqualTo(mockAppenderOne);
assertThat(((CompositeAppender) appenderOne).getAppenderTwo()).isEqualTo(mockAppenderTwo);
}
@Test
public void composeAppenderArrayWithOneAppender() {
assertThat(CompositeAppender.compose(this.mockAppenderOne)).isSameAs(this.mockAppenderOne);
}
@Test
public void composeAppenderArrayWithZeroAppenders() {
assertThat(CompositeAppender.compose()).isNull();
}
@Test
public void composeAppenderArrayIsNullSafe() {
assertThat(CompositeAppender.compose((Appender[]) null)).isNull();
}
@Test
public void composeAppenderIterable() {
Appender mockAppenderOne = mock(Appender.class);
Appender mockAppenderTwo = mock(Appender.class);
Appender mockAppenderThree = mock(Appender.class);
Appender composite =
CompositeAppender.compose(Arrays.asList(mockAppenderOne, mockAppenderTwo, mockAppenderThree));
assertThat(composite).isInstanceOf(CompositeAppender.class);
Appender appenderOne = ((CompositeAppender) composite).getAppenderOne();
Appender appenderTwo = ((CompositeAppender) composite).getAppenderTwo();
assertThat(appenderOne).isInstanceOf(CompositeAppender.class);
assertThat(appenderTwo).isEqualTo(mockAppenderThree);
assertThat(((CompositeAppender) appenderOne).getAppenderOne()).isEqualTo(mockAppenderOne);
assertThat(((CompositeAppender) appenderOne).getAppenderTwo()).isEqualTo(mockAppenderTwo);
}
@Test
public void composeAppenderIterableWithOneAppender() {
assertThat(CompositeAppender.compose(Collections.singletonList(this.mockAppenderTwo)))
.isSameAs(this.mockAppenderTwo);
}
@Test
public void composeAppenderIterableWithZeroAppenders() {
assertThat(CompositeAppender.compose(Collections.emptyList())).isNull();
}
@Test
public void composeAppenderIterableIsNullSafe() {
assertThat(CompositeAppender.compose((Iterable<Appender<Object>>) null)).isNull();
}
@Test
public void setContextConfiguresContextOnCompositeAppenderAndComposedAppenders() {