< prev index next >
src/java.base/share/classes/jdk/internal/module/Resources.java
Print this page
@@ -20,64 +20,106 @@
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package jdk.internal.loader;
+package jdk.internal.module;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
-
-import jdk.internal.module.Checks;
+import java.nio.file.attribute.BasicFileAttributes;
/**
- * Helper class for Class#getResource, Module#getResourceAsStream, and other
- * methods that locate a resource in a module.
+ * A helper class to support working with resources in modules. Also provides
+ * support for translating resource names to file paths.
*/
-public final class ResourceHelper {
- private ResourceHelper() { }
+public final class Resources {
+ private Resources() { }
/**
- * Returns the <em>package name</em> for a resource or the empty package if
- * the resource name does not contain a slash.
+ * Return true if a resource can be encapsulated. Resource with names
+ * ending in ".class" or "/" cannot be encapsulated. Resource names
+ * that map to a legal package name can be encapsulated.
*/
- public static String getPackageName(String name) {
- int index = name.lastIndexOf('/');
- if (index != -1) {
- return name.substring(0, index).replace("/", ".");
+ public static boolean canEncapsulate(String name) {
+ int len = name.length();
+ if (len > 6 && name.endsWith(".class")) {
+ return false;
} else {
- return "";
+ return Checks.isPackageName(toPackageName(name));
}
}
/**
- * Returns true if the resource is a <em>simple resource</em>. Simple
- * resources can never be encapsulated. Resources ending in "{@code .class}"
- * or where the package name is not a legal package name can not be
- * encapsulated.
+ * Derive a <em>package name</em> for a resource. The package name
+ * returned by this method may not be a legal package name. This method
+ * returns null if the the resource name ends with a "/" (a directory)
+ * or the resource name does not contain a "/".
*/
- public static boolean isSimpleResource(String name) {
- int len = name.length();
- if (len > 6 && name.endsWith(".class")) {
- return true;
+ public static String toPackageName(String name) {
+ int index = name.lastIndexOf('/');
+ if (index == -1 || index == name.length()-1) {
+ return "";
+ } else {
+ return name.substring(0, index).replace("/", ".");
}
- if (!Checks.isPackageName(getPackageName(name))) {
- return true;
}
- return false;
+
+ /**
+ * Returns a resource name corresponding to the relative file path
+ * between {@code dir} and {@code file}. If the file is a directory
+ * then the name will end with a "/", except the top-level directory
+ * where the empty string is returned.
+ */
+ public static String toResourceName(Path dir, Path file) {
+ String s = dir.relativize(file)
+ .toString()
+ .replace(File.separatorChar, '/');
+ if (s.length() > 0 && Files.isDirectory(file))
+ s += "/";
+ return s;
}
/**
- * Converts a resource name to a file path. Returns {@code null} if the
- * resource name cannot be converted into a file path. Resource names
- * with empty elements, or elements that are "." or ".." are rejected,
- * as is a resource name that translates to a file path with a root
- * component.
+ * Returns a file path to a resource in a file tree. If the resource
+ * name has a trailing "/" then the file path will locate a directory.
+ * Returns {@code null} if the resource does not map to a file in the
+ * tree file.
+ */
+ public static Path toFilePath(Path dir, String name) throws IOException {
+ boolean expectDirectory = name.endsWith("/");
+ if (expectDirectory) {
+ name = name.substring(0, name.length() - 1); // drop trailing "/"
+ }
+ Path path = toSafeFilePath(name);
+ if (path != null) {
+ Path file = dir.resolve(path);
+ try {
+ BasicFileAttributes attrs;
+ attrs = Files.readAttributes(file, BasicFileAttributes.class);
+ if (attrs.isDirectory()
+ || (!attrs.isDirectory() && !expectDirectory))
+ return file;
+ } catch (NoSuchFileException ignore) { }
+ }
+ return null;
+ }
+
+ /**
+ * Map a resource name to a "safe" file path. Returns {@code null} if
+ * the resource name cannot be converted into a "safe" file path.
+ *
+ * Resource names with empty elements, or elements that are "." or ".."
+ * are rejected, as are resource names that translates to a file path
+ * with a root component.
*/
- public static Path toFilePath(String name) {
- // scan the resource name to eagerly reject obviously invalid names
+ private static Path toSafeFilePath(String name) {
+ // scan elements of resource name
int next;
int off = 0;
while ((next = name.indexOf('/', off)) != -1) {
int len = next - off;
if (!mayTranslate(name, off, len)) {
< prev index next >