001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.services;
016:
017: import java.io.IOException;
018:
019: import org.apache.tapestry.TapestryConstants;
020: import org.apache.tapestry.internal.InternalConstants;
021: import org.apache.tapestry.internal.TapestryInternalUtils;
022: import org.apache.tapestry.services.ActionResponseGenerator;
023: import org.apache.tapestry.services.ComponentActionRequestHandler;
024: import org.apache.tapestry.services.Dispatcher;
025: import org.apache.tapestry.services.Request;
026: import org.apache.tapestry.services.Response;
027:
028: /**
029: * Processes component action events sent as requests from the client. Action events include an
030: * event type, identify a page and a component, and may provide additional context strings.
031: */
032: public class ComponentActionDispatcher implements Dispatcher {
033: private final ComponentActionRequestHandler _componentActionRequestHandler;
034:
035: private final String[] _emptyString = new String[0];
036:
037: public ComponentActionDispatcher(
038: ComponentActionRequestHandler componentActionRequestHandler) {
039: _componentActionRequestHandler = componentActionRequestHandler;
040: }
041:
042: public boolean dispatch(Request request, Response response)
043: throws IOException {
044: String path = request.getPath();
045:
046: String logicalPageName = null;
047: String nestedComponentId = "";
048: String eventType = TapestryConstants.ACTION_EVENT;
049:
050: // Will always have a dot or a colon
051:
052: int dotx = path.indexOf('.');
053: int colonx = path.indexOf(':');
054:
055: int contextStart = -1;
056:
057: if (dotx > 0) {
058: logicalPageName = path.substring(1, dotx);
059:
060: int slashx = path.indexOf('/', dotx + 1);
061:
062: // The nested id ends at the colon (if present) or
063: // the first slash (if present) or the end of the path.
064:
065: if (slashx < 0) {
066: slashx = path.length();
067: } else {
068: contextStart = slashx + 1;
069: }
070:
071: int nestedIdEnd = slashx;
072:
073: if (colonx > 0 && colonx < slashx) {
074: nestedIdEnd = colonx;
075: eventType = path.substring(colonx + 1, slashx);
076: }
077:
078: nestedComponentId = path.substring(dotx + 1, nestedIdEnd);
079: } else if (colonx > 0) {
080: // No dot, but a colon. Therefore no nested component id, but an action name and
081: // maybe some event context.
082:
083: int slashx = path.indexOf('/', colonx + 1);
084: if (slashx < 0) {
085: slashx = path.length();
086: } else {
087: contextStart = slashx + 1;
088: }
089:
090: eventType = path.substring(colonx + 1, slashx);
091: logicalPageName = path.substring(1, colonx);
092: }
093:
094: if (logicalPageName == null)
095: return false;
096:
097: String[] eventContext = contextStart > 0 ? decodeContext(path
098: .substring(contextStart)) : _emptyString;
099:
100: String activationContextValue = request
101: .getParameter(InternalConstants.PAGE_CONTEXT_NAME);
102:
103: String[] activationContext = activationContextValue == null ? _emptyString
104: : decodeContext(activationContextValue);
105:
106: ActionResponseGenerator responseGenerator = _componentActionRequestHandler
107: .handle(logicalPageName, nestedComponentId, eventType,
108: eventContext, activationContext);
109:
110: responseGenerator.sendClientResponse(response);
111:
112: return true;
113: }
114:
115: private String[] decodeContext(String input) {
116: String[] result = input.split("/");
117:
118: for (int i = 0; i < result.length; i++) {
119: result[i] = TapestryInternalUtils.urlDecode(result[i]);
120: }
121:
122: return result;
123: }
124:
125: }
|