use of org.apache.sling.resourceresolver.impl.helper.RedirectResource in project sling by apache.
the class ResourceResolverImpl method resolveInternal.
private Resource resolveInternal(final HttpServletRequest request, String absPath) {
// make sure abspath is not null and is absolute
if (absPath == null) {
absPath = "/";
} else if (!absPath.startsWith("/")) {
absPath = "/" + absPath;
}
// check for special namespace prefix treatment
absPath = unmangleNamespaces(absPath);
// 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);
} else {
requestPath = getMapPath("http", "localhost", 80, absPath);
}
logger.debug("resolve: Resolving request path {}", requestPath);
// TODO: might do better to be able to log the loop and help the user
for (int i = 0; i < 100; i++) {
String[] mappedPath = null;
final Iterator<MapEntry> mapEntriesIterator = this.factory.getMapEntries().getResolveMapsIterator(requestPath);
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 (mapEntry.isInternal()) {
// internal redirect
logger.debug("resolve: Redirecting internally");
break;
}
// external redirect
logger.debug("resolve: Returning external redirect");
return this.factory.getResourceDecoratorTracker().decorate(new RedirectResource(this, absPath, mappedPath[0], mapEntry.getStatus()));
}
}
// and use the original realPath
if (mappedPath == null) {
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");
realPathList = mappedPath;
break;
}
// 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());
realPathList = new String[] { uri.getPath() };
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);
}
}
// now we have the real path resolved from virtual host mapping
// this path may be absolute or relative, in which case we try
// to resolve it against the search path
Resource res = null;
for (int i = 0; res == null && i < realPathList.length; i++) {
final ParsedParameters parsedPath = new ParsedParameters(realPathList[i]);
final String realPath = parsedPath.getRawPath();
// first check whether the requested resource is a StarResource
if (StarResource.appliesTo(realPath)) {
logger.debug("resolve: Mapped path {} is a Star Resource", realPath);
res = new StarResource(this, ensureAbsPath(realPath));
} else {
if (realPath.startsWith("/")) {
// let's check it with a direct access first
logger.debug("resolve: Try absolute mapped path {}", realPath);
res = resolveInternal(realPath, parsedPath.getParameters());
} else {
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]);
res = resolveInternal(searchPath[spi] + realPath, parsedPath.getParameters());
}
}
}
}
// if no resource has been found, use a NonExistingResource
if (res == null) {
final ParsedParameters parsedPath = new ParsedParameters(realPathList[0]);
final String resourcePath = ensureAbsPath(parsedPath.getRawPath());
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.
// the resolution path must be the full path and is already set within
// the non existing resource
final int index = resourcePath.indexOf('.');
if (index != -1) {
res.getResourceMetadata().setResolutionPathInfo(resourcePath.substring(index));
}
res.getResourceMetadata().setParameterMap(parsedPath.getParameters());
} else {
logger.debug("resolve: Path {} resolves to Resource {}", absPath, res);
}
return this.factory.getResourceDecoratorTracker().decorate(res);
}
Aggregations