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 return value from a flow is imported into the caller's environment.
33 */
34 public class FlowReturnAccept implements Serializable
35 {
36 // For serialization. IMPORTANT; update this when changing the
37 // binary format of this class (eg adding fields).
38 private static final long serialVersionUID = 1L;
39
40 private String name;
41 private String dst;
42 private ValueExpression dstExpr;
43 private String converter;
44 private ValueExpression converterExpr;
45
46 /** Constructor. */
47 public FlowReturnAccept()
48 {
49 }
50
51 /**
52 * Check that all the properties of this object have valid values, ie
53 * whether the configuration specified by the user is valid.
54 */
55 public void validate()
56 {
57 if (name == null)
58 {
59 throw new OrchestraException("name is null");
60 }
61
62 if (dst == null)
63 {
64 // This simply indicates that the flow is returning a value that the caller doesn't care about.
65 // The caller does need to add an entry to indicate that it knows the value is being returned,
66 // but leaving dst empty indicates that it doesn't want the value to be stored anywhere.
67 //
68 // log.debug("Calling flow is ignoring return value " + name);
69 }
70 }
71
72 /**
73 * Define the name of this parameter.
74 * <p>
75 * The called flow is expected to define a return parameter with a matching name.
76 * <p>
77 * Null is never returned.
78 */
79 public String getName()
80 {
81 return name;
82 }
83
84 /** For use only during object initialization. */
85 public void setName(String name)
86 {
87 this.name = name;
88 }
89
90 /**
91 * An EL expression which defines where the actual value passed back from the called
92 * flow should be stored within the caller's environment.
93 * <p>
94 * Null is never returned.
95 */
96 public String getDst()
97 {
98 return dst;
99 }
100
101 /** For use only during object initialization. */
102 public void setDst(String expr)
103 {
104 dst = expr;
105
106 FacesContext fc = FacesContext.getCurrentInstance();
107 dstExpr = _ExpressionFactory.createValueExpression(fc, dst);
108 }
109
110 public void setDstValue(FacesContext facesContext, Object newValue)
111 {
112 if (dstExpr != null)
113 {
114 // note: dst is null when the caller doesn't want to use the returned value.
115
116 ELContext elc = facesContext.getELContext();
117 if (converterExpr != null)
118 {
119 FlowTypeConverter conv = (FlowTypeConverter) converterExpr.getValue(elc);
120 if (conv != null)
121 {
122 newValue = conv.convert(newValue);
123 }
124 else
125 {
126 // There is an expression for converter, but the expression returns
127 // null, or the expression could not be evaluated. We don't treat
128 // this as an error here, because a flow may well need a converter
129 // in some circumstances and not in others. Ignoring a missing
130 // converter here makes those use-cases easier.
131 }
132 }
133
134 dstExpr.setValue(elc, newValue);
135 }
136 }
137
138 /**
139 * An optional EL expression which maps to a FlowTypeConverter instance that will
140 * be used to transform the input parameter before it is assigned to dst.
141 * <p>
142 * Note that this EL expression is evaluated within the environment of the
143 * called flow, not the caller. TODO: This is currently never called!
144 */
145 public String getConverter()
146 {
147 return converter;
148 }
149
150 /** For use only during object initialization. */
151 public void setConverter(String converter)
152 {
153 this.converter = converter;
154
155 FacesContext fc = FacesContext.getCurrentInstance();
156 converterExpr = _ExpressionFactory.createValueExpression(fc, converter);
157 }
158 }