You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/01/14 15:18:26 UTC
svn commit: r611807 - in
/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver: pom.xml
src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
Author: fmeschbe
Date: Mon Jan 14 06:18:23 2008
New Revision: 611807
URL: http://svn.apache.org/viewvc?rev=611807&view=rev
Log:
Make the servlet resolver also the script resolver and consolidate
path configuration for relative script/servlet paths.
Still need to figure out how to define the servlet paths for
servlets registered as OSGi services
Modified:
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/pom.xml
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
Modified: incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/pom.xml?rev=611807&r1=611806&r2=611807&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/pom.xml (original)
+++ incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/pom.xml Mon Jan 14 06:18:23 2008
@@ -68,6 +68,7 @@
<Private-Package>
org.apache.sling.servlet.resolver.*
</Private-Package>
+ <!--
<Import-Package>
javax.servlet , javax.servlet.http ,
org.apache.commons.beanutils,
@@ -81,6 +82,7 @@
org.osgi.framework,
org.osgi.service.component, org.slf4j
</Import-Package>
+ -->
</instructions>
</configuration>
</plugin>
Modified: incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java?rev=611807&r1=611806&r2=611807&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java (original)
+++ incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java Mon Jan 14 06:18:23 2008
@@ -35,6 +35,8 @@
* "sling.core.servlet.default"). If no servlet is registered under this
* name, the {@link org.apache.sling.servlet.resolver.defaults.DefaultServlet} is used.
*/
- public static final String DEFAULT_SERVLET_NAME = "sling.core.servlet.default";
+ public static final String DEFAULT_SERVLET_NAME = "sling/servlet/default";
+
+ public static final String ERROR_HANDLER_PATH = "sling/servlet/errorhandler";
}
Modified: incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java?rev=611807&r1=611806&r2=611807&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java (original)
+++ incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java Mon Jan 14 06:18:23 2008
@@ -18,15 +18,19 @@
*/
package org.apache.sling.servlet.resolver;
-import static org.apache.sling.api.SlingConstants.*;
-import static org.apache.sling.core.CoreConstants.*;
-import static org.apache.sling.servlet.resolver.ServletResolverConstants.*;
+import static org.apache.sling.api.SlingConstants.ERROR_MESSAGE;
+import static org.apache.sling.api.SlingConstants.ERROR_SERVLET_NAME;
+import static org.apache.sling.api.SlingConstants.ERROR_STATUS;
+import static org.apache.sling.core.CoreConstants.SLING_CURRENT_SERVLET_NAME;
+import static org.apache.sling.servlet.resolver.ServletResolverConstants.DEFAULT_SERVLET_NAME;
+import static org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_RESOURCE_TYPES;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -39,15 +43,18 @@
import org.apache.sling.api.SlingConstants;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.scripting.SlingScript;
import org.apache.sling.api.scripting.SlingScriptResolver;
import org.apache.sling.api.servlets.ServletResolver;
import org.apache.sling.core.servlets.AbstractServiceReferenceConfig;
import org.apache.sling.core.servlets.ErrorHandler;
+import org.apache.sling.osgi.commons.OsgiUtil;
import org.apache.sling.servlet.resolver.defaults.DefaultErrorHandlerServlet;
import org.apache.sling.servlet.resolver.defaults.DefaultServlet;
-import org.apache.sling.servlet.resolver.helper.ErrorSlingHttpServletRequest;
-import org.apache.sling.servlet.resolver.helper.SlingScriptServlet;
+import org.apache.sling.servlet.resolver.helper.PathSupport;
import org.apache.sling.servlet.resolver.helper.SlingServletConfig;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
@@ -57,7 +64,7 @@
/**
* The <code>SlingServletResolver</code> TODO
- *
+ *
* @scr.component label="%servletresolver.name"
* description="%servletresolver.description"
* @scr.property name="service.description" value="Sling Servlet Resolver and
@@ -67,13 +74,14 @@
* @scr.reference name="Servlet" interface="javax.servlet.Servlet"
* cardinality="0..n" policy="dynamic"
*/
-public class SlingServletResolver implements ServletResolver, ErrorHandler {
+public class SlingServletResolver implements ServletResolver,
+ SlingScriptResolver, ErrorHandler {
/** default log */
private final Logger log = LoggerFactory.getLogger(getClass());
/**
- * @scr.property values.1="/apps/components" values.2="/libs/components"
+ * @scr.property values.1="/apps" values.2="/libs"
* label="%resolver.path.name"
* description="%resolver.path.description"
*/
@@ -81,9 +89,6 @@
private static final String REF_SERVLET = "Servlet";
- /** @scr.reference cardinality="0..1" policy="dynamic" */
- private SlingScriptResolver scriptResolver;
-
/** @scr.reference */
private ServletContext servletContext;
@@ -103,14 +108,22 @@
// ---------- ServletResolver interface -----------------------------------
- public Servlet resolveServlet(SlingHttpServletRequest request) {
+ public Servlet resolveServlet(SlingHttpServletRequest request)
+ throws SlingException {
+ ResourceResolver resolver = request.getResourceResolver();
+ String baseName = PathSupport.getScriptBaseName(request);
- // resolve a servlet or script based on the request
- Servlet servlet = resolveServletOrScript(request);
+ // search the servlet by absolute path and resource type
+ Iterator<String> pathIterator = PathSupport.getPathIterator(request,
+ path);
+ Servlet servlet = null;
+ while (servlet == null && pathIterator.hasNext()) {
+ servlet = getServletAt(resolver, pathIterator.next(), baseName);
+ }
- // use default servlet, create one if missing
+ // fall back to default servlet for the request
if (servlet == null) {
- servlet = getServlet(DEFAULT_SERVLET_NAME);
+ servlet = getServletAt(resolver, DEFAULT_SERVLET_NAME, baseName);
}
// last resort, use the core bundle default servlet
@@ -118,144 +131,187 @@
servlet = getCoreDefaultServlet();
}
- if (servlet != null && log.isDebugEnabled()) {
- String name;
- if (servlet.getServletConfig() != null) {
- name = servlet.getServletConfig().getServletName();
+ if (log.isDebugEnabled()) {
+ if (servlet != null) {
+ String name;
+ if (servlet.getServletConfig() != null) {
+ name = servlet.getServletConfig().getServletName();
+ } else {
+ name = servlet.getServletInfo();
+ }
+ if (name == null) {
+ name = servlet.getClass().getName();
+ }
+ log.info("Servlet {} found for Resource={}", name,
+ request.getResource());
} else {
- name = servlet.getServletInfo();
+ log.debug("No servlet found for Resource={}",
+ request.getResource());
}
- if (name == null) {
- name = servlet.getClass().getName();
- }
- log.debug("Using Servlet {} for {}", name, path);
}
return servlet;
}
+ // ---------- ScriptResolver interface ------------------------------------
+
+ public SlingScript findScript(ResourceResolver resourceResolver, String name)
+ throws SlingException {
+
+ if (name.startsWith("/")) {
+ Resource resource = resourceResolver.getResource(name);
+ return (resource != null)
+ ? resource.adaptTo(SlingScript.class)
+ : null;
+ }
+
+ for (int i=0; i < path.length; i++) {
+ String scriptPath = path[i] + name;
+ Resource resource = resourceResolver.getResource(scriptPath);
+ if (resource != null) {
+ SlingScript script = resource.adaptTo(SlingScript.class);
+ if (script == null) {
+ log.debug("findScript: Using script {} for {}",
+ script.getScriptResource().getURI(), name);
+ return script;
+ }
+ }
+ }
+
+ log.info("findScript: No script {} found in path", name);
+ return null;
+ }
+
// ---------- ErrorHandler interface --------------------------------------
public void handleError(int status, String message,
- HttpServletRequest request, HttpServletResponse response)
+ SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
// do not handle, if already handling ....
- if (request.getAttribute(ERROR_REQUEST_URI) == null) {
-
- // find the error handler component
- ErrorSlingHttpServletRequest eRequest = new ErrorSlingHttpServletRequest(
- request, String.valueOf(status));
- Servlet servlet = resolveServletOrScript(eRequest);
-
- if (servlet == null) {
- servlet = getDefaultErrorServlet();
+ if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) != null) {
+ log.error("handleError: Recursive invocation. Not further handling status "
+ + status + "(" + message + ")");
+ return;
+ }
+
+ // find the error handler component
+ ResourceResolver resolver = request.getResourceResolver();
+ String baseName = String.valueOf(status);
+
+ // search the servlet by absolute path
+ Iterator<String> pathIterator = PathSupport.getPathIterator(
+ ServletResolverConstants.ERROR_HANDLER_PATH, path);
+ Servlet servlet = null;
+ while (servlet == null && pathIterator.hasNext()) {
+ String location = pathIterator.next();
+ try {
+ servlet = getServletAt(resolver, location, baseName);
+ } catch (SlingException se) {
+ log.warn("handleError: Problem resolving servlet at "
+ + location + "/" + baseName, se);
}
+ }
- // set the message properties
- request.setAttribute(ERROR_STATUS, new Integer(
- status));
- request.setAttribute(ERROR_MESSAGE, message);
-
- // the servlet name for a sendError handling is still stored
- // as the request attribute
- Object servletName = request.getAttribute(SLING_CURRENT_SERVLET_NAME);
- if (servletName instanceof String) {
- request.setAttribute(ERROR_SERVLET_NAME, servletName);
- }
+ if (servlet == null) {
+ servlet = getDefaultErrorServlet();
+ }
- if (handleError(servlet, request, response)) {
- return;
- }
+ // set the message properties
+ request.setAttribute(ERROR_STATUS, new Integer(status));
+ request.setAttribute(ERROR_MESSAGE, message);
+
+ // the servlet name for a sendError handling is still stored
+ // as the request attribute
+ Object servletName = request.getAttribute(SLING_CURRENT_SERVLET_NAME);
+ if (servletName instanceof String) {
+ request.setAttribute(ERROR_SERVLET_NAME, servletName);
}
- // get here, if we have no handler, let the status go up the chain
- // and if this causes and exception, so what ...
- response.sendError(status, message);
+ handleError(servlet, request, response);
}
- public void handleError(Throwable throwable, HttpServletRequest request,
- HttpServletResponse response) throws ServletException, IOException {
+ public void handleError(Throwable throwable,
+ SlingHttpServletRequest request, SlingHttpServletResponse response)
+ throws IOException {
// do not handle, if already handling ....
- if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) == null) {
-
- // find the error handler component
- Servlet servlet = null;
- Class<?> tClass = throwable.getClass();
- ErrorSlingHttpServletRequest eRequest = new ErrorSlingHttpServletRequest(
- request, "");
- while (servlet == null && tClass != Object.class) {
- eRequest.setMethod(tClass.getSimpleName());
- servlet = resolveServletOrScript(eRequest);
-
- // go to the base class
- tClass = tClass.getSuperclass();
- }
-
- if (servlet == null) {
- servlet = getDefaultErrorServlet();
- }
-
- // set the message properties
- request.setAttribute(SlingConstants.ERROR_EXCEPTION, throwable);
- request.setAttribute(SlingConstants.ERROR_EXCEPTION_TYPE,
- throwable.getClass());
- request.setAttribute(SlingConstants.ERROR_MESSAGE,
- throwable.getMessage());
-
- if (handleError(servlet, request, response)) {
- return;
+ if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) != null) {
+ log.error(
+ "handleError: Recursive invocation. Not further handling Throwable:",
+ throwable);
+ return;
+ }
+
+ // find the error handler component
+ Servlet servlet = null;
+ ResourceResolver resolver = request.getResourceResolver();
+
+ Class<?> tClass = throwable.getClass();
+ while (servlet == null && tClass != Object.class) {
+ String baseName = tClass.getSimpleName();
+
+ Iterator<String> pathIterator = PathSupport.getPathIterator(
+ ServletResolverConstants.ERROR_HANDLER_PATH, path);
+ while (servlet == null && pathIterator.hasNext()) {
+ String location = pathIterator.next();
+ try {
+ servlet = getServletAt(resolver, location, baseName);
+ } catch (SlingException se) {
+ log.warn("handleError: Problem resolving servlet at "
+ + location + "/" + baseName, se);
+ }
}
- }
- // get here, if we have no handler, let the throwable go up the chain
- if (throwable instanceof IOException) {
- throw (IOException) throwable;
- } else if (throwable instanceof ServletException) {
- throw (ServletException) throwable;
- } else if (throwable instanceof RuntimeException) {
- throw (RuntimeException) throwable;
- } else {
- throw new ServletException(throwable);
+ // go to the base class
+ tClass = tClass.getSuperclass();
}
- }
-
- // ---------- internal helper ---------------------------------------------
-
- Servlet resolveServletOrScript(SlingHttpServletRequest request) {
- // get the servlet by resource type
- Servlet servlet = getServlet(request.getResource().getResourceType());
- if (servlet != null) {
- return servlet;
+ if (servlet == null) {
+ servlet = getDefaultErrorServlet();
}
- // no typed servlet, so lets try scripting
- try {
- servlet = getScriptServlet(request);
- if (servlet != null) {
- return servlet;
- }
- } catch (SlingException se) {
- log.error("resolveServlet: Error trying to find script", se);
- }
+ // set the message properties
+ request.setAttribute(SlingConstants.ERROR_EXCEPTION, throwable);
+ request.setAttribute(SlingConstants.ERROR_EXCEPTION_TYPE,
+ throwable.getClass());
+ request.setAttribute(SlingConstants.ERROR_MESSAGE,
+ throwable.getMessage());
- // no script either
- return null;
+ handleError(servlet, request, response);
}
- private Servlet getScriptServlet(SlingHttpServletRequest request)
- throws SlingException {
- SlingScriptResolver ssr = scriptResolver;
- if (ssr != null) {
- SlingScript script = ssr.resolveScript(request);
- if (script != null) {
- return new SlingScriptServlet(script);
+ // ---------- internal helper ---------------------------------------------
+
+ private Servlet getServletAt(ResourceResolver resolver, String location,
+ String baseName) throws SlingException {
+ Servlet result = null;
+
+ Resource scriptRoot = resolver.getResource(location);
+ if (scriptRoot != null) {
+
+ log.debug("Looking for servlet with filename={} under {}",
+ baseName, scriptRoot.getURI());
+
+ // get the item and ensure it is a node
+ Iterator<Resource> children = resolver.listChildren(scriptRoot);
+ while (result == null && children.hasNext()) {
+ Resource resource = children.next();
+
+ // extract the name of the resource
+ int lastSlash = resource.getURI().lastIndexOf('/');
+ String name = resource.getURI().substring(lastSlash + 1);
+
+ // only accept it if it is equal to the base name or
+ // if there is just a single extension after the base name
+ if (name.startsWith(baseName)
+ && (name.length() == baseName.length() || name.lastIndexOf('.') == baseName.length())) {
+ result = resource.adaptTo(Servlet.class);
+ }
}
}
- return null;
+ return result;
}
private Servlet getCoreDefaultServlet() {
@@ -288,8 +344,8 @@
return defaultErrorServlet;
}
- private boolean handleError(Servlet errorHandler,
- HttpServletRequest request, HttpServletResponse response) {
+ private void handleError(Servlet errorHandler, HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
request.setAttribute(SlingConstants.ERROR_REQUEST_URI,
request.getRequestURI());
@@ -301,51 +357,52 @@
errorHandler.getServletConfig().getServletName());
}
- // find a component by
try {
errorHandler.service(request, response);
- return true;
+ } catch (IOException ioe) {
+ // forware the IOException
+ throw ioe;
} catch (Throwable t) {
- log.error("Cannot handle error", t);
+ log.error("Calling the error handler resulted in an error", t);
}
-
- return false;
}
// ---------- SCR Integration ----------------------------------------------
protected void activate(ComponentContext context) {
- this.context = context;
-
// empty path to begin with
path = null;
// from configuration if available
Dictionary<?, ?> properties = context.getProperties();
if (properties != null) {
- Object pathObject = properties.get(PROP_PATH);
- if (pathObject instanceof String[]) {
- this.path = (String[]) pathObject;
- for (int i = 0; i < this.path.length; i++) {
+ String[] tmpPath = OsgiUtil.toStringArray(properties.get(PROP_PATH));
+ if (tmpPath != null && tmpPath.length > 0) {
+ for (int i = 0; i < tmpPath.length; i++) {
// ensure leading slash
- if (!this.path[i].startsWith("/")) {
- this.path[i] = "/" + this.path[i];
+ if (!tmpPath[i].startsWith("/")) {
+ tmpPath[i] = "/" + tmpPath;
}
// ensure trailing slash
- if (!this.path[i].endsWith("/")) {
- this.path[i] += "/";
+ if (!tmpPath[i].endsWith("/")) {
+ tmpPath[i] += "/";
}
}
}
+ path = tmpPath;
}
-
+
+ if (path == null) {
+ path = new String[] { "/" };
+ }
+
Collection<ServiceReference> refs;
synchronized (this) {
refs = pendingServlets;
pendingServlets = new ArrayList<ServiceReference>();
-
+
// register servlets immediately from now on
this.context = context;
@@ -355,7 +412,7 @@
}
protected void deactivate(ComponentContext context) {
-
+
// destroy all active servlets
Collection<ServiceReference> refs;
synchronized (this) {
@@ -366,7 +423,7 @@
// destroy all servlets
destroyAllServlets(refs);
}
-
+
protected synchronized void bindServlet(ServiceReference reference) {
if (context == null) {
pendingServlets.add(reference);