From 0752f8cc9ed0bbcb206a67cdb29bead5a4e9109e Mon Sep 17 00:00:00 2001 From: Yegor Bugayenko Date: Tue, 26 Dec 2023 14:02:09 +0300 Subject: [PATCH] #174 FileDecor --- README.md | 1 + .../java/com/jcabi/log/DecorsManager.java | 1 + src/main/java/com/jcabi/log/FileDecor.java | 77 +++++++++++++++ .../java/com/jcabi/log/FileDecorTest.java | 96 +++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 src/main/java/com/jcabi/log/FileDecor.java create mode 100644 src/test/java/com/jcabi/log/FileDecorTest.java diff --git a/README.md b/README.md index 90dccfd4..dc1a9c6e 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ other custom ones, which help formatting common values faster: * `%[nano]s` --- nanoseconds ➜ µs, ms, sec, min, hours, etc. * `%[type]s` --- `Class` ➜ name of it * `%[secret]s` --- any string ➜ stars + * `%[dom]s` --- `org.w3c.domDocument` ➜ pretty printed/formatted XML You are welcome to suggest your own "decors". diff --git a/src/main/java/com/jcabi/log/DecorsManager.java b/src/main/java/com/jcabi/log/DecorsManager.java index 5d18718c..dc471920 100644 --- a/src/main/java/com/jcabi/log/DecorsManager.java +++ b/src/main/java/com/jcabi/log/DecorsManager.java @@ -50,6 +50,7 @@ final class DecorsManager { new ConcurrentHashMap<>(0); static { + DecorsManager.DECORS.put("file", FileDecor.class); DecorsManager.DECORS.put("dom", DomDecor.class); DecorsManager.DECORS.put("exception", ExceptionDecor.class); DecorsManager.DECORS.put("list", ListDecor.class); diff --git a/src/main/java/com/jcabi/log/FileDecor.java b/src/main/java/com/jcabi/log/FileDecor.java new file mode 100644 index 00000000..55482ca3 --- /dev/null +++ b/src/main/java/com/jcabi/log/FileDecor.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012-2022, jcabi.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. 3) Neither the name of the jcabi.com nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jcabi.log; + +import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Formattable; +import java.util.Formatter; + +/** + * Decorates File. + * + * @since 0.1 + */ +final class FileDecor implements Formattable { + + /** + * The path. + */ + private final transient Object path; + + /** + * Public ctor. + * @param file The file + */ + FileDecor(final Object file) { + this.path = file; + } + + // @checkstyle ParameterNumber (4 lines) + @Override + public void formatTo(final Formatter formatter, final int flags, + final int width, final int precision) { + final StringWriter writer = new StringWriter(); + if (this.path == null) { + writer.write("NULL"); + } else { + final Path self = Paths.get(this.path.toString()).toAbsolutePath(); + final Path root = Paths.get("").toAbsolutePath(); + String rel = root.relativize(self).toString(); + if (rel.startsWith("..")) { + rel = self.toString(); + } + writer.write(rel); + } + formatter.format("%s", writer); + } + +} diff --git a/src/test/java/com/jcabi/log/FileDecorTest.java b/src/test/java/com/jcabi/log/FileDecorTest.java new file mode 100644 index 00000000..ae2c5fcd --- /dev/null +++ b/src/test/java/com/jcabi/log/FileDecorTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012-2022, jcabi.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. 3) Neither the name of the jcabi.com nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jcabi.log; + +import java.io.File; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collection; +import java.util.Locale; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * Test case for {@link FileDecor}. + * + * @since 0.1 + * @checkstyle ParameterNumberCheck (500 lines) + */ +public final class FileDecorTest { + + @Test + public void simplyWorks() { + MatcherAssert.assertThat( + new Printed(new FileDecor("/tmp/test-me.txt"), 0, 0, 0).toString(), + Matchers.endsWith("test-me.txt") + ); + } + + @ParameterizedTest + @MethodSource("params") + public void testPrintsRight(final Object path, final String text, + final int flags, final int width, final int precision) { + Locale.setDefault(Locale.US); + MatcherAssert.assertThat( + new Printed(new FileDecor(path), flags, width, precision), + Matchers.hasToString(text) + ); + } + + @ParameterizedTest + @MethodSource("params") + public void testLogsRight(final Object path, final String text, + final int flags, final int width, final int precision) { + Locale.setDefault(Locale.US); + MatcherAssert.assertThat( + new Logged(new FileDecor(path), flags, width, precision), + Matchers.hasToString(text) + ); + } + + /** + * Params for this parametrized test. + * @return Array of arrays of params for ctor + */ + @SuppressWarnings("PMD.UnusedPrivateMethod") + private static Collection params() { + return Arrays.asList( + new Object[][] { + {null, "NULL", 0, 0, 0}, + {"foo.txt", "foo.txt", 0, 0, 0}, + {new File("/tmp/x.txt"), "/tmp/x.txt", 0, 0, 0}, + {Paths.get("/a/b/c.txt"), "/a/b/c.txt", 0, 0, 0}, + } + ); + } +}