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]