001: /*
002: * Copyright 2004, 2005, 2006 Odysseus Software GmbH
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package de.odysseus.calyxo.control.base;
017:
018: import javax.servlet.http.HttpServletRequest;
019:
020: import de.odysseus.calyxo.base.conf.ConfigException;
021:
022: /**
023: * Module mapping.
024: * Requests may be mapped to a module by a prefix and/or extension.
025: * This class encapsulates a servlet mapping and allows mapping between
026: * (context-relative) requests paths and module-relative action paths
027: * and vice versa.
028: *
029: * @author Christoph Beck
030: */
031: public class ControlModuleMapping {
032:
033: /**
034: * The request attribute under which the path information is stored for
035: * processing during a RequestDispatcher.include() call.
036: */
037: private static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
038:
039: /**
040: * The request attribute under which the servlet path information is stored
041: * for processing during a RequestDispatcher.include() call.
042: */
043: private static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
044:
045: /**
046: * Get the servlet path from specified request.
047: */
048: private static final String getServletPath(
049: HttpServletRequest request) {
050: String path = (String) request
051: .getAttribute(INCLUDE_SERVLET_PATH);
052: if (path == null)
053: path = request.getServletPath();
054: return path;
055: }
056:
057: /**
058: * Get the path info from specified request.
059: */
060: private static final String getPathInfo(HttpServletRequest request) {
061: String path = (String) request.getAttribute(INCLUDE_PATH_INFO);
062: if (path == null)
063: path = request.getPathInfo();
064: return path;
065: }
066:
067: private String prefix;
068: private String extension;
069:
070: /**
071: * Constructor.
072: */
073: public ControlModuleMapping(String prefix, String extension) {
074: this .prefix = prefix;
075: this .extension = extension;
076: }
077:
078: /**
079: * Constructor.
080: * @param pattern servlet mapping pattern as specified in web.xml
081: * @throws ConfigException
082: */
083: public ControlModuleMapping(String pattern) throws ConfigException {
084: if (pattern.startsWith("*.")) {
085: extension = pattern.substring(1);
086: } else if (pattern.endsWith("/*")) {
087: prefix = pattern.substring(0, pattern.length() - 2);
088: } else if (pattern.equals("/")) {
089: prefix = "";
090: } else {
091: throw new ConfigException("Bad url-pattern: " + pattern);
092: }
093: }
094:
095: /**
096: * Get mapping extension
097: */
098: public String getExtension() {
099: return extension;
100: }
101:
102: /**
103: * Get mapping prefix
104: */
105: public String getPrefix() {
106: return prefix;
107: }
108:
109: /**
110: * Answer path for specified action.
111: * The action may have a query string, which is also appended to
112: * the returned path.
113: * @param action the module-relative action path (with optional query string)
114: * @return context-relative path that selects the specified action
115: */
116: public String getPath(String action) {
117: StringBuffer s = new StringBuffer();
118: if (prefix != null) {
119: s.append(prefix);
120: }
121: if (!action.startsWith("/")) {
122: s.append("/");
123: }
124: if (extension != null) {
125: int query = action.indexOf("?");
126: if (query > 0) {
127: // insert extension before query string
128: s.append(action.substring(0, query));
129: s.append(extension);
130: s.append(action.substring(query));
131: } else {
132: int anchor = action.indexOf("#");
133: if (anchor > 0) {
134: // insert extension before anchor
135: s.append(action.substring(0, anchor));
136: s.append(extension);
137: s.append(action.substring(anchor));
138: } else {
139: s.append(action);
140: s.append(extension);
141: }
142: }
143: } else {
144: s.append(action);
145: }
146: return s.toString();
147: }
148:
149: /**
150: * Get the action path from specified request.
151: * The action path is the concatenation of servlet path and path info,
152: * stripped by prefix and extension.
153: * @param request
154: * @return module-relative action path
155: */
156: public String getAction(HttpServletRequest request) {
157: String action = getServletPath(request);
158: if (prefix != null) {
159: if (!action.startsWith(prefix)) {
160: return null;
161: }
162: action = action.substring(prefix.length());
163: }
164: if (extension == null) {
165: String info = getPathInfo(request);
166: if (info != null) {
167: action += info;
168: }
169: } else {
170: if (!action.endsWith(extension)) {
171: return null;
172: }
173: action = action.substring(0, action.length()
174: - extension.length());
175: }
176: return action.length() == 0 ? "/" : action;
177: }
178:
179: }
|