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 }