/*
* ModeShape (http://www.modeshape.org)
*
* Licensed 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.modeshape.web.jcr.webdav;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/**
* A {@link RequestResolver} implementation that expects the first segment of the URI is the repository name, the second is the
* workspace name, and the remaining form the node path. This resolver does handle the case when only the repository name is
* specified, or only the repository and workspace names are supplied, or when not even the repository name is given.
*
* @see SingleRepositoryRequestResolver
*/
public class MultiRepositoryRequestResolver implements RequestResolver {
/**
* The string representation of the Java version of the {@link #PATH_PATTERN} regular expression.
*/
protected static final String PATH_PATTERN_STRING = "/*(([^/]*)(/+([^/]*)?(/+(.*))?)?)?";
/**
* The regular expression that is used to extract the repository name, workspace name, and node path. Group 2 will contain the
* repository name, group 4 the workspace name, group 5 the node path (with leading slash). Any of these groups may be empty
* (or null).
* <p>
* The regular expression is <code>/?(([^/]*)(/([^/]*)?(/(.*))?)?)?</code>.
*/
protected static final Pattern PATH_PATTERN = Pattern.compile(PATH_PATTERN_STRING);
protected static final int REPOSITORY_NAME_GROUP = 2;
protected static final int WORKSPACE_WITH_SLASH_GROUP = 3;
protected static final int WORKSPACE_NAME_GROUP = 4;
protected static final int PATH_GROUP = 5;
protected static final String ROOT_NODE_PATH = "/";
@Override
public void initialize( ServletContext context ) {
// nothing to do
}
@Override
public ResolvedRequest resolve( HttpServletRequest request,
String relativePath ) {
if (relativePath != null && relativePath.length() != 0) {
Matcher matcher = PATH_PATTERN.matcher(relativePath);
if (matcher.matches()) {
String repositoryName = matcher.group(REPOSITORY_NAME_GROUP); // may be null
String workspaceName = matcher.group(WORKSPACE_NAME_GROUP); // may be null
String nodePath = matcher.group(PATH_GROUP); // may be null
if (nodePath == null) {
if (workspaceName != null) {
if (workspaceName.length() == 0 && "/".equals(matcher.group(WORKSPACE_WITH_SLASH_GROUP))) {
// There really isn't a workspace
workspaceName = null;
} else {
// There's a real workspace, so set the path to the root node ...
nodePath = ROOT_NODE_PATH;
}
} else if (repositoryName != null && repositoryName.length() == 0) {
// There's no path or workspace, and the repository name is blank ...
repositoryName = null;
}
} else {
// There is a path, so make sure that the repository and workspace names exist ...
if (repositoryName == null) repositoryName = "";
else if (workspaceName == null) workspaceName = "";
nodePath = nodePath.replaceAll("/{2,}+", "/");
}
return new ResolvedRequest(request, repositoryName, workspaceName, nodePath);
}
}
return new ResolvedRequest(request, null, null, null);
}
}