You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2014/03/24 09:30:04 UTC
svn commit: r1580784 - in
/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal:
ScriptResource.java SlingServletResolver.java
Author: cziegeler
Date: Mon Mar 24 08:30:03 2014
New Revision: 1580784
URL: http://svn.apache.org/r1580784
Log:
SLING-3441 : Avoid shared resource resolver usage
Added:
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java (with props)
Modified:
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
Added: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java?rev=1580784&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java (added)
+++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java Mon Mar 24 08:30:03 2014
@@ -0,0 +1,163 @@
+/*
+ * 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.sling.servlets.resolver.internal;
+
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+
+import javax.servlet.Servlet;
+
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+
+/**
+ * ScriptResource is a resource wrapper of a resource fetched by a
+ * per thread resource resolver.
+ * As the script engines usually keep a reference to this resource
+ * for a longer time, the resource switches internally to
+ * a resource fetched by the shared resource resolver.
+ *
+ * We can't extend ResourceWrapper as its not possible to clear
+ * the wrapped resource field.
+ */
+public class ScriptResource extends AbstractResource {
+
+ private Resource activeResource;
+
+ private final ResourceResolver sharedResourceResolver;
+
+ private WeakReference<ResourceResolver> perThreadResourceResolver;
+
+ public ScriptResource(final Resource resource, final ResourceResolver sharedResourceResolver) {
+ this.perThreadResourceResolver = new WeakReference<ResourceResolver>(resource.getResourceResolver());
+ this.sharedResourceResolver = sharedResourceResolver;
+ this.activeResource = resource;
+ }
+
+ private Resource getActiveResource() {
+ if ( this.perThreadResourceResolver != null ) {
+ final ResourceResolver rr = this.perThreadResourceResolver.get();
+ if ( rr == null || !rr.isLive() ) {
+ this.perThreadResourceResolver = null;
+ this.activeResource = this.sharedResourceResolver.getResource(this.activeResource.getPath());
+ }
+ }
+ return this.activeResource;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceType()
+ */
+ public String getResourceType() {
+ return this.getActiveResource().getResourceType();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+ */
+ public String getResourceSuperType() {
+ return this.getActiveResource().getResourceSuperType();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+ */
+ public ResourceResolver getResourceResolver() {
+ return this.getActiveResource().getResourceResolver();
+ }
+
+ /**
+ * @see org.apache.sling.api.adapter.SlingAdaptable#adaptTo(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
+ if ( type == Servlet.class ) {
+ final Servlet s = (Servlet)super.adaptTo(type);
+ if ( s != null ) {
+ return (AdapterType)s;
+ }
+ }
+ return this.getActiveResource().adaptTo(type);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getPath()
+ */
+ public String getPath() {
+ return this.getActiveResource().getPath();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+ */
+ public ResourceMetadata getResourceMetadata() {
+ return this.getActiveResource().getResourceMetadata();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AbstractResource#getName()
+ */
+ @Override
+ public String getName() {
+ return this.getActiveResource().getName();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AbstractResource#getParent()
+ */
+ @Override
+ public Resource getParent() {
+ return this.getActiveResource().getParent();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AbstractResource#getChild(java.lang.String)
+ */
+ @Override
+ public Resource getChild(String relPath) {
+ return this.getActiveResource().getChild(relPath);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AbstractResource#listChildren()
+ */
+ @Override
+ public Iterator<Resource> listChildren() {
+ return this.getActiveResource().listChildren();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AbstractResource#getChildren()
+ */
+ @Override
+ public Iterable<Resource> getChildren() {
+ return this.getActiveResource().getChildren();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AbstractResource#isResourceType(java.lang.String)
+ */
+ @Override
+ public boolean isResourceType(String resourceType) {
+ return this.getActiveResource().isResourceType(resourceType);
+ }
+}
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ScriptResource.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java?rev=1580784&r1=1580783&r2=1580784&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java (original)
+++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java Mon Mar 24 08:30:03 2014
@@ -235,7 +235,7 @@ public class SlingServletResolver
Servlet servlet = null;
if ( type != null && type.length() > 0 ) {
- servlet = resolveServletInternal(request, type, scriptResolver);
+ servlet = resolveServletInternal(request, null, type, scriptResolver);
}
// last resort, use the core bundle default servlet
@@ -277,7 +277,7 @@ public class SlingServletResolver
}
final ResourceResolver scriptResolver = this.getScriptResourceResolver();
- final Servlet servlet = resolveServletInternal(resource, scriptName, scriptResolver);
+ final Servlet servlet = resolveServletInternal(null, resource, scriptName, scriptResolver);
// log the servlet found
if (LOGGER.isDebugEnabled()) {
@@ -303,7 +303,7 @@ public class SlingServletResolver
}
final ResourceResolver scriptResolver = this.getScriptResourceResolver();
- final Servlet servlet = resolveServletInternal((Resource)null, scriptName, scriptResolver);
+ final Servlet servlet = resolveServletInternal(null, (Resource)null, scriptName, scriptResolver);
// log the servlet found
if (LOGGER.isDebugEnabled()) {
@@ -317,40 +317,26 @@ public class SlingServletResolver
return servlet;
}
- /** Internal method to resolve a servlet. */
- private Servlet resolveServletInternal(
- final Resource resource,
- final String scriptName,
- final ResourceResolver resolver) {
- Servlet servlet = null;
-
- // first check whether the type of a resource is the absolute
- // path of a servlet (or script)
- if (scriptName.charAt(0) == '/') {
- final String scriptPath = ResourceUtil.normalize(scriptName);
- if ( this.isPathAllowed(scriptPath) ) {
- final Resource res = resolver.getResource(scriptPath);
- if (res != null) {
- servlet = res.adaptTo(Servlet.class);
- }
- if (servlet != null && LOGGER.isDebugEnabled()) {
- LOGGER.debug("Servlet {} found using absolute resource type {}", RequestUtil.getServletName(servlet),
- scriptName);
- }
- }
- }
- if ( servlet == null ) {
- // the resource type is not absolute, so lets go for the deep search
- final NamedScriptResourceCollector locationUtil = NamedScriptResourceCollector.create(scriptName, resource, this.executionPaths);
- servlet = getServletInternal(locationUtil, null, resolver);
-
- if (LOGGER.isDebugEnabled() && servlet != null) {
- LOGGER.debug("resolveServlet returns servlet {}", RequestUtil.getServletName(servlet));
- }
- }
- return servlet;
-
+ /**
+ * Get the servlet for the resource.
+ */
+ private Servlet getServlet(final Resource scriptResource) {
+ // no resource -> no servlet
+ if ( scriptResource == null ) {
+ return null;
+ }
+ // if resource is fetched using shared resource resolver
+ // or resource is a servlet resource, just adapt to servlet
+ if ( scriptResource.getResourceResolver() == this.sharedScriptResolver
+ || "sling/bundle/resource".equals(scriptResource.getResourceSuperType()) ) {
+ return scriptResource.adaptTo(Servlet.class);
+ }
+ // return a resource wrapper to make sure the implementation
+ // switches from the per thread resource resolver to the shared once
+ // the per thread resource resolver is closed
+ return new ScriptResource(scriptResource, this.sharedScriptResolver).adaptTo(Servlet.class);
}
+
// ---------- ScriptResolver interface ------------------------------------
/**
@@ -366,7 +352,7 @@ public class SlingServletResolver
final String path = ResourceUtil.normalize(name);
if ( this.isPathAllowed(path) ) {
final Resource resource = resourceResolver.getResource(path);
- if (resource != null) {
+ if ( resource != null ) {
script = resource.adaptTo(SlingScript.class);
}
}
@@ -561,42 +547,48 @@ public class SlingServletResolver
return res;
}
- /**
+ /**
* Resolve an appropriate servlet for a given request and resource type
* using the provided ResourceResolver
*/
private Servlet resolveServletInternal(final SlingHttpServletRequest request,
- final String type,
+ final Resource resource,
+ final String scriptName,
final ResourceResolver resolver) {
Servlet servlet = null;
// first check whether the type of a resource is the absolute
// path of a servlet (or script)
- if (type.charAt(0) == '/') {
- String scriptPath = ResourceUtil.normalize(type);
+ if (scriptName.charAt(0) == '/') {
+ final String scriptPath = ResourceUtil.normalize(scriptName);
if ( this.isPathAllowed(scriptPath) ) {
final Resource res = resolver.getResource(scriptPath);
- if (res != null) {
- servlet = res.adaptTo(Servlet.class);
- }
+ servlet = this.getServlet(res);
if (servlet != null && LOGGER.isDebugEnabled()) {
LOGGER.debug("Servlet {} found using absolute resource type {}", RequestUtil.getServletName(servlet),
- type);
+ scriptName);
}
} else {
- request.getRequestProgressTracker().log(
- "Will not look for a servlet at {0} as it is not in the list of allowed paths",
- type
- );
+ if ( request != null ) {
+ request.getRequestProgressTracker().log(
+ "Will not look for a servlet at {0} as it is not in the list of allowed paths",
+ scriptName
+ );
+ }
}
}
if ( servlet == null ) {
// the resource type is not absolute, so lets go for the deep search
- final ResourceCollector locationUtil = ResourceCollector.create(request, this.executionPaths, this.defaultExtensions);
+ final AbstractResourceCollector locationUtil;
+ if ( request != null ) {
+ locationUtil = ResourceCollector.create(request, this.executionPaths, this.defaultExtensions);
+ } else {
+ locationUtil = NamedScriptResourceCollector.create(scriptName, resource, this.executionPaths);
+ }
servlet = getServletInternal(locationUtil, request, resolver);
if (servlet != null && LOGGER.isDebugEnabled()) {
- LOGGER.debug("getServlet returns servlet {}", RequestUtil.getServletName(servlet));
+ LOGGER.debug("getServletInternal returns servlet {}", RequestUtil.getServletName(servlet));
}
}
return servlet;
@@ -648,12 +640,10 @@ public class SlingServletResolver
}
boolean hasOptingServlet = false;
- for (Resource candidateResource : candidates) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Checking if candidate resource {} adapts to servlet and accepts request", candidateResource
+ for (final Resource candidateResource : candidates) {
+ LOGGER.debug("Checking if candidate resource {} adapts to servlet and accepts request", candidateResource
.getPath());
- }
- Servlet candidate = candidateResource.adaptTo(Servlet.class);
+ Servlet candidate = this.getServlet(candidateResource);
if (candidate != null) {
final boolean isOptingServlet = candidate instanceof OptingServlet;
boolean servletAcceptsRequest = !isOptingServlet || (request != null && ((OptingServlet) candidate).accepts(request));
@@ -673,13 +663,9 @@ public class SlingServletResolver
if (isOptingServlet) {
hasOptingServlet = true;
}
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Candidate {} does not accept request, ignored", candidateResource.getPath());
- }
+ LOGGER.debug("Candidate {} does not accept request, ignored", candidateResource.getPath());
} else {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Candidate {} does not adapt to a servlet, ignored", candidateResource.getPath());
- }
+ LOGGER.debug("Candidate {} does not adapt to a servlet, ignored", candidateResource.getPath());
}
}
@@ -696,9 +682,9 @@ public class SlingServletResolver
if (defaultServlet == null) {
try {
Servlet servlet = new DefaultServlet();
- servlet.init(new SlingServletConfig(servletContext, null, "Sling Core Default Servlet"));
+ servlet.init(new SlingServletConfig(servletContext, null, "Apache Sling Core Default Servlet"));
defaultServlet = servlet;
- } catch (ServletException se) {
+ } catch (final ServletException se) {
LOGGER.error("Failed to initialize default servlet", se);
}
}
@@ -851,6 +837,9 @@ public class SlingServletResolver
this.cacheSize = 0;
}
+ // setup default servlet
+ this.getDefaultServlet();
+
// and finally register as event listener
this.eventHandlerReg = context.getBundleContext().registerService(EventHandler.class.getName(), this,
properties);