001: /*
002: * Copyright 2004-2007 the original author or authors.
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 org.springframework.webflow.engine.support;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import org.springframework.binding.expression.Expression;
022: import org.springframework.util.StringUtils;
023: import org.springframework.webflow.engine.ViewSelector;
024: import org.springframework.webflow.execution.RequestContext;
025: import org.springframework.webflow.execution.ViewSelection;
026: import org.springframework.webflow.execution.support.FlowDefinitionRedirect;
027:
028: /**
029: * Makes a {@link FlowDefinitionRedirect} selection when requested, calculating the
030: * <code>flowDefinitionId</code> and <code>executionInput</code> by
031: * evaluating an expression against the request context.
032: *
033: * @see org.springframework.webflow.execution.support.FlowDefinitionRedirect
034: *
035: * @author Keith Donald
036: */
037: public class FlowDefinitionRedirectSelector implements ViewSelector {
038:
039: /**
040: * The parsed flow expression, evaluatable to the string format:
041: * flowDefinitionId?param1Name=parmValue¶m2Name=paramValue.
042: */
043: private Expression expression;
044:
045: /**
046: * Creates a new launch flow redirect selector.
047: * @param expression the parsed flow redirect expression, evaluatable to the
048: * string format: flowDefinitionId?param1Name=parmValue¶m2Name=paramValue
049: */
050: public FlowDefinitionRedirectSelector(Expression expression) {
051: this .expression = expression;
052: }
053:
054: public boolean isEntrySelectionRenderable(RequestContext context) {
055: return true;
056: }
057:
058: public ViewSelection makeEntrySelection(RequestContext context) {
059: String encodedRedirect = (String) expression.evaluate(context,
060: null);
061: if (encodedRedirect == null) {
062: throw new IllegalStateException(
063: "Flow definition redirect expression evaluated to [null], the expression was "
064: + expression);
065: }
066: // the encoded FlowDefinitionRedirect should look something like
067: // "flowDefinitionId?param0=value0¶m1=value1"
068: // now parse that and build a corresponding view selection
069: int index = encodedRedirect.indexOf('?');
070: String flowDefinitionId;
071: Map executionInput = null;
072: if (index != -1) {
073: flowDefinitionId = encodedRedirect.substring(0, index);
074: String[] parameters = StringUtils
075: .delimitedListToStringArray(encodedRedirect
076: .substring(index + 1), "&");
077: executionInput = new HashMap(parameters.length, 1);
078: for (int i = 0; i < parameters.length; i++) {
079: String nameAndValue = parameters[i];
080: index = nameAndValue.indexOf('=');
081: if (index != -1) {
082: executionInput.put(
083: nameAndValue.substring(0, index),
084: nameAndValue.substring(index + 1));
085: } else {
086: executionInput.put(nameAndValue, "");
087: }
088: }
089: } else {
090: flowDefinitionId = encodedRedirect;
091: }
092: if (!StringUtils.hasText(flowDefinitionId)) {
093: // equivalent to restart
094: flowDefinitionId = context.getFlowExecutionContext()
095: .getDefinition().getId();
096: }
097: return new FlowDefinitionRedirect(flowDefinitionId,
098: executionInput);
099: }
100:
101: public ViewSelection makeRefreshSelection(RequestContext context) {
102: return makeEntrySelection(context);
103: }
104: }
|