diff --git a/java/org/apache/catalina/Context.java b/java/org/apache/catalina/Context.java
index 928c1bfcd079..ddb29516b618 100644
--- a/java/org/apache/catalina/Context.java
+++ b/java/org/apache/catalina/Context.java
@@ -16,6 +16,7 @@
*/
package org.apache.catalina;
+import java.io.IOException;
import java.net.URL;
import java.util.Locale;
import java.util.Map;
@@ -38,6 +39,7 @@
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
+import org.apache.tomcat.util.file.ConfigurationSource.Resource;
import org.apache.tomcat.util.http.CookieProcessor;
/**
@@ -84,6 +86,11 @@ public interface Context extends Container, ContextBind {
String CHANGE_SESSION_ID_EVENT = "changeSessionId";
+ /**
+ * Prefix for resource lookup.
+ */
+ String WEBAPP_PROTOCOL = "webapp:";
+
// ------------------------------------------------------------- Properties
/**
@@ -1963,4 +1970,17 @@ void setAllowMultipleLeadingForwardSlashInPath(
* @param dispatcherWrapsSameObject the new flag value
*/
void setDispatcherWrapsSameObject(boolean dispatcherWrapsSameObject);
+
+
+ /**
+ * Find configuration file with the specified path, first looking into the
+ * webapp resources, then delegating to
+ * ConfigFileLoader.getSource().getResource
. The
+ * WEBAPP_PROTOCOL
constant prefix is used to denote webapp
+ * resources.
+ * @param name The resource name
+ * @return the resource
+ * @throws IOException if an error occurs or if the resource does not exist
+ */
+ Resource findConfigFileResource(String name) throws IOException;
}
diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java
index 6476bf08c5c6..b8c911a9c300 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -20,6 +20,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
@@ -127,6 +128,8 @@
import org.apache.tomcat.util.descriptor.web.MessageDestination;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
+import org.apache.tomcat.util.file.ConfigFileLoader;
+import org.apache.tomcat.util.file.ConfigurationSource.Resource;
import org.apache.tomcat.util.http.CookieProcessor;
import org.apache.tomcat.util.http.Rfc6265CookieProcessor;
import org.apache.tomcat.util.scan.StandardJarScanner;
@@ -3497,6 +3500,25 @@ public String[] findWrapperListeners() {
}
+ @Override
+ public Resource findConfigFileResource(String name) throws IOException {
+ if (name.startsWith(WEBAPP_PROTOCOL)) {
+ String path = name.substring(WEBAPP_PROTOCOL.length());
+ WebResource resource = getResources().getResource(path);
+ if (resource.canRead()) {
+ InputStream stream = resource.getInputStream();
+ try {
+ return new Resource(stream, resource.getURL().toURI());
+ } catch (URISyntaxException e) {
+ stream.close();
+ }
+ }
+ return null;
+ } else {
+ return ConfigFileLoader.getSource().getResource(name);
+ }
+ }
+
/**
* Reload this web application, if reloading is supported.
*
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6d58f1ceb270..537749e57a2b 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -117,6 +117,12 @@
if the web applications were deliberately crafted to allow it even when
allowLinking
was set to false
. (markt)
+ Context
to allow
+ looking up resources from the webapp (prefixed with
+ webapp:
) and make the resource lookup API more visible.
+ (remm)
+