View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.orchestra.flow.config;
20  
21  import java.io.Serializable;
22  
23  import javax.el.ELContext;
24  import javax.el.ValueExpression;
25  import javax.faces.context.FacesContext;
26  
27  import org.apache.myfaces.orchestra.flow.FlowTypeConverter;
28  import org.apache.myfaces.orchestra.flow.utils._ExpressionFactory;
29  import org.apache.myfaces.orchestra.lib.OrchestraException;
30  
31  /**
32   * Defines how a parameter value provided by a flow caller is imported
33   * into the called flow's environment.
34   */
35  public class FlowParamAccept implements Serializable
36  {
37      // For serialization. IMPORTANT; update this when changing the
38      // binary format of this class (eg adding fields).
39      private static final long serialVersionUID = 1L;
40  
41      private String name;
42      private String dst;
43      private ValueExpression dstExpr;
44      private String dflt;
45      private ValueExpression dfltExpr;
46      private String converter;
47      private ValueExpression converterExpr;
48  
49      /** Constructor. */
50      public FlowParamAccept()
51      {
52      }
53  
54      /**
55       * Check that all the properties of this object have valid values, ie
56       * whether the configuration specified by the user is valid.
57       */
58      public void validate()
59      {
60          if (name == null)
61          {
62              throw new OrchestraException("name is null");
63          }
64  
65          if (dst == null)
66          {
67              throw new OrchestraException("dst is null");
68          }
69  
70          // dflt is optional
71      }
72  
73      /**
74       * Define the name of this parameter.
75       * <p>
76       * The caller is expected to define a parameter with a matching name;
77       * it is an error for the caller to not provide a matching value - 
78       * unless this object has a non-null dflt property.
79       * <p> 
80       * Null is never returned.
81       */
82      public String getName()
83      {
84          return name;
85      }
86  
87      /** For use only during object initialization. */
88      public void setName(String name)
89      {
90          this.name = name;
91      }
92  
93      /**
94       * An EL expression which defines where the actual value passed by the caller
95       * should be stored within the called flow's environment.
96       * <p>
97       * Null is never returned.
98       */
99      public String getDst()
100     {
101         return dst;
102     }
103 
104     /** For use only during object initialization. */
105     public void setDst(String expr)
106     {
107         this.dst = expr;
108 
109         FacesContext fc = FacesContext.getCurrentInstance();
110         dstExpr = _ExpressionFactory.createValueExpression(fc, dst);
111     }
112 
113     public void setDstValue(FacesContext facesContext, Object newValue)
114     {
115         if (dstExpr != null)
116         {
117             // note: dst is null when the caller doesn't want to use the returned value.
118             ELContext elc = facesContext.getELContext();
119             if (converterExpr != null)
120             {
121                 FlowTypeConverter conv = (FlowTypeConverter) converterExpr.getValue(elc);
122                 if (conv != null)
123                 {
124                     newValue = conv.convert(newValue);
125                 }
126                 else
127                 {
128                     // There is an expression for converter, but the expression returns
129                     // null, or the expression could not be evaluated. We don't treat
130                     // this as an error here, because a flow may well need a converter
131                     // in some circumstances and not in others. Ignoring a missing
132                     // converter here makes those use-cases easier.
133                 }
134             }
135             dstExpr.setValue(elc, newValue);
136         }
137     }
138 
139     /**
140      * An EL expression which defines a default value to use when the caller
141      * does not specify a value for this input parameter.
142      * <p>
143      * Optional; if this is not defined then an error is reported if a
144      * caller does not provide an actual value for this named parameter.
145      * <p>
146      * Note that this EL expression is evaluated within the environment of the
147      * called flow, not the caller.
148      */
149     public String getDflt()
150     {
151         return dflt;
152     }
153 
154     /** For use only during object initialization. */
155     public void setDflt(String dflt)
156     {
157         this.dflt = dflt;
158 
159         FacesContext fc = FacesContext.getCurrentInstance();
160         dfltExpr = _ExpressionFactory.createValueExpression(fc, dflt);
161     }
162 
163     /**
164      * Evaluate the src EL expression and return the resulting object (or null).
165      */
166     public Object getDfltValue(FacesContext facesContext)
167     {
168         return dfltExpr.getValue(facesContext.getELContext());
169     }
170 
171     /**
172      * An optional EL expression which maps to a FlowTypeConverter instance that will
173      * be used to transform the input parameter before it is assigned to dst.
174      * <p>
175      * Note that this EL expression is evaluated within the environment of the
176      * called flow, not the caller.
177      */
178     public String getConverter()
179     {
180         return converter;
181     }
182 
183     /** For use only during object initialization. */
184     public void setConverter(String converter)
185     {
186         this.converter = converter;
187 
188         FacesContext fc = FacesContext.getCurrentInstance();
189         converterExpr = _ExpressionFactory.createValueExpression(fc, converter);
190     }
191 }