Return-Path: X-Original-To: apmail-sling-commits-archive@www.apache.org Delivered-To: apmail-sling-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6FC309574 for ; Thu, 14 Jun 2012 09:52:37 +0000 (UTC) Received: (qmail 94731 invoked by uid 500); 14 Jun 2012 09:52:37 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 94644 invoked by uid 500); 14 Jun 2012 09:52:36 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 94469 invoked by uid 99); 14 Jun 2012 09:52:36 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 14 Jun 2012 09:52:36 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 14 Jun 2012 09:52:32 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 00EC623889D5; Thu, 14 Jun 2012 09:52:12 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1350169 [2/5] - in /sling/trunk/bundles/resourceresolver/src: main/java/org/apache/sling/resourceresolver/impl/ main/java/org/apache/sling/resourceresolver/impl/console/ main/java/org/apache/sling/resourceresolver/impl/helper/ main/java/or... Date: Thu, 14 Jun 2012 09:52:09 -0000 To: commits@sling.apache.org From: cziegeler@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120614095212.00EC623889D5@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java?rev=1350169&r1=1350168&r2=1350169&view=diff ============================================================================== --- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java (original) +++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java Thu Jun 14 09:52:08 2012 @@ -16,65 +16,52 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.sling.jcr.resource.internal; +package org.apache.sling.resourceresolver.impl; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.jcr.Credentials; import javax.jcr.NamespaceException; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.Value; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; -import javax.jcr.query.Row; -import javax.jcr.query.RowIterator; import javax.servlet.http.HttpServletRequest; -import org.apache.sling.adapter.SlingAdaptable; import org.apache.sling.adapter.annotations.Adaptable; import org.apache.sling.adapter.annotations.Adapter; import org.apache.sling.api.SlingException; +import org.apache.sling.api.adapter.SlingAdaptable; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.NonExistingResource; -import org.apache.sling.api.resource.QuerySyntaxException; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceNotFoundException; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.api.resource.ResourceWrapper; import org.apache.sling.api.resource.ValueMap; -import org.apache.sling.jcr.resource.JcrResourceConstants; -import org.apache.sling.jcr.resource.JcrResourceUtil; -import org.apache.sling.jcr.resource.internal.helper.MapEntry; -import org.apache.sling.jcr.resource.internal.helper.RedirectResource; -import org.apache.sling.jcr.resource.internal.helper.ResourceIterator; -import org.apache.sling.jcr.resource.internal.helper.ResourcePathIterator; -import org.apache.sling.jcr.resource.internal.helper.URI; -import org.apache.sling.jcr.resource.internal.helper.URIException; -import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResourceIterator; -import org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderEntry; -import org.apache.sling.jcr.resource.internal.helper.starresource.StarResource; +import org.apache.sling.resourceresolver.impl.helper.RedirectResource; +import org.apache.sling.resourceresolver.impl.helper.ResourceIterator; +import org.apache.sling.resourceresolver.impl.helper.ResourceIteratorDecorator; +import org.apache.sling.resourceresolver.impl.helper.ResourcePathIterator; +import org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext; +import org.apache.sling.resourceresolver.impl.helper.StarResource; +import org.apache.sling.resourceresolver.impl.helper.URI; +import org.apache.sling.resourceresolver.impl.helper.URIException; +import org.apache.sling.resourceresolver.impl.mapping.MapEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Adaptable(adaptableClass=ResourceResolver.class, adapters={ @Adapter(Session.class) }) -public class JcrResourceResolver - extends SlingAdaptable implements ResourceResolver { +@Adaptable(adaptableClass = ResourceResolver.class, adapters = { @Adapter(Session.class) }) +public class ResourceResolverImpl extends SlingAdaptable implements ResourceResolver { - /** default logger */ - private final Logger LOGGER = LoggerFactory.getLogger(JcrResourceResolver.class); + /** Default logger */ + private final Logger logger = LoggerFactory.getLogger(ResourceResolverImpl.class); private static final String MANGLE_NAMESPACE_IN_SUFFIX = "_"; @@ -88,17 +75,10 @@ public class JcrResourceResolver private static final String MANGLE_NAMESPACE_OUT = "/([^:/]+):"; - public static final String PROP_REG_EXP = "sling:match"; public static final String PROP_REDIRECT_INTERNAL = "sling:internalRedirect"; - public static final String PROP_ALIAS = "sling:alias"; - - public static final String PROP_REDIRECT_EXTERNAL = "sling:redirect"; - - public static final String PROP_REDIRECT_EXTERNAL_STATUS = "sling:status"; - - public static final String PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS = "sling:redirectStatus"; + private static final String PROP_ALIAS = "sling:alias"; // The suffix of a resource being a content node of some parent // such as nt:file. The slash is included to prevent false @@ -106,87 +86,53 @@ public class JcrResourceResolver // "xyzjcr:content" private static final String JCR_CONTENT_LEAF = "/jcr:content"; - @SuppressWarnings("deprecation") - private static final String DEFAULT_QUERY_LANGUAGE = Query.XPATH; - - /** column name for node path */ - private static final String QUERY_COLUMN_PATH = "jcr:path"; - - /** column name for score value */ - private static final String QUERY_COLUMN_SCORE = "jcr:score"; - - /** The root provider for the resource tree. */ - private final JcrResourceProviderEntry rootProvider; - /** The factory which created this resource resolver. */ - private final JcrResourceResolverFactoryImpl factory; - - /** Is this a resource resolver for an admin? */ - private final boolean isAdmin; - - /** The original authentication information - this is used for further resource resolver creations. */ - private final Map originalAuthInfo; - - /** Resolvers for different workspaces. */ - private Map createdResolvers; + private final ResourceResolverFactoryImpl factory; /** Closed marker. */ private volatile boolean closed = false; - /** a resolver with the workspace which was specifically requested via a request attribute. */ - private ResourceResolver requestBoundResolver; - - private final boolean useMultiWorkspaces; + /** Resource resolver context. */ + private final ResourceResolverContext context; - public JcrResourceResolver(final JcrResourceProviderEntry rootProvider, - final JcrResourceResolverFactoryImpl factory, - final boolean isAdmin, - final Map originalAuthInfo, - boolean useMultiWorkspaces) { - this.rootProvider = rootProvider; + /** + * The resource resolver context. + */ + public ResourceResolverImpl(final ResourceResolverFactoryImpl factory, final ResourceResolverContext ctx) { this.factory = factory; - this.isAdmin = isAdmin; - this.originalAuthInfo = originalAuthInfo; - this.useMultiWorkspaces = useMultiWorkspaces; + this.context = ctx; } /** * @see org.apache.sling.api.resource.ResourceResolver#clone(Map) */ - public ResourceResolver clone(Map authenticationInfo) - throws LoginException { - + public ResourceResolver clone(final Map authenticationInfo) + throws LoginException { // ensure resolver is still live checkClosed(); // create the merged map - Map newAuthenticationInfo = new HashMap(); - if (originalAuthInfo != null) { - newAuthenticationInfo.putAll(originalAuthInfo); + final Map newAuthenticationInfo = new HashMap(); + if (this.context.getAuthenticationInfo() != null) { + newAuthenticationInfo.putAll(this.context.getAuthenticationInfo()); } if (authenticationInfo != null) { newAuthenticationInfo.putAll(authenticationInfo); } - // get an administrative resolver if this resolver isAdmin unless - // credentials and/or user name are present in the credentials and/or - // a session is present - if (isAdmin - && !(newAuthenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS) instanceof Credentials) - && !(newAuthenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_SESSION) instanceof Session) - && !(newAuthenticationInfo.get(ResourceResolverFactory.USER) instanceof String)) { - return factory.getAdministrativeResourceResolver(newAuthenticationInfo); - } + // create new context + final ResourceResolverContext newContext = new ResourceResolverContext(this.context.isAdmin(), newAuthenticationInfo); + this.factory.getRootProviderEntry().loginToRequiredFactories(newContext); // create a regular resource resolver - return factory.getResourceResolver(newAuthenticationInfo); + return new ResourceResolverImpl(this.factory, newContext); } /** * @see org.apache.sling.api.resource.ResourceResolver#isLive() */ public boolean isLive() { - return !this.closed && getSession().isLive(); + return !this.closed && this.context.isLive(); } /** @@ -195,46 +141,7 @@ public class JcrResourceResolver public void close() { if (!this.closed) { this.closed = true; - closeCreatedResolvers(); - closeSession(); - } - } - - /** - * Closes the session underlying this resource resolver. This method is - * called by the {@link #close()} method. - *

- * Extensions can overwrite this method to do other work (or not close the - * session at all). Handle with care ! - */ - protected void closeSession() { - try { - getSession().logout(); - } catch (Throwable t) { - LOGGER.debug( - "closeSession: Unexpected problem closing the session; ignoring", - t); - } - } - - /** - * Closes any helper resource resolver created while this resource resolver - * was used. - *

- * Extensions can overwrite this method to do other work (or not close the - * created resource resovlers at all). Handle with care ! - */ - protected void closeCreatedResolvers() { - if (this.createdResolvers != null) { - for (final ResourceResolver resolver : createdResolvers.values()) { - try { - resolver.close(); - } catch (Throwable t) { - LOGGER.debug( - "closeCreatedResolvers: Unexpected problem closing the created resovler " - + resolver + "; ignoring", t); - } - } + this.context.close(); } } @@ -243,17 +150,19 @@ public class JcrResourceResolver * cleaned up before it is being collected by the garbage collector because * it is not referred to any more. */ - protected void finalize() { + protected void finalize() throws Throwable { close(); + super.finalize(); } /** * Check if the resource resolver is already closed. * - * @throws IllegalStateException If the resolver is already closed + * @throws IllegalStateException + * If the resolver is already closed */ private void checkClosed() { - if ( this.closed ) { + if (this.closed) { throw new IllegalStateException("Resource resolver is already closed."); } } @@ -265,65 +174,19 @@ public class JcrResourceResolver */ public Iterator getAttributeNames() { checkClosed(); - final Set names = new HashSet(); - names.addAll(Arrays.asList(getSession().getAttributeNames())); - if (originalAuthInfo != null) { - names.addAll(originalAuthInfo.keySet()); - } - return new Iterator() { - final Iterator keys = names.iterator(); - - String nextKey = seek(); - - private String seek() { - while (keys.hasNext()) { - final String key = keys.next(); - if (JcrResourceResolverFactoryImpl.isAttributeVisible(key)) { - return key; - } - } - return null; - } - - public boolean hasNext() { - return nextKey != null; - } - - public String next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - String toReturn = nextKey; - nextKey = seek(); - return toReturn; - } - - public void remove() { - throw new UnsupportedOperationException("remove"); - } - }; + return this.factory.getRootProviderEntry().getAttributeNames(this.context); } /** * @see org.apache.sling.api.resource.ResourceResolver#getAttribute(String) */ - public Object getAttribute(String name) { + public Object getAttribute(final String name) { + checkClosed(); if (name == null) { throw new NullPointerException("name"); } - if (JcrResourceResolverFactoryImpl.isAttributeVisible(name)) { - final Object sessionAttr = getSession().getAttribute(name); - if (sessionAttr != null) { - return sessionAttr; - } - if (originalAuthInfo != null) { - return originalAuthInfo.get(name); - } - } - - // not a visible attribute - return null; + return this.factory.getRootProviderEntry().getAttribute(this.context, name); } // ---------- resolving resources @@ -331,7 +194,7 @@ public class JcrResourceResolver /** * @see org.apache.sling.api.resource.ResourceResolver#resolve(java.lang.String) */ - public Resource resolve(String absPath) { + public Resource resolve(final String absPath) { checkClosed(); return resolve(null, absPath); } @@ -339,82 +202,40 @@ public class JcrResourceResolver /** * @see org.apache.sling.api.resource.ResourceResolver#resolve(javax.servlet.http.HttpServletRequest) */ - public Resource resolve(HttpServletRequest request) { + @SuppressWarnings("javadoc") + public Resource resolve(final HttpServletRequest request) { checkClosed(); // throws NPE if request is null as required return resolve(request, request.getPathInfo()); } /** - * @see org.apache.sling.api.resource.ResourceResolver#resolve(javax.servlet.http.HttpServletRequest, java.lang.String) + * @see org.apache.sling.api.resource.ResourceResolver#resolve(javax.servlet.http.HttpServletRequest, + * java.lang.String) */ public Resource resolve(final HttpServletRequest request, String absPath) { checkClosed(); - String workspaceName = null; - // make sure abspath is not null and is absolute if (absPath == null) { absPath = "/"; } else if (!absPath.startsWith("/")) { - if (useMultiWorkspaces) { - final int wsSepPos = absPath.indexOf(":/"); - if (wsSepPos != -1) { - workspaceName = absPath.substring(0, wsSepPos); - absPath = absPath.substring(wsSepPos + 1); - } else { - absPath = "/" + absPath; - } - } else { - absPath = "/" + absPath; - } + absPath = "/" + absPath; } // check for special namespace prefix treatment absPath = unmangleNamespaces(absPath); - if (useMultiWorkspaces) { - if (workspaceName == null) { - // check for workspace info from request - workspaceName = (request == null ? null : - (String)request.getAttribute(ResourceResolver.REQUEST_ATTR_WORKSPACE_INFO)); - } - if (workspaceName != null && !workspaceName.equals(getSession().getWorkspace().getName())) { - LOGGER.debug("Delegating resolving to resolver for workspace {}", workspaceName); - try { - final ResourceResolver wsResolver = getResolverForWorkspace(workspaceName); - requestBoundResolver = wsResolver; - return wsResolver.resolve(request, absPath); - } catch (LoginException e) { - // requested a resource in a workspace I don't have access to. - // we treat this as a not found resource - LOGGER.debug( - "resolve: Path {} does not resolve, returning NonExistingResource", - absPath); - - final Resource res = new NonExistingResource(this, absPath); - // SLING-864: if the path contains a dot we assume this to be - // the start for any selectors, extension, suffix, which may be - // used for further request processing. - int index = absPath.indexOf('.'); - if (index != -1) { - res.getResourceMetadata().setResolutionPathInfo(absPath.substring(index)); - } - return this.factory.getResourceDecoratorTracker().decorate(res, workspaceName); - } - } - } // Assume http://localhost:80 if request is null String[] realPathList = { absPath }; String requestPath; if (request != null) { - requestPath = getMapPath(request.getScheme(), - request.getServerName(), request.getServerPort(), absPath); + requestPath = getMapPath(request.getScheme(), request.getServerName(), request.getServerPort(), absPath); } else { requestPath = getMapPath("http", "localhost", 80, absPath); } - LOGGER.debug("resolve: Resolving request path {}", requestPath); + logger.debug("resolve: Resolving request path {}", requestPath); // loop while finding internal or external redirect into the // content out of the virtual host mapping tree @@ -425,41 +246,36 @@ public class JcrResourceResolver String[] mappedPath = null; final Iterator mapEntriesIterator = this.factory.getMapEntries().getResolveMapsIterator(requestPath); - while ( mapEntriesIterator.hasNext() ) { + while (mapEntriesIterator.hasNext()) { final MapEntry mapEntry = mapEntriesIterator.next(); mappedPath = mapEntry.replace(requestPath); if (mappedPath != null) { - if ( LOGGER.isDebugEnabled() ) { - LOGGER.debug( - "resolve: MapEntry {} matches, mapped path is {}", - mapEntry, Arrays.toString(mappedPath)); + if (logger.isDebugEnabled()) { + logger.debug("resolve: MapEntry {} matches, mapped path is {}", mapEntry, Arrays.toString(mappedPath)); } if (mapEntry.isInternal()) { // internal redirect - LOGGER.debug("resolve: Redirecting internally"); + logger.debug("resolve: Redirecting internally"); break; } // external redirect - LOGGER.debug("resolve: Returning external redirect"); + logger.debug("resolve: Returning external redirect"); return this.factory.getResourceDecoratorTracker().decorate( - new RedirectResource(this, absPath, mappedPath[0], - mapEntry.getStatus()), workspaceName); + new RedirectResource(this, absPath, mappedPath[0], mapEntry.getStatus())); } } // if there is no virtual host based path mapping, abort // and use the original realPath if (mappedPath == null) { - LOGGER.debug( - "resolve: Request path {} does not match any MapEntry", - requestPath); + logger.debug("resolve: Request path {} does not match any MapEntry", requestPath); break; } // if the mapped path is not an URL, use this path to continue if (!mappedPath[0].contains("://")) { - LOGGER.debug("resolve: Mapped path is for resource tree"); + logger.debug("resolve: Mapped path is for resource tree"); realPathList = mappedPath; break; } @@ -468,13 +284,10 @@ public class JcrResourceResolver // resolve that URI now, using the URI's path as the real path try { final URI uri = new URI(mappedPath[0], false); - requestPath = getMapPath(uri.getScheme(), uri.getHost(), - uri.getPort(), uri.getPath()); + requestPath = getMapPath(uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath()); realPathList = new String[] { uri.getPath() }; - LOGGER.debug( - "resolve: Mapped path is an URL, using new request path {}", - requestPath); + logger.debug("resolve: Mapped path is an URL, using new request path {}", requestPath); } catch (final URIException use) { // TODO: log and fail throw new ResourceNotFoundException(absPath); @@ -487,12 +300,11 @@ public class JcrResourceResolver Resource res = null; for (int i = 0; res == null && i < realPathList.length; i++) { - String realPath = realPathList[i]; + final String realPath = realPathList[i]; // first check whether the requested resource is a StarResource if (StarResource.appliesTo(realPath)) { - LOGGER.debug("resolve: Mapped path {} is a Star Resource", - realPath); + logger.debug("resolve: Mapped path {} is a Star Resource", realPath); res = new StarResource(this, ensureAbsPath(realPath)); } else { @@ -500,16 +312,14 @@ public class JcrResourceResolver if (realPath.startsWith("/")) { // let's check it with a direct access first - LOGGER.debug("resolve: Try absolute mapped path {}", realPath); + logger.debug("resolve: Try absolute mapped path {}", realPath); res = resolveInternal(realPath); } else { - String[] searchPath = getSearchPath(); + final String[] searchPath = getSearchPath(); for (int spi = 0; res == null && spi < searchPath.length; spi++) { - LOGGER.debug( - "resolve: Try relative mapped path with search path entry {}", - searchPath[spi]); + logger.debug("resolve: Try relative mapped path with search path entry {}", searchPath[spi]); res = resolveInternal(searchPath[spi] + realPath); } @@ -520,28 +330,27 @@ public class JcrResourceResolver // if no resource has been found, use a NonExistingResource if (res == null) { - String resourcePath = ensureAbsPath(realPathList[0]); - LOGGER.debug( - "resolve: Path {} does not resolve, returning NonExistingResource at {}", - absPath, resourcePath); + final String resourcePath = ensureAbsPath(realPathList[0]); + logger.debug("resolve: Path {} does not resolve, returning NonExistingResource at {}", absPath, resourcePath); res = new NonExistingResource(this, resourcePath); // SLING-864: if the path contains a dot we assume this to be // the start for any selectors, extension, suffix, which may be // used for further request processing. - int index = resourcePath.indexOf('.'); + final int index = resourcePath.indexOf('.'); if (index != -1) { res.getResourceMetadata().setResolutionPathInfo(resourcePath.substring(index)); } } else { - LOGGER.debug("resolve: Path {} resolves to Resource {}", absPath, res); + logger.debug("resolve: Path {} resolves to Resource {}", absPath, res); } - return this.factory.getResourceDecoratorTracker().decorate(res, workspaceName); + return this.factory.getResourceDecoratorTracker().decorate(res); } /** * calls map(HttpServletRequest, String) as map(null, resourcePath) + * * @see org.apache.sling.api.resource.ResourceResolver#map(java.lang.String) */ public String map(final String resourcePath) { @@ -550,11 +359,12 @@ public class JcrResourceResolver } /** - * full implementation - * - apply sling:alias from the resource path - * - apply /etc/map mappings (inkl. config backwards compat) - * - return absolute uri if possible - * @see org.apache.sling.api.resource.ResourceResolver#map(javax.servlet.http.HttpServletRequest, java.lang.String) + * full implementation - apply sling:alias from the resource path - apply + * /etc/map mappings (inkl. config backwards compat) - return absolute uri + * if possible + * + * @see org.apache.sling.api.resource.ResourceResolver#map(javax.servlet.http.HttpServletRequest, + * java.lang.String) */ public String map(final HttpServletRequest request, final String resourcePath) { checkClosed(); @@ -571,83 +381,38 @@ public class JcrResourceResolver if (fragmentQueryMark >= 0) { fragmentQuery = resourcePath.substring(fragmentQueryMark); mappedPath = resourcePath.substring(0, fragmentQueryMark); - LOGGER.debug("map: Splitting resource path '{}' into '{}' and '{}'", - new Object[] { resourcePath, mappedPath, fragmentQuery }); + logger.debug("map: Splitting resource path '{}' into '{}' and '{}'", new Object[] { resourcePath, mappedPath, + fragmentQuery }); } else { fragmentQuery = null; mappedPath = resourcePath; } - // cut off scheme and host, if the same as requested final String schemehostport; final String schemePrefix; if (request != null) { - schemehostport = MapEntry.getURI(request.getScheme(), - request.getServerName(), request.getServerPort(), "/"); + schemehostport = MapEntry.getURI(request.getScheme(), request.getServerName(), request.getServerPort(), "/"); schemePrefix = request.getScheme().concat("://"); - LOGGER.debug( - "map: Mapping path {} for {} (at least with scheme prefix {})", - new Object[] { resourcePath, schemehostport, schemePrefix }); + logger.debug("map: Mapping path {} for {} (at least with scheme prefix {})", new Object[] { resourcePath, + schemehostport, schemePrefix }); } else { schemehostport = null; schemePrefix = null; - LOGGER.debug("map: Mapping path {} for default", resourcePath); - - } + logger.debug("map: Mapping path {} for default", resourcePath); - Resource res = null; - String workspaceName = null; - - if (useMultiWorkspaces) { - final int wsSepPos = mappedPath.indexOf(":/"); - if (wsSepPos != -1) { - workspaceName = mappedPath.substring(0, wsSepPos); - if (workspaceName.equals(getSession().getWorkspace().getName())) { - mappedPath = mappedPath.substring(wsSepPos + 1); - } else { - try { - JcrResourceResolver wsResolver = getResolverForWorkspace(workspaceName); - mappedPath = mappedPath.substring(wsSepPos + 1); - res = wsResolver.resolveInternal(mappedPath); - } catch (LoginException e) { - // requested a resource in a workspace I don't have access to. - // we treat this as a not found resource - return null; - } - } - } else { - // check for workspace info in request - workspaceName = (request == null ? null : - (String)request.getAttribute(ResourceResolver.REQUEST_ATTR_WORKSPACE_INFO)); - if ( workspaceName != null && !workspaceName.equals(getSession().getWorkspace().getName())) { - LOGGER.debug("Delegating resolving to resolver for workspace {}", workspaceName); - try { - JcrResourceResolver wsResolver = getResolverForWorkspace(workspaceName); - res = wsResolver.resolveInternal(mappedPath); - } catch (LoginException e) { - // requested a resource in a workspace I don't have access to. - // we treat this as a not found resource - return null; - } - - } - } } - if (res == null) { - res = resolveInternal(mappedPath); - } + final Resource res = resolveInternal(mappedPath); if (res != null) { // keep, what we might have cut off in internal resolution final String resolutionPathInfo = res.getResourceMetadata().getResolutionPathInfo(); - LOGGER.debug("map: Path maps to resource {} with path info {}", res, - resolutionPathInfo); + logger.debug("map: Path maps to resource {} with path info {}", res, resolutionPathInfo); // find aliases for segments. we can't walk the parent chain // since the request session might not have permissions to @@ -656,9 +421,9 @@ public class JcrResourceResolver Resource current = res; String path = res.getPath(); - while ( path != null ) { + while (path != null) { String alias = null; - if ( current != null && !path.endsWith(JCR_CONTENT_LEAF)) { + if (current != null && !path.endsWith(JCR_CONTENT_LEAF)) { alias = getProperty(current, PROP_ALIAS); } if (alias == null || alias.length() == 0) { @@ -666,9 +431,9 @@ public class JcrResourceResolver } names.add(alias); path = ResourceUtil.getParent(path); - if ( "/".equals(path) ) { + if ("/".equals(path)) { path = null; - } else if ( path != null ) { + } else if (path != null) { current = res.getResourceResolver().resolve(path); } } @@ -694,7 +459,7 @@ public class JcrResourceResolver // and then we have the mapped path to work on mappedPath = buf.toString(); - LOGGER.debug("map: Alias mapping resolves to path {}", mappedPath); + logger.debug("map: Alias mapping resolves to path {}", mappedPath); } @@ -703,7 +468,7 @@ public class JcrResourceResolver final String[] mappedPaths = mapEntry.replace(mappedPath); if (mappedPaths != null) { - LOGGER.debug("map: Match for Entry {}", mapEntry); + logger.debug("map: Match for Entry {}", mapEntry); mappedPathIsUrl = !mapEntry.isInternal(); @@ -715,12 +480,9 @@ public class JcrResourceResolver if (candidate.startsWith(schemehostport)) { mappedPath = candidate.substring(schemehostport.length() - 1); mappedPathIsUrl = false; - LOGGER.debug( - "map: Found host specific mapping {} resolving to {}", - candidate, mappedPath); + logger.debug("map: Found host specific mapping {} resolving to {}", candidate, mappedPath); break; - } else if (candidate.startsWith(schemePrefix) - && mappedPath == null) { + } else if (candidate.startsWith(schemePrefix) && mappedPath == null) { mappedPath = candidate; } } @@ -736,9 +498,7 @@ public class JcrResourceResolver } - LOGGER.debug( - "resolve: MapEntry {} matches, mapped path is {}", - mapEntry, mappedPath); + logger.debug("resolve: MapEntry {} matches, mapped path is {}", mapEntry, mappedPath); break; } @@ -753,28 +513,26 @@ public class JcrResourceResolver try { // use commons-httpclient's URI instead of java.net.URI, as it can // actually accept *unescaped* URIs, such as the "mappedPath" and - // return them in proper escaped form, including the path, via toString() - URI uri = new URI(mappedPath, false); + // return them in proper escaped form, including the path, via + // toString() + final URI uri = new URI(mappedPath, false); // 1. mangle the namespaces in the path String path = mangleNamespaces(uri.getPath()); // 2. prepend servlet context path if we have a request - if (request != null && request.getContextPath() != null - && request.getContextPath().length() > 0) { + if (request != null && request.getContextPath() != null && request.getContextPath().length() > 0) { path = request.getContextPath().concat(path); } // update the path part of the URI uri.setPath(path); mappedPath = uri.toString(); - } catch (URIException e) { - LOGGER.warn("map: Unable to mangle namespaces for " + mappedPath - + " returning unmangled", e); + } catch (final URIException e) { + logger.warn("map: Unable to mangle namespaces for " + mappedPath + " returning unmangled", e); } - LOGGER.debug("map: Returning URL {} as mapping for path {}", - mappedPath, resourcePath); + logger.debug("map: Returning URL {} as mapping for path {}", mappedPath, resourcePath); // reappend fragment and/or query if (fragmentQuery != null) { @@ -802,36 +560,12 @@ public class JcrResourceResolver public Resource getResource(String path) { checkClosed(); - if (useMultiWorkspaces) { - final int wsSepPos = path.indexOf(":/"); - if (wsSepPos != -1) { - final String workspaceName = path.substring(0, wsSepPos); - if (workspaceName.equals(getSession().getWorkspace().getName())) { - path = path.substring(wsSepPos + 1); - } else { - try { - ResourceResolver wsResolver = getResolverForWorkspace(workspaceName); - return wsResolver.getResource(path.substring(wsSepPos + 1)); - } catch (LoginException e) { - // requested a resource in a workspace I don't have access to. - // we treat this as a not found resource - return null; - } - } - } - } - // if the path is absolute, normalize . and .. segements and get res if (path.startsWith("/")) { path = ResourceUtil.normalize(path); Resource result = (path != null) ? getResourceInternal(path) : null; - if ( result != null ) { - String workspacePrefix = null; - if ( useMultiWorkspaces && !getSession().getWorkspace().getName().equals(this.factory.getDefaultWorkspaceName()) ) { - workspacePrefix = getSession().getWorkspace().getName(); - } - - result = this.factory.getResourceDecoratorTracker().decorate(result, workspacePrefix); + if (result != null) { + result = this.factory.getResourceDecoratorTracker().decorate(result); return result; } return null; @@ -839,10 +573,10 @@ public class JcrResourceResolver // otherwise we have to apply the search path // (don't use this.getSearchPath() to save a few cycle for not cloning) - String[] paths = factory.getSearchPath(); + final String[] paths = factory.getSearchPath(); if (paths != null) { - for (String prefix : factory.getSearchPath()) { - Resource res = getResource(prefix + path); + for (final String prefix : factory.getSearchPath()) { + final Resource res = getResource(prefix + path); if (res != null) { return res; } @@ -854,9 +588,10 @@ public class JcrResourceResolver } /** - * @see org.apache.sling.api.resource.ResourceResolver#getResource(org.apache.sling.api.resource.Resource, java.lang.String) + * @see org.apache.sling.api.resource.ResourceResolver#getResource(org.apache.sling.api.resource.Resource, + * java.lang.String) */ - public Resource getResource(Resource base, String path) { + public Resource getResource(final Resource base, String path) { checkClosed(); if (!path.startsWith("/") && base != null) { @@ -869,137 +604,38 @@ public class JcrResourceResolver /** * @see org.apache.sling.api.resource.ResourceResolver#listChildren(org.apache.sling.api.resource.Resource) */ - @SuppressWarnings("unchecked") - public Iterator listChildren(Resource parent) { + public Iterator listChildren(final Resource parent) { checkClosed(); - final String path = parent.getPath(); - final int wsSepPos = path.indexOf(":/"); - if (wsSepPos != -1) { - final String workspaceName = path.substring(0, wsSepPos); - if (!workspaceName.equals(getSession().getWorkspace().getName())) { - if (useMultiWorkspaces) { - try { - ResourceResolver wsResolver = getResolverForWorkspace(workspaceName); - return wsResolver.listChildren(parent); - } catch (LoginException e) { - // requested a resource in a workspace I don't have access to. - // we treat this as a not found resource - return Collections.EMPTY_LIST.iterator(); - } - } - // this is illegal - return Collections.EMPTY_LIST.iterator(); - } else if (parent instanceof WorkspaceDecoratedResource) { - parent = ((WorkspaceDecoratedResource) parent).getResource(); - } else { - LOGGER.warn("looking for children of workspace path {}, but with an undecorated resource.", - parent.getPath()); - } - } - String workspacePrefix = null; - if ( useMultiWorkspaces && !getSession().getWorkspace().getName().equals(this.factory.getDefaultWorkspaceName()) ) { - workspacePrefix = getSession().getWorkspace().getName(); + if (parent instanceof ResourceWrapper) { + return listChildren(((ResourceWrapper) parent).getResource()); } - - return new ResourceIteratorDecorator( - this.factory.getResourceDecoratorTracker(), workspacePrefix, - new ResourceIterator(parent, rootProvider)); + return new ResourceIteratorDecorator(this.factory.getResourceDecoratorTracker(), + new ResourceIterator(this.context, parent, this.factory.getRootProviderEntry())); } // ---------- Querying resources /** - * @see org.apache.sling.api.resource.ResourceResolver#findResources(java.lang.String, java.lang.String) + * @see org.apache.sling.api.resource.ResourceResolver#findResources(java.lang.String, + * java.lang.String) */ - public Iterator findResources(final String query, final String language) - throws SlingException { + public Iterator findResources(final String query, final String language) throws SlingException { checkClosed(); - try { - Session session = null; - String workspaceName = null; - if (requestBoundResolver != null) { - session = requestBoundResolver.adaptTo(Session.class); - workspaceName = session.getWorkspace().getName(); - } else { - session = getSession(); - } - final QueryResult res = JcrResourceUtil.query(session, query, language); - return new ResourceIteratorDecorator(this.factory.getResourceDecoratorTracker(), workspaceName, - new JcrNodeResourceIterator(this, res.getNodes(), factory.getDynamicClassLoader())); - } catch (javax.jcr.query.InvalidQueryException iqe) { - throw new QuerySyntaxException(iqe.getMessage(), query, language, iqe); - } catch (RepositoryException re) { - throw new SlingException(re.getMessage(), re); - } + + return new ResourceIteratorDecorator(this.factory.getResourceDecoratorTracker(), + this.factory.getRootProviderEntry().findResources(this.context, this, query, language)); } /** - * @see org.apache.sling.api.resource.ResourceResolver#queryResources(java.lang.String, java.lang.String) + * @see org.apache.sling.api.resource.ResourceResolver#queryResources(java.lang.String, + * java.lang.String) */ - public Iterator> queryResources(final String query, - final String language) + public Iterator> queryResources(final String query, final String language) throws SlingException { checkClosed(); - final String queryLanguage = isSupportedQueryLanguage(language) ? language : DEFAULT_QUERY_LANGUAGE; - - try { - QueryResult result = JcrResourceUtil.query(adaptTo(Session.class), query, - queryLanguage); - final String[] colNames = result.getColumnNames(); - final RowIterator rows = result.getRows(); - return new Iterator>() { - public boolean hasNext() { - return rows.hasNext(); - }; - - public Map next() { - Map row = new HashMap(); - try { - Row jcrRow = rows.nextRow(); - boolean didPath = false; - boolean didScore = false; - Value[] values = jcrRow.getValues(); - for (int i = 0; i < values.length; i++) { - Value v = values[i]; - if (v != null) { - String colName = colNames[i]; - row.put(colName, - JcrResourceUtil.toJavaObject(values[i])); - if (colName.equals(QUERY_COLUMN_PATH)) { - didPath = true; - } - if (colName.equals(QUERY_COLUMN_SCORE)) { - didScore = true; - } - } - } - if (!didPath) { - row.put(QUERY_COLUMN_PATH, jcrRow.getPath()); - } - if (!didScore) { - row.put(QUERY_COLUMN_SCORE, jcrRow.getScore()); - } - - } catch (RepositoryException re) { - LOGGER.error( - "queryResources$next: Problem accessing row values", - re); - } - return row; - } - - public void remove() { - throw new UnsupportedOperationException("remove"); - } - }; - } catch (javax.jcr.query.InvalidQueryException iqe) { - throw new QuerySyntaxException(iqe.getMessage(), query, language, - iqe); - } catch (RepositoryException re) { - throw new SlingException(re.getMessage(), re); - } + return this.factory.getRootProviderEntry().queryResources(this.context, query, language); } /** @@ -1007,23 +643,68 @@ public class JcrResourceResolver */ public String getUserID() { checkClosed(); - return getSession().getUserID(); + + // Try auth info first + if ( this.context.getAuthenticationInfo() != null ) { + final Object impUser = this.context.getAuthenticationInfo().get(ResourceResolverFactory.USER_IMPERSONATION); + if ( impUser != null ) { + return impUser.toString(); + } + final Object user = this.context.getAuthenticationInfo().get(ResourceResolverFactory.USER); + if ( user != null ) { + return user.toString(); + } + } + // Try session + final Session session = this.getSession(); + if ( session != null ) { + return session.getUserID(); + } + // Try attributes + final Object impUser = this.getAttribute(ResourceResolverFactory.USER_IMPERSONATION); + if ( impUser != null ) { + return impUser.toString(); + } + final Object user = this.getAttribute(ResourceResolverFactory.USER); + if ( user != null ) { + return user.toString(); + } + + return null; + } + + /** Cached session object, fetched on demand. */ + private Session cachedSession; + /** Flag indicating if a searching has already been searched. */ + private boolean searchedSession = false; + + /** + * Try to get a session from one of the resource providers. + */ + private Session getSession() { + if ( !this.searchedSession ) { + this.searchedSession = true; + this.cachedSession = this.factory.getRootProviderEntry().adaptTo(this.context, Session.class); + } + return this.cachedSession; } // ---------- Adaptable interface /** - * @see org.apache.sling.adapter.SlingAdaptable#adaptTo(java.lang.Class) + * @see org.apache.sling.api.adapter.SlingAdaptable#adaptTo(java.lang.Class) */ @SuppressWarnings("unchecked") - public AdapterType adaptTo(Class type) { + public AdapterType adaptTo(final Class type) { checkClosed(); + if (type == Session.class) { - if (requestBoundResolver != null) { - return (AdapterType) requestBoundResolver.adaptTo(Session.class); - } return (AdapterType) getSession(); } + final AdapterType result = this.factory.getRootProviderEntry().adaptTo(this.context, type); + if ( result != null ) { + return result; + } // fall back to default behaviour return super.adaptTo(type); @@ -1032,45 +713,22 @@ public class JcrResourceResolver // ---------- internal /** - * Returns the JCR Session of the root resource provider which provides - * access to the repository. - */ - private Session getSession() { - return rootProvider.getSession(); - } - - /** - * Get a resolver for the workspace. - */ - private synchronized JcrResourceResolver getResolverForWorkspace( - final String workspaceName) throws LoginException { - if (createdResolvers == null) { - createdResolvers = new HashMap(); - } - JcrResourceResolver wsResolver = createdResolvers.get(workspaceName); - if (wsResolver == null) { - final Map newAuthInfo = new HashMap(); - newAuthInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE, - workspaceName); - wsResolver = (JcrResourceResolver) clone(newAuthInfo); - createdResolvers.put(workspaceName, wsResolver); - } - return wsResolver; - } - - /** * Returns a string used for matching map entries against the given request * or URI parts. * - * @param scheme The URI scheme - * @param host The host name - * @param port The port number. If this is negative, the default value used + * @param scheme + * The URI scheme + * @param host + * The host name + * @param port + * The port number. If this is negative, the default value used * is 80 unless the scheme is "https" in which case the default * value is 443. - * @param path The (absolute) path + * @param path + * The (absolute) path * @return The request path string {scheme}/{host}.{port}{path}. */ - public static String getMapPath(String scheme, String host, int port, String path) { + private static String getMapPath(final String scheme, final String host, int port, final String path) { if (port < 0) { port = ("https".equals(scheme)) ? 443 : 80; } @@ -1087,24 +745,24 @@ public class JcrResourceResolver * This method operates in two steps: *

    *
  1. Check the path directly - *
  2. Drill down the resource tree from the root down to the resource - * trying to get the child as per the respective path segment or finding a - * child whose sling:alias property is set to the respective - * name. + *
  3. Drill down the resource tree from the root down to the resource trying to get the child + * as per the respective path segment or finding a child whose sling:alias property + * is set to the respective name. *
*

- * If neither mechanism (direct access and drill down) resolves to a - * resource this method returns null. + * If neither mechanism (direct access and drill down) resolves to a resource this method + * returns null. * - * @param absPath The absolute path of the resource to return. - * @return The resource found or null if the resource could - * not be found. The - * {@link org.apache.sling.api.resource.ResourceMetadata#getResolutionPathInfo() resolution path info} - * field of the resource returned is set to the part of the - * absPath which has been cut off by the - * {@link ResourcePathIterator} to resolve the resource. + * @param absPath + * The absolute path of the resource to return. + * @return The resource found or null if the resource could not + * be found. The + * {@link org.apache.sling.api.resource.ResourceMetadata#getResolutionPathInfo() + * resolution path info} field of the resource returned is set to + * the part of the absPath which has been cut off by + * the {@link ResourcePathIterator} to resolve the resource. */ - private Resource resolveInternal(String absPath) { + private Resource resolveInternal(final String absPath) { Resource resource = null; String curPath = absPath; try { @@ -1113,9 +771,8 @@ public class JcrResourceResolver curPath = it.next(); resource = getResourceInternal(curPath); } - } catch (Exception ex) { - throw new SlingException("Problem trying " + curPath - + " for request path " + absPath, ex); + } catch (final Exception ex) { + throw new SlingException("Problem trying " + curPath + " for request path " + absPath, ex); } // SLING-627: set the part cut off from the uriPath as @@ -1123,22 +780,20 @@ public class JcrResourceResolver // uriPath = curPath + sling.resolutionPathInfo if (resource != null) { - String rpi = absPath.substring(curPath.length()); + final String rpi = absPath.substring(curPath.length()); resource.getResourceMetadata().setResolutionPathInfo(rpi); - LOGGER.debug( - "resolveInternal: Found resource {} with path info {} for {}", - new Object[] { resource, rpi, absPath }); + logger.debug("resolveInternal: Found resource {} with path info {} for {}", new Object[] { resource, rpi, absPath }); } else { // no direct resource found, so we have to drill down into the // resource tree to find a match resource = getResourceInternal("/"); - StringBuilder resolutionPath = new StringBuilder(); - StringTokenizer tokener = new StringTokenizer(absPath, "/"); + final StringBuilder resolutionPath = new StringBuilder(); + final StringTokenizer tokener = new StringTokenizer(absPath, "/"); while (resource != null && tokener.hasMoreTokens()) { - String childNameRaw = tokener.nextToken(); + final String childNameRaw = tokener.nextToken(); Resource nextResource = getChildInternal(resource, childNameRaw); if (nextResource != null) { @@ -1149,8 +804,7 @@ public class JcrResourceResolver } else { String childName = null; - ResourcePathIterator rpi = new ResourcePathIterator( - childNameRaw); + final ResourcePathIterator rpi = new ResourcePathIterator(childNameRaw); while (rpi.hasNext() && nextResource == null) { childName = rpi.next(); nextResource = getChildInternal(resource, childName); @@ -1179,24 +833,22 @@ public class JcrResourceResolver resource.getResourceMetadata().setResolutionPath(path); resource.getResourceMetadata().setResolutionPathInfo(pathInfo); - LOGGER.debug( - "resolveInternal: Found resource {} with path info {} for {}", - new Object[] { resource, pathInfo, absPath }); + logger.debug("resolveInternal: Found resource {} with path info {} for {}", new Object[] { resource, pathInfo, + absPath }); } } return resource; } - private Resource getChildInternal(Resource parent, String childName) { + private Resource getChildInternal(final Resource parent, final String childName) { Resource child = getResource(parent, childName); if (child != null) { - String alias = getProperty(child, PROP_REDIRECT_INTERNAL); + final String alias = getProperty(child, PROP_REDIRECT_INTERNAL); if (alias != null) { // TODO: might be a redirect ?? - LOGGER.warn( - "getChildInternal: Internal redirect to {} for Resource {} is not supported yet, ignoring", - alias, child); + logger.warn("getChildInternal: Internal redirect to {} for Resource {} is not supported yet, ignoring", alias, + child); } // we have the resource name, continue with the next level @@ -1205,60 +857,54 @@ public class JcrResourceResolver // we do not have a child with the exact name, so we look for // a child, whose alias matches the childName - Iterator children = listChildren(parent); + final Iterator children = listChildren(parent); while (children.hasNext()) { child = children.next(); - if (!child.getPath().endsWith(JCR_CONTENT_LEAF)){ - String[] aliases = getProperty(child, PROP_ALIAS, String[].class); - if (aliases != null) { - for (String alias : aliases) { - if (childName.equals(alias)) { - LOGGER.debug( - "getChildInternal: Found Resource {} with alias {} to use", - child, childName); - return child; - } - } - } + if (!child.getPath().endsWith(JCR_CONTENT_LEAF)) { + final String[] aliases = getProperty(child, PROP_ALIAS, String[].class); + if (aliases != null) { + for (final String alias : aliases) { + if (childName.equals(alias)) { + logger.debug("getChildInternal: Found Resource {} with alias {} to use", child, childName); + return child; + } + } + } } } // no match for the childName found - LOGGER.debug("getChildInternal: Resource {} has no child {}", parent, - childName); + logger.debug("getChildInternal: Resource {} has no child {}", parent, childName); return null; } /** - * Creates a JcrNodeResource with the given path if existing + * Creates a resource with the given path if existing */ - protected Resource getResourceInternal(String path) { + private Resource getResourceInternal(final String path) { - Resource resource = rootProvider.getResource(this, path); + final Resource resource = this.factory.getRootProviderEntry().getResource(this.context, this, path); if (resource != null) { resource.getResourceMetadata().setResolutionPath(path); return resource; } - LOGGER.debug( - "getResourceInternal: Cannot resolve path '{}' to a resource", path); + logger.debug("getResourceInternal: Cannot resolve path '{}' to a resource", path); return null; } - public String getProperty(Resource res, String propName) { + private String getProperty(final Resource res, final String propName) { return getProperty(res, propName, String.class); } - public Type getProperty(Resource res, String propName, - Class type) { + private Type getProperty(final Resource res, final String propName, final Class type) { // check the property in the resource itself - ValueMap props = res.adaptTo(ValueMap.class); + final ValueMap props = res.adaptTo(ValueMap.class); if (props != null) { Type prop = props.get(propName, type); if (prop != null) { - LOGGER.debug("getProperty: Resource {} has property {}={}", - new Object[] { res, propName, prop }); + logger.debug("getProperty: Resource {} has property {}={}", new Object[] { res, propName, prop }); return prop; } // otherwise, check it in the jcr:content child resource @@ -1275,12 +921,13 @@ public class JcrResourceResolver } /** - * Returns the path as an absolute path. If the path is - * already absolute it is returned unmodified (the same instance actually). - * If the path is relative it is made absolute by prepending the first entry - * of the {@link #getSearchPath() search path}. + * Returns the path as an absolute path. If the path is already + * absolute it is returned unmodified (the same instance actually). If the + * path is relative it is made absolute by prepending the first entry of the + * {@link #getSearchPath() search path}. * - * @param path The path to ensure absolute + * @param path + * The path to ensure absolute * @return The absolute path as explained above */ private String ensureAbsPath(String path) { @@ -1292,12 +939,12 @@ public class JcrResourceResolver private String mangleNamespaces(String absPath) { if (factory.isMangleNamespacePrefixes() && absPath.contains(MANGLE_NAMESPACE_OUT_SUFFIX)) { - Pattern p = Pattern.compile(MANGLE_NAMESPACE_OUT); - Matcher m = p.matcher(absPath); + final Pattern p = Pattern.compile(MANGLE_NAMESPACE_OUT); + final Matcher m = p.matcher(absPath); - StringBuffer buf = new StringBuffer(); + final StringBuffer buf = new StringBuffer(); while (m.find()) { - String replacement = MANGLE_NAMESPACE_IN_PREFIX + m.group(1) + MANGLE_NAMESPACE_IN_SUFFIX; + final String replacement = MANGLE_NAMESPACE_IN_PREFIX + m.group(1) + MANGLE_NAMESPACE_IN_SUFFIX; m.appendReplacement(buf, replacement); } @@ -1311,33 +958,33 @@ public class JcrResourceResolver private String unmangleNamespaces(String absPath) { if (factory.isMangleNamespacePrefixes() && absPath.contains(MANGLE_NAMESPACE_IN_PREFIX)) { - Pattern p = Pattern.compile(MANGLE_NAMESPACE_IN); - Matcher m = p.matcher(absPath); - StringBuffer buf = new StringBuffer(); + final Pattern p = Pattern.compile(MANGLE_NAMESPACE_IN); + final Matcher m = p.matcher(absPath); + final StringBuffer buf = new StringBuffer(); while (m.find()) { - String namespace = m.group(1); + final String namespace = m.group(1); try { // throws if "namespace" is not a registered // namespace prefix - getSession().getNamespaceURI(namespace); + final Session session = getSession(); + if ( session != null ) { + session.getNamespaceURI(namespace); + final String replacement = MANGLE_NAMESPACE_OUT_PREFIX + namespace + MANGLE_NAMESPACE_OUT_SUFFIX; + m.appendReplacement(buf, replacement); + } else { + logger.debug("unmangleNamespaces: '{}' is not a prefix, not unmangling", namespace); + } - String replacement = MANGLE_NAMESPACE_OUT_PREFIX - + namespace + MANGLE_NAMESPACE_OUT_SUFFIX; - m.appendReplacement(buf, replacement); - } catch (NamespaceException ne) { + } catch (final NamespaceException ne) { // not a valid prefix - LOGGER.debug( - "unmangleNamespaces: '{}' is not a prefix, not unmangling", - namespace); - - } catch (RepositoryException re) { - - LOGGER.warn( - "unmangleNamespaces: Problem checking namespace '{}'", - namespace, re); + logger.debug("unmangleNamespaces: '{}' is not a prefix, not unmangling", namespace); + + } catch (final RepositoryException re) { + + logger.warn("unmangleNamespaces: Problem checking namespace '{}'", namespace, re); } } @@ -1347,19 +994,4 @@ public class JcrResourceResolver return absPath; } - - private boolean isSupportedQueryLanguage(String language) { - try { - String[] supportedLanguages = adaptTo(Session.class).getWorkspace(). - getQueryManager().getSupportedQueryLanguages(); - for (String lang : supportedLanguages) { - if (lang.equals(language)) { - return true; - } - } - } catch (RepositoryException e) { - LOGGER.error("Unable to discover supported query languages", e); - } - return false; - } } Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java?rev=1350169&r1=1350168&r2=1350169&view=diff ============================================================================== --- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java (original) +++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java Thu Jun 14 09:52:08 2012 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.sling.jcr.resource.internal; +package org.apache.sling.resourceresolver.impl.console; import java.io.IOException; import java.io.PrintWriter; @@ -28,25 +28,24 @@ import java.util.Dictionary; import java.util.Hashtable; import java.util.List; -import javax.jcr.Session; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; -import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.request.ResponseUtil; -import org.apache.sling.jcr.resource.internal.helper.MapEntries; -import org.apache.sling.jcr.resource.internal.helper.MapEntry; -import org.apache.sling.jcr.resource.internal.helper.URI; -import org.apache.sling.jcr.resource.internal.helper.URIException; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl; +import org.apache.sling.resourceresolver.impl.helper.URI; +import org.apache.sling.resourceresolver.impl.helper.URIException; +import org.apache.sling.resourceresolver.impl.mapping.MapEntries; +import org.apache.sling.resourceresolver.impl.mapping.MapEntry; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; -public class JcrResourceResolverWebConsolePlugin extends - HttpServlet { +public class ResourceResolverWebConsolePlugin extends HttpServlet { private static final long serialVersionUID = 0; @@ -57,29 +56,28 @@ public class JcrResourceResolverWebConso private static final String PAR_MSG = "msg"; private static final String PAR_TEST = "test"; - private final transient JcrResourceResolverFactoryImpl resolverFactory; + private final transient ResourceResolverFactoryImpl resolverFactory; private transient ServiceRegistration service; - JcrResourceResolverWebConsolePlugin(BundleContext context, - JcrResourceResolverFactoryImpl resolverFactory) { + public ResourceResolverWebConsolePlugin(BundleContext context, + ResourceResolverFactoryImpl resolverFactory) { this.resolverFactory = resolverFactory; Dictionary props = new Hashtable(); props.put(Constants.SERVICE_DESCRIPTION, - "JCRResourceResolver Web Console Plugin"); + "Resource Resolver Web Console Plugin"); props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation"); props.put(Constants.SERVICE_PID, getClass().getName()); props.put("felix.webconsole.label", "jcrresolver"); props.put("felix.webconsole.title", "Sling Resource Resolver"); props.put("felix.webconsole.configprinter.modes", "always"); - service = context.registerService(new String[] { - "javax.servlet.Servlet" }, - this, props); + service = context.registerService( + new String[] { "javax.servlet.Servlet" }, this, props); } - void dispose() { + public void dispose() { if (service != null) { service.unregister(); service = null; @@ -87,11 +85,12 @@ public class JcrResourceResolverWebConso } @Override - protected void doGet(final HttpServletRequest request, final HttpServletResponse response) - throws ServletException, IOException { + protected void doGet(final HttpServletRequest request, + final HttpServletResponse response) throws ServletException, + IOException { final String msg = request.getParameter(PAR_MSG); final String test; - if ( msg != null ) { + if (msg != null) { test = request.getParameter(PAR_TEST); } else { test = null; @@ -113,7 +112,8 @@ public class JcrResourceResolverWebConso pw.println(""); pw.println("Namespace Mangling"); pw.print(""); - pw.print(resolverFactory.isMangleNamespacePrefixes() ? "Enabled" : "Disabled"); + pw.print(resolverFactory.isMangleNamespacePrefixes() ? "Enabled" + : "Disabled"); pw.print(""); pw.println(""); pw.println(""); @@ -126,29 +126,29 @@ public class JcrResourceResolverWebConso separatorHtml(pw); titleHtml( - pw, - "Configuration Test", - "To test the configuration, enter an URL or a resource path into " + - "the field and click 'Resolve' to resolve the URL or click 'Map' " + - "to map the resource path. To simulate a map call that takes the " + - "current request into account, provide a full URL whose " + - "scheme/host/port prefix will then be used as the request " + - "information. The path passed to map will always be the path part " + - "of the URL."); + pw, + "Configuration Test", + "To test the configuration, enter an URL or a resource path into " + + "the field and click 'Resolve' to resolve the URL or click 'Map' " + + "to map the resource path. To simulate a map call that takes the " + + "current request into account, provide a full URL whose " + + "scheme/host/port prefix will then be used as the request " + + "information. The path passed to map will always be the path part " + + "of the URL."); pw.println(""); pw.println("Test"); pw.print(""); pw.print("

"); pw.print(""); pw.println("  "); + + "' value='Resolve' class='submit'>"); pw.println("  "); + + "' value='Map' class='submit'>"); pw.print("
"); pw.print(""); pw.println(""); @@ -165,18 +165,18 @@ public class JcrResourceResolverWebConso separatorHtml(pw); dumpMapHtml( - pw, - "Resolver Map Entries", - "Lists the entries used by the ResourceResolver.resolve methods to map URLs to Resources", - mapEntries.getResolveMaps()); + pw, + "Resolver Map Entries", + "Lists the entries used by the ResourceResolver.resolve methods to map URLs to Resources", + mapEntries.getResolveMaps()); separatorHtml(pw); dumpMapHtml( - pw, - "Mapping Map Entries", - "Lists the entries used by the ResourceResolver.map methods to map Resource Paths to URLs", - mapEntries.getMapMaps()); + pw, + "Mapping Map Entries", + "Lists the entries used by the ResourceResolver.map methods to map Resource Paths to URLs", + mapEntries.getMapMaps()); pw.println(""); @@ -190,15 +190,14 @@ public class JcrResourceResolverWebConso String msg = null; if (test != null && test.length() > 0) { - Session session = null; + ResourceResolver resolver = null; try { // prepare the request for the resource resolver HttpServletRequest helper = new ResolverRequest(request, test); - // get the resource resolver with an administrative session - session = resolverFactory.getRepository().loginAdministrative( - null); - ResourceResolver resolver = resolverFactory.getResourceResolver(session); + // get an administrative resource resolver + resolver = resolverFactory + .getAdministrativeResourceResolver(null); // map or resolve as instructed Object result; @@ -221,20 +220,22 @@ public class JcrResourceResolverWebConso msg = "Test Failure: " + t; } finally { - if (session != null) { - session.logout(); + if (resolver != null) { + resolver.close(); } } } // finally redirect - final String path = request.getContextPath() + request.getServletPath() + request.getPathInfo(); + final String path = request.getContextPath() + request.getServletPath() + + request.getPathInfo(); final String redirectTo; - if ( msg == null ) { + if (msg == null) { redirectTo = path; } else { - redirectTo = path + '?' + PAR_MSG + '=' + encodeParam(msg) + '&' + PAR_TEST + '=' + encodeParam(test); + redirectTo = path + '?' + PAR_MSG + '=' + encodeParam(msg) + '&' + + PAR_TEST + '=' + encodeParam(test); } response.sendRedirect(redirectTo); } @@ -253,17 +254,11 @@ public class JcrResourceResolverWebConso public void printConfiguration(PrintWriter pw) { final MapEntries mapEntries = resolverFactory.getMapEntries(); - dumpMapText( - pw, - "Resolver Map Entries", - mapEntries.getResolveMaps()); - - separatorText(pw); - - dumpMapText( - pw, - "Mapping Map Entries", - mapEntries.getMapMaps()); + dumpMapText(pw, "Resolver Map Entries", mapEntries.getResolveMaps()); + + separatorText(pw); + + dumpMapText(pw, "Mapping Map Entries", mapEntries.getMapMaps()); } // ---------- internal @@ -282,7 +277,7 @@ public class JcrResourceResolverWebConso for (MapEntry entry : list) { pw.println(""); pw.println("" - + entry.getPattern() + ""); + + entry.getPattern() + ""); pw.print(""); String[] repls = entry.getRedirect(); @@ -305,13 +300,13 @@ public class JcrResourceResolverWebConso private void titleHtml(PrintWriter pw, String title, String description) { pw.println(""); pw.println("" + title - + ""); + + ""); pw.println(""); if (description != null) { pw.println(""); pw.println("" + description - + ""); + + ""); pw.println(""); } } @@ -332,8 +327,7 @@ public class JcrResourceResolverWebConso for (MapEntry entry : list) { final List redir = Arrays.asList(entry.getRedirect()); - final String status = entry.isInternal() - ? "internal" + final String status = entry.isInternal() ? "internal" : "external: " + entry.getStatus(); pw.printf(format, entry.getPattern(), redir, status); } Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java?rev=1350169&r1=1350168&r2=1350169&view=diff ============================================================================== --- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java (original) +++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java Thu Jun 14 09:52:08 2012 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.sling.jcr.resource.internal.helper; +package org.apache.sling.resourceresolver.impl.helper; import java.util.Collections; import java.util.HashMap; @@ -45,7 +45,7 @@ public final class RedirectResource exte final String target, final int status) { super(resolver, path, RT_SLING_REDIRECT); - HashMap props = new HashMap(); + final Map props = new HashMap(); props.put(PROP_SLING_TARGET, target); props.put(PROP_SLING_STATUS, status); this.values = Collections.unmodifiableMap(props); @@ -55,7 +55,7 @@ public final class RedirectResource exte * @see org.apache.sling.api.adapter.Adaptable#adaptTo(java.lang.Class) */ @SuppressWarnings("unchecked") - public AdapterType adaptTo(Class type) { + public AdapterType adaptTo(final Class type) { if (type == ValueMap.class) { return (AdapterType) new ValueMapDecorator(values); } else if (type == Map.class) { Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java?rev=1350169&r1=1350168&r2=1350169&view=diff ============================================================================== --- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java (original) +++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java Thu Jun 14 09:52:08 2012 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.sling.jcr.resource.internal; +package org.apache.sling.resourceresolver.impl.helper; import java.util.ArrayList; import java.util.Collections; @@ -24,15 +24,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; - import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceDecorator; -import org.apache.sling.commons.osgi.OsgiUtil; +import org.apache.sling.commons.osgi.ServiceUtil; /** - * Helper class to track the resource decorators and keep - * them sorted by their service ranking. + * Helper class to track the resource decorators and keep them sorted by their + * service ranking. */ public class ResourceDecoratorTracker { @@ -55,38 +53,44 @@ public class ResourceDecoratorTracker { } } - /** Decorate a resource. */ - public Resource decorate(final Resource resource, String workspaceName) { + /** + * Decorate a resource. + */ + public Resource decorate(final Resource resource) { Resource result = resource; final ResourceDecorator[] decorators = this.resourceDecoratorsArray; - for(final ResourceDecorator decorator : decorators) { + for (final ResourceDecorator decorator : decorators) { final Resource original = result; result = decorator.decorate(original); - if ( result == null ) { + if (result == null) { result = original; } } - if (workspaceName != null) { - result = new WorkspaceDecoratedResource(result, workspaceName); - } - return result; - } - public ResourceDecorator[] getResourceDecorators() { - return this.resourceDecoratorsArray; + return result; } - protected void bindResourceDecorator(final ResourceDecorator decorator, final Map props) { + /** + * Bind a resouce decorator. + */ + public void bindResourceDecorator(final ResourceDecorator decorator, + final Map props) { synchronized (this.resourceDecorators) { - this.resourceDecorators.add(new ResourceDecoratorEntry(decorator, OsgiUtil.getComparableForServiceRanking(props))); + this.resourceDecorators.add(new ResourceDecoratorEntry(decorator, + ServiceUtil.getComparableForServiceRanking(props))); Collections.sort(this.resourceDecorators); updateResourceDecoratorsArray(); } } - protected void unbindResourceDecorator(final ResourceDecorator decorator, final Map props) { + /** + * Unbind a resouce decorator. + */ + public void unbindResourceDecorator(final ResourceDecorator decorator, + final Map props) { synchronized (this.resourceDecorators) { - final Iterator i = this.resourceDecorators.iterator(); + final Iterator i = this.resourceDecorators + .iterator(); while (i.hasNext()) { final ResourceDecoratorEntry current = i.next(); if (current.decorator == decorator) { @@ -99,15 +103,16 @@ public class ResourceDecoratorTracker { } /** - * Updates the ResourceDecorators array, this method is not thread safe and should only be - * called from a synchronized block. + * Updates the ResourceDecorators array, this method is not thread safe and + * should only be called from a synchronized block. */ - protected void updateResourceDecoratorsArray() { + private void updateResourceDecoratorsArray() { final ResourceDecorator[] decorators; if (this.resourceDecorators.size() > 0) { decorators = new ResourceDecorator[this.resourceDecorators.size()]; int index = 0; - final Iterator i = this.resourceDecorators.iterator(); + final Iterator i = this.resourceDecorators + .iterator(); while (i.hasNext()) { decorators[index] = i.next().decorator; index++; @@ -121,7 +126,8 @@ public class ResourceDecoratorTracker { /** * Internal class to keep track of the resource decorators. */ - private static final class ResourceDecoratorEntry implements Comparable { + private static final class ResourceDecoratorEntry implements + Comparable { final Comparable comparable; @@ -133,7 +139,7 @@ public class ResourceDecoratorTracker { this.decorator = d; } - public int compareTo(ResourceDecoratorEntry o) { + public int compareTo(final ResourceDecoratorEntry o) { return comparable.compareTo(o.comparable); } }