View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.web.jcr.webdav;
25  
26  import java.util.regex.Matcher;
27  import java.util.regex.Pattern;
28  import javax.servlet.ServletContext;
29  import javax.servlet.http.HttpServletRequest;
30  
31  /**
32   * A {@link RequestResolver} implementation that expects the first segment of the URI is the repository name, the second is the
33   * workspace name, and the remaining form the node path. This resolver does handle the case when only the repository name is
34   * specified, or only the repository and workspace names are supplied, or when not even the repository name is given.
35   * 
36   * @see SingleRepositoryRequestResolver
37   */
38  public class MultiRepositoryRequestResolver implements RequestResolver {
39  
40      /**
41       * The string representation of the Java version of the {@link #PATH_PATTERN} regular expression.
42       */
43      protected static final String PATH_PATTERN_STRING = "/?(([^/]*)(/([^/]*)?(/(.*))?)?)?";
44  
45      /**
46       * The regular expression that is used to extract the repository name, workspace name, and node path. Group 2 will contain the
47       * repository name, group 4 the workspace name, group 5 the node path (with leading slash). Any of these groups may be empty
48       * (or null).
49       * <p>
50       * The regular expression is <code>/?(([^/]*)(/([^/]*)?(/(.*))?)?)?</code>.
51       */
52      protected static final Pattern PATH_PATTERN = Pattern.compile(PATH_PATTERN_STRING);
53  
54      protected static final int REPOSITORY_NAME_GROUP = 2;
55      protected static final int WORKSPACE_WITH_SLASH_GROUP = 3;
56      protected static final int WORKSPACE_NAME_GROUP = 4;
57      protected static final int PATH_GROUP = 5;
58  
59      protected static final String ROOT_NODE_PATH = "/";
60  
61      @Override
62      public void initialize( ServletContext context ) {
63          // nothing to do
64      }
65  
66      @Override
67      public ResolvedRequest resolve( HttpServletRequest request,
68                                      String relativePath ) {
69          if (relativePath != null && relativePath.length() != 0) {
70              Matcher matcher = PATH_PATTERN.matcher(relativePath);
71              if (matcher.matches()) {
72                  String repositoryName = matcher.group(REPOSITORY_NAME_GROUP); // may be null
73                  String workspaceName = matcher.group(WORKSPACE_NAME_GROUP); // may be null
74                  String nodePath = matcher.group(PATH_GROUP); // may be null
75                  if (nodePath == null) {
76                      if (workspaceName != null) {
77                          if (workspaceName.length() == 0 && "/".equals(matcher.group(WORKSPACE_WITH_SLASH_GROUP))) {
78                              // There really isn't a workspace
79                              workspaceName = null;
80                          } else {
81                              // There's a real workspace, so set the path to the root node ...
82                              nodePath = ROOT_NODE_PATH;
83                          }
84                      } else if (repositoryName != null && repositoryName.length() == 0) {
85                          // There's no path or workspace, and the repository name is blank ...
86                          repositoryName = null;
87                      }
88                  } else {
89                      // There is a path, so make sure that the repository and workspace names exist ...
90                      if (repositoryName == null) repositoryName = "";
91                      else if (workspaceName == null) workspaceName = "";
92                  }
93                  return new ResolvedRequest(request, repositoryName, workspaceName, nodePath);
94              }
95          }
96          return new ResolvedRequest(request, null, null, null);
97      }
98  }