001: // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
002:
003: package jodd.madvoc;
004:
005: import jodd.madvoc.interceptor.ActionInterceptor;
006: import jodd.madvoc.result.ActionResult;
007: import jodd.util.StringUtil;
008:
009: import javax.servlet.http.HttpServletRequest;
010: import javax.servlet.http.HttpServletResponse;
011:
012: /**
013: * Encapsulates single action invocation and acts as an action proxy.
014: * It invokes all assigned interceptors during action invocation and
015: * specified result set after the action method invocation.
016: */
017: public class ActionRequest {
018:
019: protected final WebApplication webapp;
020: protected final ActionConfig config;
021: protected HttpServletRequest request;
022: protected HttpServletResponse response;
023:
024: protected final int totalInterceptors;
025: protected int interceptorIndex;
026: protected final Object action;
027:
028: protected boolean executed;
029: protected boolean rendered;
030:
031: // ---------------------------------------------------------------- accessors
032:
033: public HttpServletRequest getHttpServletRequest() {
034: return request;
035: }
036:
037: public void setHttpServletRequest(HttpServletRequest request) {
038: this .request = request;
039: }
040:
041: public HttpServletResponse getHttpServletResponse() {
042: return response;
043: }
044:
045: public void setHttpServletResponse(HttpServletResponse response) {
046: this .response = response;
047: }
048:
049: public ActionConfig getActionConfig() {
050: return config;
051: }
052:
053: public Object getAction() {
054: return action;
055: }
056:
057: public String getActionPath() {
058: return config.actionPath;
059: }
060:
061: public WebApplication getWebApplication() {
062: return webapp;
063: }
064:
065: public boolean isExecuted() {
066: return executed;
067: }
068:
069: public boolean isRendered() {
070: return rendered;
071: }
072:
073: // ---------------------------------------------------------------- ctor
074:
075: /**
076: * Creates new action request.
077: */
078: protected ActionRequest(WebApplication webapp, ActionConfig config,
079: HttpServletRequest request, HttpServletResponse response) {
080: this .webapp = webapp;
081: this .config = config;
082: this .request = request;
083: this .response = response;
084:
085: totalInterceptors = (this .config.interceptors != null ? this .config.interceptors.length
086: : 0);
087: interceptorIndex = 0;
088: this .action = webapp.buildAction(config);
089: }
090:
091: // ---------------------------------------------------------------- invoke
092:
093: /**
094: * Invokes all interceptors and the action.
095: * @see #render(String)
096: * @return action result value
097: */
098: public String invoke() throws Exception {
099: if (executed == true) {
100: throw new MadvocException("Action '" + config.actionPath
101: + "' has already been executed.");
102: }
103: // interceptors
104: if (interceptorIndex < totalInterceptors) {
105: ActionInterceptor interceptor = config.interceptors[interceptorIndex];
106: interceptorIndex++;
107: return interceptor.intercept(this );
108: }
109: // action
110: config.usage++;
111: Object actionInvocationResult = config.actionMethod
112: .invoke(action);
113: executed = true;
114: return (actionInvocationResult != null ? actionInvocationResult
115: .toString() : null);
116: }
117:
118: // ---------------------------------------------------------------- result
119:
120: protected String resultName;
121:
122: protected String resultValue;
123:
124: /**
125: * Returns result name. Availiable only after rendering.
126: */
127: public String getResultName() {
128: return resultName;
129: }
130:
131: /**
132: * Returns result value. Availiable only after rendering.
133: */
134: public String getResultValue() {
135: return resultValue;
136: }
137:
138: /**
139: * Invokes a result after the action invocation.
140: * @see #invoke()
141: */
142: public void render(String value) throws Exception {
143: if (executed == false) {
144: throw new MadvocException(
145: "Result can not be rendered before the action.");
146: }
147: if (rendered == true) {
148: throw new MadvocException("Result for action '"
149: + config.actionPath + "' already rendered.");
150: }
151: resultValue = value;
152: if (resultValue == null) {
153: return;
154: }
155:
156: resultName = webapp.getDefaultActionResultName();
157: int columnIndex = resultValue.indexOf(':');
158: if (columnIndex != -1) {
159: resultName = resultValue.substring(0, columnIndex);
160: resultValue = resultValue.substring(columnIndex + 1);
161: }
162: resultValue = buildResultTarget(config.actionPath, resultValue);
163: resultValue = webapp.getResultAlias(resultValue);
164: columnIndex = resultValue.indexOf(':');
165: if (columnIndex != -1) {
166: resultName = resultValue.substring(0, columnIndex);
167: resultValue = resultValue.substring(columnIndex + 1);
168: }
169:
170: ActionResult result = webapp.lookupActionResult(resultName);
171: if (result == null) {
172: throw new MadvocException("Unable to find action result '"
173: + resultName + "'.");
174: }
175:
176: result.execute(this , resultValue);
177: rendered = true;
178: }
179:
180: /**
181: * Builds result target string by inserting result value after the path
182: * and before the extension. Extension is stripped.
183: * If result value starts with '/' then it represents an absolute path
184: * and it will be returned as is.
185: * If result value starts with '.' then method name will be also stripped.
186: */
187: protected String buildResultTarget(String actionPath,
188: String resultValue) {
189: if (resultValue.startsWith("/")) {
190: return resultValue;
191: }
192: int slashNdx = actionPath.lastIndexOf('/');
193: if (slashNdx == -1) {
194: slashNdx = 0;
195: }
196: int ndx = StringUtil.lastIndexOf(actionPath, '.', actionPath
197: .length(), slashNdx);
198: if (ndx != -1) {
199: actionPath = actionPath.substring(0, ndx);
200: }
201: boolean dot = true;
202: if (resultValue.startsWith(".")) {
203: ndx = StringUtil.lastIndexOf(actionPath, '.', actionPath
204: .length(), slashNdx);
205: if (ndx != -1) {
206: actionPath = actionPath.substring(0, ndx);
207: dot = false;
208: }
209: }
210: StringBuilder target = new StringBuilder(actionPath.length()
211: + resultValue.length() + 8);
212: target.append(actionPath);
213: if (resultValue.length() != 0) {
214: if (dot == true) {
215: target.append('.');
216: }
217: target.append(resultValue);
218: }
219: return target.toString();
220: }
221: }
|