diff --git a/api/src/main/java/com/google/common/flogger/backend/LogSiteFormatter.java b/api/src/main/java/com/google/common/flogger/backend/LogSiteFormatter.java new file mode 100644 index 0000000..673e7a9 --- /dev/null +++ b/api/src/main/java/com/google/common/flogger/backend/LogSiteFormatter.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 The Flogger Authors. + * + * 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. + */ + +package com.google.common.flogger.backend; + +import com.google.common.flogger.LogSite; +import com.google.errorprone.annotations.CanIgnoreReturnValue; + +/** Interface for custom LogSite formatting. */ +public interface LogSiteFormatter { + + /** + * Appends log site information to a buffer. + * + * @param logSite the log site to be appended (ignored if {@link LogSite#INVALID}). + * @param out the destination buffer. + * @return whether the logSite was appended. + */ + @CanIgnoreReturnValue + boolean appendLogSite(LogSite logSite, StringBuilder out); +} diff --git a/api/src/main/java/com/google/common/flogger/backend/LogSiteFormatters.java b/api/src/main/java/com/google/common/flogger/backend/LogSiteFormatters.java new file mode 100644 index 0000000..f99f8b6 --- /dev/null +++ b/api/src/main/java/com/google/common/flogger/backend/LogSiteFormatters.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 The Flogger Authors. + * + * 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. + */ + +package com.google.common.flogger.backend; + +import com.google.common.flogger.LogSite; + +/** Sample LogSiteFormatter implementations. */ +public enum LogSiteFormatters implements LogSiteFormatter { + DEFAULT { + /** Appends logsite information in the default format, .: */ + @Override + public boolean appendLogSite(LogSite logSite, StringBuilder out) { + if (logSite == LogSite.INVALID) { + return false; + } + out.append(logSite.getClassName()) + .append('.') + .append(logSite.getMethodName()) + .append(':') + .append(logSite.getLineNumber()); + return true; + } + }, + NO_OP { + /** Does not append logsite information. */ + @Override + public boolean appendLogSite(LogSite logSite, StringBuilder out) { + return false; + } + }, + SIMPLE_CLASSNAME { + /** + * Appends logsite information using the unqualified class name, + * .: + * + *

The unqualified class name is all text after the last period. A class name with no + * separators or a trailing separator will be appended in full. + */ + @Override + public boolean appendLogSite(LogSite logSite, StringBuilder out) { + if (logSite == LogSite.INVALID) { + return false; + } + String qualifiedClassName = logSite.getClassName(); + int lastDotIndex = qualifiedClassName.lastIndexOf('.'); + if (lastDotIndex == -1 || lastDotIndex + 1 >= qualifiedClassName.length()) { + out.append(qualifiedClassName); + } else { + out.append(qualifiedClassName, lastDotIndex + 1, qualifiedClassName.length()); + } + out.append('.').append(logSite.getMethodName()).append(':').append(logSite.getLineNumber()); + return true; + } + } +} diff --git a/api/src/main/java/com/google/common/flogger/backend/MessageUtils.java b/api/src/main/java/com/google/common/flogger/backend/MessageUtils.java index 31679b9..a37a911 100644 --- a/api/src/main/java/com/google/common/flogger/backend/MessageUtils.java +++ b/api/src/main/java/com/google/common/flogger/backend/MessageUtils.java @@ -47,23 +47,15 @@ private MessageUtils() {} static final Locale FORMAT_LOCALE = Locale.ROOT; /** - * Appends log-site information in the default format, including a trailing space. + * Appends log-site information in the default format. * - * @param logSite the log site to be appended (ingored if {@link LogSite#INVALID}). + * @param logSite the log site to be appended (ignored if {@link LogSite#INVALID}). * @param out the destination buffer. * @return whether the log-site was appended. */ @CanIgnoreReturnValue public static boolean appendLogSite(LogSite logSite, StringBuilder out) { - if (logSite == LogSite.INVALID) { - return false; - } - out.append(logSite.getClassName()) - .append('.') - .append(logSite.getMethodName()) - .append(':') - .append(logSite.getLineNumber()); - return true; + return LogSiteFormatters.DEFAULT.appendLogSite(logSite, out); } /** diff --git a/api/src/test/java/com/google/common/flogger/backend/LogSiteFormattersTest.java b/api/src/test/java/com/google/common/flogger/backend/LogSiteFormattersTest.java new file mode 100644 index 0000000..31c8100 --- /dev/null +++ b/api/src/test/java/com/google/common/flogger/backend/LogSiteFormattersTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 The Flogger Authors. + * + * 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. + */ + +package com.google.common.flogger.backend; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.flogger.LogSite; +import com.google.common.flogger.testing.FakeLogSite; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class LogSiteFormattersTest { + + @Test + public void testInvalidLogSite() { + for (LogSiteFormatter formatter : LogSiteFormatters.values()) { + StringBuilder out = new StringBuilder(); + assertThat(formatter.appendLogSite(LogSite.INVALID, out)).isFalse(); + assertThat(out.toString()).isEmpty(); + } + } + + @Test + public void testAppendLogSite_default() { + StringBuilder out = new StringBuilder(); + LogSite logSite = FakeLogSite.create("", "", 32, "Ignored.java"); + assertThat(LogSiteFormatters.DEFAULT.appendLogSite(logSite, out)).isTrue(); + assertThat(out.toString()).isEqualTo(".:32"); + } + + @Test + public void testAppendLogSite_noOp() { + StringBuilder out = new StringBuilder(); + LogSite logSite = FakeLogSite.create("", "", 32, "Ignored.java"); + assertThat(LogSiteFormatters.NO_OP.appendLogSite(logSite, out)).isFalse(); + assertThat(out.toString()).isEmpty(); + } + + @Test + public void testAppendLogSite_simpleClassname_qualifiedName_unqualified() { + StringBuilder out = new StringBuilder(); + LogSite logSite = + FakeLogSite.create( + "com.google.common.flogger.backend.LogSiteFormattersTest", + "testMethod", + 42, + "Ignored.java"); + assertThat(LogSiteFormatters.SIMPLE_CLASSNAME.appendLogSite(logSite, out)).isTrue(); + assertThat(out.toString()).isEqualTo("LogSiteFormattersTest.testMethod:42"); + } + + @Test + public void testAppendLogSite_simpleClassname_unqualifiedName_all() { + StringBuilder out = new StringBuilder(); + LogSite logSite = FakeLogSite.create("LogSiteFormattersTest", "testMethod", 55, "Ignored.java"); + assertThat(LogSiteFormatters.SIMPLE_CLASSNAME.appendLogSite(logSite, out)).isTrue(); + assertThat(out.toString()).isEqualTo("LogSiteFormattersTest.testMethod:55"); + } + + @Test + public void testAppendLogSite_simpleClassname_trailingDot_all() { + StringBuilder out = new StringBuilder(); + LogSite logSite = + FakeLogSite.create("LogSiteFormattersTest.", "testMethod", 63, "Ignored.java"); + assertThat(LogSiteFormatters.SIMPLE_CLASSNAME.appendLogSite(logSite, out)).isTrue(); + assertThat(out.toString()).isEqualTo("LogSiteFormattersTest..testMethod:63"); + } + + @Test + public void testAppendLogSite_simpleClassname_fakeClassName() { + StringBuilder out = new StringBuilder(); + LogSite logSite = FakeLogSite.create("", "", 32, "Ignored.java"); + assertThat(LogSiteFormatters.SIMPLE_CLASSNAME.appendLogSite(logSite, out)).isTrue(); + assertThat(out.toString()).isEqualTo(".:32"); + } +}