strongduanmu commented on code in PR #30321:
URL: https://github.com/apache/shardingsphere/pull/30321#discussion_r1506892978


##########
mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java:
##########
@@ -67,123 +46,16 @@ public final class JDBCRepositorySQLLoader {
      * @param type type of JDBC repository SQL
      * @return loaded JDBC repository SQL
      */
-    @SneakyThrows({IOException.class, URISyntaxException.class})
+    @SneakyThrows(IOException.class)
     public static JDBCRepositorySQL load(final String type) {
-        Enumeration<URL> resources = 
JDBCRepositorySQLLoader.class.getClassLoader().getResources(ROOT_DIRECTORY);
-        if (null == resources) {
-            return null;
-        }
-        JDBCRepositorySQL result = null;
-        while (resources.hasMoreElements()) {
-            URL resource = resources.nextElement();
-            result = JAR_URL_PROTOCOLS.contains(resource.getProtocol()) ? 
loadFromJar(resource, type) : loadFromDirectory(resource, type);
-            if (null != result && !result.isDefault()) {
-                break;
-            }
-        }
-        return result;
-    }
-    
-    /**
-     * Under the GraalVM Native Image, 
`com.oracle.svm.core.jdk.resources.NativeImageResourceFileSystem` does not 
autoload.
-     * This is mainly to align the behavior of `jdk.nio.zipfs.ZipFileSystem`,
-     * so ShardingSphere need to manually open and close the FileSystem 
corresponding to the `resource:/` scheme.
-     * For more background reference <a 
href="https://github.com/oracle/graal/issues/7682";>oracle/graal#7682</a>.
-     *
-     * @param url  url
-     * @param type type of JDBC repository SQL
-     * @return loaded JDBC repository SQL
-     * @throws URISyntaxException Checked exception thrown to indicate that a 
string could not be parsed as a URI reference
-     * @throws IOException        Signals that an I/O exception to some sort 
has occurred
-     * @see jdk.nio.zipfs.ZipFileSystemProvider
-     * @see sun.nio.fs.UnixFileSystemProvider
-     */
-    private static JDBCRepositorySQL loadFromDirectory(final URL url, final 
String type) throws URISyntaxException, IOException {
-        if ("resource".equals(url.getProtocol())) {
-            try (FileSystem ignored = 
FileSystems.newFileSystem(URI.create("resource:/"), Collections.emptyMap())) {
-                return loadFromDirectoryInNativeImage(url, type);
-            }
-        }
-        return loadFromDirectoryLegacy(url, type);
-    }
-    
-    /**
-     * Affected by <a 
href="https://github.com/oracle/graal/issues/7804";>oracle/graal#7804</a>, 
ShardingSphere needs to
-     * avoid the use of `java.nio.file.Path#toFile` in GraalVM Native Image.
-     *
-     * @param url  url
-     * @param type type of JDBC repository SQL
-     * @return loaded JDBC repository SQL
-     * @throws URISyntaxException Checked exception thrown to indicate that a 
string could not be parsed as a URI reference
-     * @throws IOException        Signals that an I/O exception to some sort 
has occurred
-     * @see java.nio.file.Path
-     * @see java.io.File
-     */
-    private static JDBCRepositorySQL loadFromDirectoryInNativeImage(final URL 
url, final String type) throws URISyntaxException, IOException {
-        final JDBCRepositorySQL[] result = new JDBCRepositorySQL[1];
-        Files.walkFileTree(Paths.get(url.toURI()), new 
SimpleFileVisitor<Path>() {
-            
-            @Override
-            public FileVisitResult visitFile(final Path file, final 
BasicFileAttributes attributes) throws IOException {
-                if (file.toString().endsWith(FILE_EXTENSION)) {
-                    InputStream inputStream = 
Files.newInputStream(file.toAbsolutePath());
-                    JDBCRepositorySQL provider = 
XML_MAPPER.readValue(inputStream, JDBCRepositorySQL.class);
-                    if (provider.isDefault()) {
-                        result[0] = provider;
-                    }
-                    if (Objects.equals(provider.getType(), type)) {
-                        result[0] = provider;
-                        return FileVisitResult.TERMINATE;
-                    }
-                }
-                return FileVisitResult.CONTINUE;
-            }
-        });
-        return result[0];
-    }
-    
-    private static JDBCRepositorySQL loadFromDirectoryLegacy(final URL url, 
final String type) throws URISyntaxException, IOException {
-        final JDBCRepositorySQL[] result = new JDBCRepositorySQL[1];
-        Files.walkFileTree(Paths.get(url.toURI()), new 
SimpleFileVisitor<Path>() {
-            
-            @Override
-            public FileVisitResult visitFile(final Path file, final 
BasicFileAttributes attributes) throws IOException {
-                if (file.toString().endsWith(FILE_EXTENSION)) {
-                    InputStream inputStream = 
Files.newInputStream(file.toFile().toPath());
-                    JDBCRepositorySQL provider = 
XML_MAPPER.readValue(inputStream, JDBCRepositorySQL.class);
-                    if (provider.isDefault()) {
-                        result[0] = provider;
-                    }
-                    if (Objects.equals(provider.getType(), type)) {
-                        result[0] = provider;
-                        return FileVisitResult.TERMINATE;
-                    }
-                }
-                return FileVisitResult.CONTINUE;
-            }
-        });
-        return result[0];
-    }
-    
-    private static JDBCRepositorySQL loadFromJar(final URL url, final String 
type) throws IOException {
-        URL jarUrl = url;
-        if ("zip".equals(url.getProtocol())) {
-            jarUrl = new URL(url.toExternalForm().replace("zip:/", 
"jar:file:/"));
-        }
-        URLConnection urlConnection = jarUrl.openConnection();
-        if (!(urlConnection instanceof JarURLConnection)) {
-            return null;
-        }
         JDBCRepositorySQL result = null;
-        try (JarFile jar = ((JarURLConnection) urlConnection).getJarFile()) {
-            Enumeration<JarEntry> entries = jar.entries();
-            while (entries.hasMoreElements()) {
-                String name = entries.nextElement().getName();
-                if (!name.startsWith(ROOT_DIRECTORY) || 
!name.endsWith(FILE_EXTENSION)) {
+        try (Stream<String> resourceNameStream = 
ClasspathResourceDirectoryReader.read(JDBCRepositorySQLLoader.class.getClassLoader(),
 ROOT_DIRECTORY)) {
+            Iterable<String> resourceNameIterable = 
resourceNameStream::iterator;
+            for (final String each : resourceNameIterable) {

Review Comment:
   Please remove final in local variable.



##########
infra/util/src/main/java/org/apache/shardingsphere/infra/util/directory/ClasspathResourceDirectoryReader.java:
##########
@@ -0,0 +1,185 @@
+/*
+ * 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.shardingsphere.infra.util.directory;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Stream;
+
+/**
+ * Classpath resource directory reader.
+ */
+@RequiredArgsConstructor
+public class ClasspathResourceDirectoryReader {
+    
+    private static final Collection<String> JAR_URL_PROTOCOLS = new 
HashSet<>(Arrays.asList("jar", "war", "zip", "wsjar", "vfszip"));
+    
+    /**
+     * Tests whether a resource is a directory.

Review Comment:
   Do you think `Judge whether a resource is a directory or not.` is better?



##########
infra/util/src/main/java/org/apache/shardingsphere/infra/util/directory/ClasspathResourceDirectoryReader.java:
##########
@@ -0,0 +1,185 @@
+/*
+ * 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.shardingsphere.infra.util.directory;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Stream;
+
+/**
+ * Classpath resource directory reader.
+ */
+@RequiredArgsConstructor
+public class ClasspathResourceDirectoryReader {
+    
+    private static final Collection<String> JAR_URL_PROTOCOLS = new 
HashSet<>(Arrays.asList("jar", "war", "zip", "wsjar", "vfszip"));
+    
+    /**
+     * Tests whether a resource is a directory.
+     *
+     * @param name resource name
+     * @return true if the resource is a directory; false if the resource does 
not exist, is not a directory, or it cannot be determined if the resource is a 
directory or not.
+     */
+    public static boolean isDirectory(final String name) {
+        return isDirectory(Thread.currentThread().getContextClassLoader(), 
name);
+    }
+    
+    /**
+     * Tests whether a resource is a directory.
+     *
+     * @param classLoader class loader
+     * @param name resource name
+     * @return true if the resource is a directory; false if the resource does 
not exist, is not a directory, or it cannot be determined if the resource is a 
directory or not.
+     */
+    @SneakyThrows({IOException.class, URISyntaxException.class})
+    public static boolean isDirectory(final ClassLoader classLoader, final 
String name) {
+        URL resourceUrl = classLoader.getResource(name);
+        if (null == resourceUrl) {
+            return false;
+        }
+        if (JAR_URL_PROTOCOLS.contains(resourceUrl.getProtocol())) {
+            JarFile jarFile = getJarFile(resourceUrl);
+            if (null == jarFile) {
+                return false;
+            }
+            return jarFile.getJarEntry(name).isDirectory();
+        } else {
+            if ("resourceUrl".equals(resourceUrl.getProtocol())) {
+                try (FileSystem ignored = 
FileSystems.newFileSystem(URI.create("resource:/"), Collections.emptyMap())) {
+                    return Files.isDirectory(Paths.get(resourceUrl.toURI()));
+                }
+            }
+            return Files.isDirectory(Paths.get(resourceUrl.toURI()));
+        }
+    }
+    
+    /**
+     * Return a lazily populated Stream that contains the names of resources 
in the provided directory. The Stream is recursive, meaning it includes 
resources from all subdirectories as well.
+     *
+     * <p>When the {@code directory} parameter is a file, the method can still 
work.</p>
+     *
+     * @param directory directory
+     * @return resource iterator.
+     * @apiNote This method must be used within a try-with-resources statement 
or similar
+     *         control structure to ensure that the stream's open resources 
are closed
+     *         promptly after the stream's operations have completed.
+     */
+    public static Stream<String> read(final String directory) {
+        return read(Thread.currentThread().getContextClassLoader(), directory);
+    }
+    
+    /**
+     * Return a lazily populated Stream that contains the names of resources 
in the provided directory. The Stream is recursive, meaning it includes 
resources from all subdirectories as well.
+     *
+     * <p>When the {@code directory} parameter is a file, the method can still 
work.</p>
+     *
+     * @param classLoader class loader
+     * @param directory directory
+     * @return resource iterator.
+     * @apiNote This method must be used within a try-with-resources statement 
or similar
+     *         control structure to ensure that the stream's open resources 
are closed
+     *         promptly after the stream's operations have completed.
+     */
+    @SneakyThrows(IOException.class)
+    public static Stream<String> read(final ClassLoader classLoader, final 
String directory) {
+        Enumeration<URL> directoryUrlEnumeration = 
classLoader.getResources(directory);
+        if (null == directoryUrlEnumeration) {
+            return Stream.empty();
+        }
+        return 
Collections.list(directoryUrlEnumeration).stream().flatMap(directoryUrl -> {
+            if (JAR_URL_PROTOCOLS.contains(directoryUrl.getProtocol())) {
+                return readDirectoryInJar(directory, directoryUrl);
+            } else {
+                return readDirectoryInFileSystem(directoryUrl);
+            }
+        });
+    }
+    
+    private static Stream<String> readDirectoryInJar(final String directory, 
final URL directoryUrl) {
+        JarFile jar = getJarFile(directoryUrl);
+        if (null == jar) {
+            return Stream.empty();
+        }
+        return jar.stream().filter(jarEntry -> 
jarEntry.getName().startsWith(directory) && 
!jarEntry.isDirectory()).map(JarEntry::getName).onClose(() -> {
+            try {
+                jar.close();
+            } catch (IOException e) {

Review Comment:
   Please add final and rename e to ex.



##########
infra/util/src/main/java/org/apache/shardingsphere/infra/util/directory/ClasspathResourceDirectoryReader.java:
##########
@@ -0,0 +1,185 @@
+/*
+ * 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.shardingsphere.infra.util.directory;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Stream;
+
+/**
+ * Classpath resource directory reader.
+ */
+@RequiredArgsConstructor
+public class ClasspathResourceDirectoryReader {
+    
+    private static final Collection<String> JAR_URL_PROTOCOLS = new 
HashSet<>(Arrays.asList("jar", "war", "zip", "wsjar", "vfszip"));
+    
+    /**
+     * Tests whether a resource is a directory.
+     *
+     * @param name resource name
+     * @return true if the resource is a directory; false if the resource does 
not exist, is not a directory, or it cannot be determined if the resource is a 
directory or not.
+     */
+    public static boolean isDirectory(final String name) {
+        return isDirectory(Thread.currentThread().getContextClassLoader(), 
name);
+    }
+    
+    /**
+     * Tests whether a resource is a directory.

Review Comment:
   Do you think `Judge whether a resource is a directory or not.` is better?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to