2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.dialog.scxml;
19  
20  import java.util.regex.Pattern;
21  
22  import javax.faces.context.FacesContext;
23  import javax.faces.el.EvaluationException;
24  import javax.faces.el.MethodBinding;
25  import javax.faces.el.MethodNotFoundException;
26  import javax.faces.el.ReferenceSyntaxException;
27  
28  import org.apache.commons.scxml.Context;
29  import org.apache.commons.scxml.SCXMLExpressionException;
30  import org.apache.commons.scxml.env.jsp.ELEvaluator;
31  
32  
33  /***
34   * <p>EL evaluator, for evaluating the expressions in SCXML documents used
35   * to specify Shale dialogs.</p>
36   *
37   * <p>This evaluator uses the following premises for evaluation:
38   *   <ol>
39   *     <li>JSF method binding expressions will take the form:
40   *         #{...}
41   *         These will return a <code>java.lang.String</code> object as
42   *         required by the methods associated with
43   *         <code>org.apache.shale.dialog.ActionState</code></li>
44   *     <li>JSP 2.0 EL expressions will take the form:
45   *         ${...}</li>
46   *   </ol>
47   * </p>
48   *
49   * <p>This evaluator delegates to the following expression evaluators:
50   *   <ol>
51   *     <li>JSF method binding expressions get delegated to the JSF
52   *         implementation (Ex: Apache MyFaces).</li>
53   *     <li>JSP expressions get delegated to the Apache Jakarta Commons
54   *         EL ExpressionEvaluator implementation. This evaluator adds
55   *         ability to evaluate special predicates defined by SCXML.</li>
56   *   </ol>
57   * </p>
58   *
59   * @since 1.0.4
60   *
61   * $Id: ShaleDialogELEvaluator.java 481499 2006-12-02 03:47:39Z rahul $
62   */
63  
64  public class ShaleDialogELEvaluator extends ELEvaluator {
65  
66  
67      /***
68       * Shale ActionState method parameters.
69       */
70      private static final Object[] PARAMETERS = new Object[0];
71  
72  
73      /***
74       * Shale ActionState method signature.
75       */
76      private static final Class[] SIGNATURE = new Class[0];
77  
78  
79      // We do not have the privilege of having specific element attributes
80      // associated with specific types of expressions
81      /*** Pattern for recognizing the method / value binding expression. */
82      private static Pattern jsfBindingExpr =
83          Pattern.compile("^//s*#//{.*//}//s*$");
84  
85  
86      /*** FacesContext for this request. */
87      private transient FacesContext context;
88  
89  
90      /***
91       * Constructor.
92       */
93      public ShaleDialogELEvaluator() {
94          super();
95          this.context = null;
96      }
97  
98  
99      /***
100      * Set per request context.
101      *
102      * @param context The FacesContext for this request.
103      */
104     public void setFacesContext(final FacesContext context) {
105         this.context = context;
106     }
107 
108 
109     /***
110      * Evaluate an expression.
111      *
112      * @param ctx variable context
113      * @param expr expression
114      * @return Object The result of the evaluation
115      * @throws SCXMLExpressionException For a malformed expression
116      * @see ELEvaluator#eval(Context, String)
117      */
118     public Object eval(final Context ctx, final String expr)
119     throws SCXMLExpressionException {
120 
121         if (jsfBindingExpr.matcher(expr).matches()) {
122             return invokeShaleActionStateMethod(expr);
123         }
124 
125         return super.eval(ctx, expr);
126     }
127 
128 
129     /***
130      * Invoke method binding expression for Shale <code>ActionState</code>.
131      * Shale requires return type to be a <code>java.lang.String</code>.
132      *
133      * @param expr Method binding expression
134      * @return String Method return value
135      * @throws SCXMLExpressionException Re-throw potential Faces
136      *                  exceptions as a SCXMLExpressionException.
137      */
138     private String invokeShaleActionStateMethod(final String expr)
139     throws SCXMLExpressionException {
140 
141         try {
142 
143             MethodBinding mb = context.getApplication().
144                 createMethodBinding(expr, SIGNATURE);
145             return (String) mb.invoke(context, PARAMETERS);
146 
147         //Rethrow any exception as SCXMLExpressionException instance
148         } catch (ReferenceSyntaxException rse) {
149 
150             throw new SCXMLExpressionException(rse.getMessage(), rse);
151 
152         } catch (MethodNotFoundException mnfe) {
153 
154             throw new SCXMLExpressionException(mnfe.getMessage(), mnfe);
155 
156         } catch (EvaluationException ee) {
157 
158             throw new SCXMLExpressionException(ee.getMessage(), ee);
159 
160         }
161     }
162 
163 }