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 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 }