This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 4078378df 
org.apache.juneau.microservice.jetty.JettyMicroservice.Builder.jettyXml(Object, 
boolean) now handles java.nio.file.Path.
4078378df is described below

commit 4078378dff0fe97f44dae6d27a7cb8b3649e72ed
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Fri Jun 6 12:29:23 2025 -0400

    
org.apache.juneau.microservice.jetty.JettyMicroservice.Builder.jettyXml(Object,
    boolean) now handles java.nio.file.Path.
    
    - Add org.apache.juneau.common.internal.PathReaderBuilder
    - Add org.apache.juneau.common.internal.IOUtils.read(Path)
---
 RELEASE-NOTES.txt                                  |   3 +
 .../org/apache/juneau/common/internal/IOUtils.java |  86 +++++++++-----
 .../juneau/common/internal/PathReaderBuilder.java  | 125 +++++++++++++++++++++
 .../microservice/jetty/JettyMicroservice.java      |  18 +--
 .../apache/juneau/common/internal/IOUtilsTest.java |  36 ++++++
 .../common/internal/PathReaderBuilderTest.java     | 116 +++++++++++++++++++
 6 files changed, 352 insertions(+), 32 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 323e38eab..3e7618739 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -48,6 +48,9 @@ Release Notes - Juneau - Version 9.1.0
     * Add org.apache.juneau.rest.mock.MockServletResponse.sendRedirect(String, 
int, boolean) for jakarta.servlet:jakarta.servlet-api 6.1.0.
     * Bump org.junit:junit-bom from 5.10.3 to 5.11.4 #161, #168, #171, #173, 
#185.
     * Flip console output logic on shutdown from a system property called 
'SystemUtils.quiet' to 'SystemUtils.verbose'.
+    * 
org.apache.juneau.microservice.jetty.JettyMicroservice.Builder.jettyXml(Object, 
boolean) now handles java.nio.file.Path.
+    * Add org.apache.juneau.common.internal.PathReaderBuilder
+    * Add org.apache.juneau.common.internal.IOUtils.read(Path)
     
 Release Notes - Juneau - Version 9.0.1
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/IOUtils.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/IOUtils.java
index 9c935a3eb..79aea8565 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/IOUtils.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/IOUtils.java
@@ -12,11 +12,24 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.common.internal;
 
-import java.io.*;
-import java.nio.charset.*;
-import java.util.*;
-import java.util.concurrent.atomic.*;
-import java.util.function.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Scanner;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 
 /**
  * Various I/O related utility methods.
@@ -461,26 +474,49 @@ public final class IOUtils {
                return new String(in, charset);
        }
 
-       /**
-        * Reads the contents of a file into a string.
-        *
-        * <p>
-        * Assumes default character encoding.
-        *
-        * @param in
-        *      The file to read.
-        *      <br>Can be <jk>null</jk>.
-        * @return
-        *      The contents of the reader as a string, or <jk>null</jk> if 
file does not exist.
-        * @throws IOException If a problem occurred trying to read from the 
reader.
-        */
-       public static String read(File in) throws IOException {
-               if (in == null || ! in.exists())
-                       return null;
-               try (Reader r = FileReaderBuilder.create(in).build()) {
-                       return read(r, in.length());
-               }
-       }
+    /**
+     * Reads the contents of a file into a string.
+     *
+     * <p>
+     * Assumes default character encoding.
+     *
+     * @param in
+     *  The file to read.
+     *  <br>Can be <jk>null</jk>.
+     * @return
+     *  The contents of the reader as a string, or <jk>null</jk> if file does 
not exist.
+     * @throws IOException If a problem occurred trying to read from the 
reader.
+     */
+    public static String read(File in) throws IOException {
+        if (in == null || ! in.exists())
+            return null;
+        try (Reader r = FileReaderBuilder.create(in).build()) {
+            return read(r, in.length());
+        }
+    }
+
+    /**
+     * Reads the contents of a path into a string.
+     *
+     * <p>
+     * Assumes default character encoding.
+     *
+     * @param in
+     *  The path to read.
+     *  <br>Can be <jk>null</jk>.
+     * @return
+     *  The contents of the reader as a string, or <jk>null</jk> if path does 
not exist.
+     * @throws IOException If a problem occurred trying to read from the 
reader.
+     * @since 9.1.0
+     */
+    public static String read(Path in) throws IOException {
+        if (in == null || !Files.exists(in)) {
+            return null;
+        }
+        try (Reader r = PathReaderBuilder.create(in).build()) {
+            return read(r, Files.size(in));
+        }
+    }
 
        /**
         * Reads the contents of a reader into a string.
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/PathReaderBuilder.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/PathReaderBuilder.java
new file mode 100644
index 000000000..c2c6bcb8a
--- /dev/null
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/internal/PathReaderBuilder.java
@@ -0,0 +1,125 @@
+// 
***************************************************************************************************************************
+// * 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.juneau.common.internal;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Utility class for creating {@link Path}-based {@link Reader} objects.
+ *
+ * @since 9.1.0
+ */
+public final class PathReaderBuilder {
+
+    /**
+     * Creates a new builder.
+     *
+     * @return A new builder.
+     */
+    public static PathReaderBuilder create() {
+        return new PathReaderBuilder();
+    }
+
+    /**
+     * Creates a new builder initialized with the specified path.
+     *
+     * @param path The path being written to.
+     * @return A new builder.
+     */
+    public static PathReaderBuilder create(final Path path) {
+        return new PathReaderBuilder().path(path);
+    }
+
+    private Path path;
+
+    private Charset charset = Charset.defaultCharset();
+
+    private boolean allowNoFile;
+
+    /**
+     * If called and the path is <jk>null</jk> or non-existent, then the 
{@link #build()} command will return an empty reader instead of a {@link 
IOException}.
+     *
+     * @return This object.
+     */
+    public PathReaderBuilder allowNoFile() {
+        this.allowNoFile = true;
+        return this;
+    }
+
+    /**
+     * Creates a new File reader.
+     *
+     * @return A new File reader.
+     * @throws IOException if an I/O error occurs opening the path
+     */
+    public Reader build() throws IOException {
+        if (!allowNoFile && path == null) {
+            throw new IllegalStateException("No path");
+        }
+        if (!allowNoFile && !Files.exists(path)) {
+            throw new NoSuchFileException(path.toString());
+        }
+        return allowNoFile ? new StringReader("") : 
Files.newBufferedReader(path, charset != null ? charset : 
Charset.defaultCharset());
+    }
+
+    /**
+     * Sets the character encoding of the path.
+     *
+     * @param charset The character encoding. The default is {@link 
Charset#defaultCharset()}. Null resets to the default.
+     * @return This object.
+     */
+    public PathReaderBuilder charset(final Charset charset) {
+        this.charset = charset;
+        return this;
+    }
+
+    /**
+     * Sets the character encoding of the path.
+     *
+     * @param charset The character encoding. The default is {@link 
Charset#defaultCharset()}. Null resets to the default.
+     * @return This object.
+     */
+    public PathReaderBuilder charset(final String charset) {
+        this.charset = charset != null ? Charset.forName(charset) : null;
+        return this;
+    }
+
+    /**
+     * Sets the path being written from.
+     *
+     * @param path The path being written from.
+     * @return This object.
+     */
+    public PathReaderBuilder path(final Path path) {
+        this.path = path;
+        return this;
+    }
+
+    /**
+     * Sets the path of the path being written from.
+     *
+     * @param path The path of the path being written from.
+     * @return This object.
+     */
+    public PathReaderBuilder path(final String path) {
+        this.path = Paths.get(path);
+        return this;
+    }
+}
diff --git 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
index ccc9890a7..261d0bebc 100644
--- 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
+++ 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
@@ -30,6 +30,7 @@ import java.net.ServerSocket;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.UnknownHostException;
+import java.nio.file.Path;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Random;
@@ -203,7 +204,8 @@ public class JettyMicroservice extends Microservice {
                 *      <br>Can be any of the following:
                 *      <ul>
                 *              <li>{@link String} - Relative path to file on 
file system or classpath.
-                *              <li>{@link File} - File on file system.
+         *      <li>{@link File} - File on file system.
+         *      <li>{@link Path} - Path on file system.
                 *              <li>{@link InputStream} - Raw contents as 
<c>UTF-8</c> encoded stream.
                 *              <li>{@link Reader} - Raw contents.
                 *      </ul>
@@ -216,12 +218,14 @@ public class JettyMicroservice extends Microservice {
                public Builder jettyXml(Object jettyXml, boolean resolveVars) 
throws IOException {
                        if (jettyXml instanceof String)
                                this.jettyXml = 
read(resolveFile(jettyXml.toString()));
-                       else if (jettyXml instanceof File)
-                               this.jettyXml = read((File)jettyXml);
-                       else if (jettyXml instanceof InputStream)
-                               this.jettyXml = read((InputStream)jettyXml);
-                       else if (jettyXml instanceof Reader)
-                               this.jettyXml = read((Reader)jettyXml);
+            else if (jettyXml instanceof File file)
+                this.jettyXml = read(file);
+            else if (jettyXml instanceof Path path)
+                this.jettyXml = read(path);
+                       else if (jettyXml instanceof InputStream inputStream)
+                               this.jettyXml = read(inputStream);
+                       else if (jettyXml instanceof Reader reader)
+                               this.jettyXml = read(reader);
                        else
                                throw new BasicRuntimeException("Invalid object 
type passed to jettyXml(Object): {0}", className(jettyXml));
                        this.jettyXmlResolveVars = resolveVars;
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/internal/IOUtilsTest.java 
b/juneau-utest/src/test/java/org/apache/juneau/common/internal/IOUtilsTest.java
new file mode 100644
index 000000000..c2dedf9a1
--- /dev/null
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/internal/IOUtilsTest.java
@@ -0,0 +1,36 @@
+// 
***************************************************************************************************************************
+// * 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.juneau.common.internal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link IOUtils}.
+ */
+public class IOUtilsTest {
+
+    @Test
+    public void testReadPath() throws IOException {
+        var p = new Properties();
+        p.load(new 
StringReader(IOUtils.read(Paths.get("src/test/resources/files/Test3.properties"))));
+        assertEquals("files/Test3.properties", p.get("file"));
+    }
+}
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/internal/PathReaderBuilderTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/internal/PathReaderBuilderTest.java
new file mode 100644
index 000000000..ad9d6f142
--- /dev/null
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/internal/PathReaderBuilderTest.java
@@ -0,0 +1,116 @@
+// 
***************************************************************************************************************************
+// * 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.juneau.common.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link PathReaderBuilder}.
+ */
+public class PathReaderBuilderTest {
+
+    private static final Path PATH = 
Paths.get("src/test/resources/files/Test3.properties");
+
+    @Test
+    public void testAllowNoFile() throws IOException {
+        final var p = new Properties();
+        try (Reader r = PathReaderBuilder.create().allowNoFile().build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertNull(p.get("file"));
+        p.clear();
+        try (Reader r = PathReaderBuilder.create().allowNoFile().path("this 
file does not exist, at all.").build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertNull(p.get("file"));
+    }
+
+    @Test
+    public void testAllowNoFileException() throws IOException {
+        final var p = new Properties();
+        assertThrows(IllegalStateException.class, () -> 
PathReaderBuilder.create().build());
+        assertThrows(NoSuchFileException.class, () -> 
PathReaderBuilder.create().path("this file does not exist, at all.").build());
+    }
+
+    @Test
+    public void testCharsetCharset() throws IOException {
+        final var p = new Properties();
+        try (Reader r = 
PathReaderBuilder.create().path(PATH).charset(StandardCharsets.UTF_8).build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+        p.clear();
+        try (Reader r = 
PathReaderBuilder.create().path(PATH).charset((Charset) null).build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+    }
+
+    @Test
+    public void testCharsetString() throws IOException {
+        final var p = new Properties();
+        try (Reader r = 
PathReaderBuilder.create().path(PATH).charset(StandardCharsets.UTF_8.name()).build())
 {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+        p.clear();
+        try (Reader r = PathReaderBuilder.create().path(PATH).charset((String) 
null).build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+    }
+
+    @Test
+    public void testCreate() throws IOException {
+        final var p = new Properties();
+        try (Reader r = PathReaderBuilder.create(PATH).build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+    }
+
+    @Test
+    public void testPathPath() throws IOException {
+        final var p = new Properties();
+        try (Reader r = PathReaderBuilder.create().path(PATH).build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+    }
+
+    @Test
+    public void testPathString() throws IOException {
+        final var p = new Properties();
+        try (Reader r = 
PathReaderBuilder.create().path(PATH.toString()).build()) {
+            p.load(new StringReader(IOUtils.read(r, Files.size(PATH))));
+        }
+        assertEquals("files/Test3.properties", p.get("file"));
+    }
+
+}

Reply via email to