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.builder;
017:
018: import org.springframework.binding.convert.ConversionContext;
019: import org.springframework.binding.convert.ConversionException;
020: import org.springframework.binding.convert.support.AbstractConverter;
021: import org.springframework.binding.expression.Expression;
022: import org.springframework.util.StringUtils;
023: import org.springframework.webflow.engine.TransitionCriteria;
024: import org.springframework.webflow.engine.WildcardTransitionCriteria;
025: import org.springframework.webflow.engine.support.BooleanExpressionTransitionCriteria;
026: import org.springframework.webflow.engine.support.EventIdTransitionCriteria;
027:
028: /**
029: * Converter that takes an encoded string representation and produces a
030: * corresponding <code>TransitionCriteria</code> object.
031: * <p>
032: * This converter supports the following encoded forms:
033: * <ul>
034: * <li>"*" - will result in a TransitionCriteria object that matches on
035: * everything ({@link org.springframework.webflow.engine.WildcardTransitionCriteria})
036: * </li>
037: * <li>"eventId" - will result in a TransitionCriteria object that matches
038: * given event id ({@link org.springframework.webflow.engine.support.EventIdTransitionCriteria})
039: * </li>
040: * <li>"${...}" - will result in a TransitionCriteria object that evaluates
041: * given condition, expressed as an expression
042: * ({@link org.springframework.webflow.engine.support.BooleanExpressionTransitionCriteria})
043: * </li>
044: * <li>"bean:<id>" - will result in usage of a custom TransitionCriteria
045: * bean implementation.</li>
046: * </ul>
047: *
048: * @see org.springframework.webflow.engine.TransitionCriteria
049: *
050: * @author Keith Donald
051: * @author Erwin Vervaet
052: */
053: public class TextToTransitionCriteria extends AbstractConverter {
054:
055: /**
056: * Prefix used when the user wants to use a custom TransitionCriteria
057: * implementation managed by a bean factory.
058: */
059: private static final String BEAN_PREFIX = "bean:";
060:
061: /**
062: * Locator to use for loading custom TransitionCriteria beans.
063: */
064: private FlowServiceLocator flowServiceLocator;
065:
066: /**
067: * Create a new converter that converts strings to transition criteria
068: * objects. Custom transition criteria will be looked up using given
069: * service locator.
070: */
071: public TextToTransitionCriteria(
072: FlowServiceLocator flowServiceLocator) {
073: this .flowServiceLocator = flowServiceLocator;
074: }
075:
076: public Class[] getSourceClasses() {
077: return new Class[] { String.class };
078: }
079:
080: public Class[] getTargetClasses() {
081: return new Class[] { TransitionCriteria.class };
082: }
083:
084: protected Object doConvert(Object source, Class targetClass,
085: ConversionContext context) throws Exception {
086: String encodedCriteria = (String) source;
087: if (!StringUtils.hasText(encodedCriteria)
088: || WildcardTransitionCriteria.WILDCARD_EVENT_ID
089: .equals(encodedCriteria)) {
090: return WildcardTransitionCriteria.INSTANCE;
091: } else if (flowServiceLocator.getExpressionParser()
092: .isDelimitedExpression(encodedCriteria)) {
093: Expression expression = flowServiceLocator
094: .getExpressionParser().parseExpression(
095: encodedCriteria);
096: return createBooleanExpressionTransitionCriteria(expression);
097: } else if (encodedCriteria.startsWith(BEAN_PREFIX)) {
098: return flowServiceLocator
099: .getTransitionCriteria(encodedCriteria
100: .substring(BEAN_PREFIX.length()));
101: } else {
102: return createEventIdTransitionCriteria(encodedCriteria);
103: }
104: }
105:
106: /**
107: * Hook method subclasses can override to return a specialized eventId
108: * matching transition criteria implementation.
109: * @param eventId the event id to match
110: * @return the transition criteria object
111: * @throws ConversionException when something goes wrong
112: */
113: protected TransitionCriteria createEventIdTransitionCriteria(
114: String eventId) throws ConversionException {
115: return new EventIdTransitionCriteria(eventId);
116: }
117:
118: /**
119: * Hook method subclasses can override to return a specialized expression
120: * evaluating transition criteria implementation.
121: * @param expression the expression to evaluate
122: * @return the transition criteria object
123: * @throws ConversionException when something goes wrong
124: */
125: protected TransitionCriteria createBooleanExpressionTransitionCriteria(
126: Expression expression) throws ConversionException {
127: return new BooleanExpressionTransitionCriteria(expression);
128: }
129: }
|