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.flow.impl;
20  
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.concurrent.ConcurrentHashMap;
24  import javax.faces.context.ExternalContext;
25  import javax.faces.context.FacesContext;
26  import javax.faces.flow.Flow;
27  import org.apache.myfaces.flow.util.FlowUtils;
28  import org.apache.myfaces.spi.FacesFlowProvider;
29  
30  /**
31   *
32   * @author Leonardo Uribe
33   */
34  public class DefaultFacesFlowProvider extends FacesFlowProvider
35  {
36      private static final String FLOW_PREFIX = "oam.flow";
37      
38      static final String FLOW_SESSION_MAP_SUBKEY_PREFIX = FLOW_PREFIX + ".SCOPE";
39      
40      /**
41       * Token separator.
42       */
43      static final char SEPARATOR_CHAR = '.';
44      
45      private final static String CURRENT_FLOW_SCOPE_MAP = "oam.flow.SCOPE_MAP";
46  
47      @Override
48      public Iterator<Flow> getAnnotatedFlows(FacesContext facesContext)
49      {
50          //Without CDI there is no @FlowDefinition annotations to scan for
51          return null;
52      }
53  
54      @Override
55      public void doAfterEnterFlow(FacesContext facesContext, Flow flow)
56      {
57          // Reset current flow scope map
58          String mapKey = CURRENT_FLOW_SCOPE_MAP+SEPARATOR_CHAR+
59              flow.getDefiningDocumentId()+SEPARATOR_CHAR+flow.getId();        
60          facesContext.getAttributes().remove(mapKey);
61      }
62  
63      @Override
64      public void doBeforeExitFlow(FacesContext facesContext, Flow flow)
65      {
66          String flowMapKey = FlowUtils.getFlowMapKey(facesContext, flow);
67          String fullToken = FLOW_SESSION_MAP_SUBKEY_PREFIX + SEPARATOR_CHAR + flowMapKey;
68  
69          String mapKey = CURRENT_FLOW_SCOPE_MAP+SEPARATOR_CHAR+
70              flow.getDefiningDocumentId()+SEPARATOR_CHAR+flow.getId();
71          Map<Object, Object> map = (Map<Object, Object>) facesContext.getAttributes().get(
72              mapKey);
73          if (map != null)
74          {
75              map.clear();
76          }
77          else
78          {
79              map = (Map<Object, Object>) facesContext.getExternalContext().
80                  getSessionMap().get(fullToken);
81              if (map != null)
82              {
83                  map.clear();
84              }
85          }
86          // Remove the map from session
87          facesContext.getExternalContext().getSessionMap().remove(fullToken);
88          
89          // Reset current flow scope map
90          facesContext.getAttributes().remove(mapKey);
91      }
92  
93      @Override
94      public Map<Object, Object> getCurrentFlowScope(FacesContext facesContext)
95      {
96          Flow flow = facesContext.getApplication().getFlowHandler().getCurrentFlow(facesContext);
97          Map<Object, Object> map = null;
98          if (flow != null)
99          {
100             String mapKey = CURRENT_FLOW_SCOPE_MAP+SEPARATOR_CHAR+
101                 flow.getDefiningDocumentId()+SEPARATOR_CHAR+flow.getId();
102             map = (Map<Object, Object>) facesContext.getAttributes().get(mapKey);
103             if (map == null)
104             {
105                 String flowMapKey = FlowUtils.getFlowMapKey(facesContext, flow);
106                 
107                 //String fullToken = FLOW_SESSION_MAP_SUBKEY_PREFIX + SEPARATOR_CHAR + flowMapKey;
108                 //map = createOrRestoreMap(facesContext, fullToken);
109                 map = new FlowScopeMap(this, flowMapKey);
110                 
111                 facesContext.getAttributes().put(mapKey, map);
112             }
113         }
114         return map;
115     }
116     
117     /**
118      * Create a new subkey-wrapper of the session map with the given prefix.
119      * This wrapper is used to implement the maps for the flash scope.
120      * For more information see the SubKeyMap doc.
121      */
122     Map<Object, Object> createOrRestoreMap(FacesContext context, String prefix,
123         boolean create)
124     {
125         ExternalContext external = context.getExternalContext();
126         Map<String, Object> sessionMap = external.getSessionMap();
127 
128         Map<Object, Object> map = (Map<Object, Object>) sessionMap.get(prefix);
129         if (map == null && create)
130         {
131             map = new ConcurrentHashMap<Object, Object>();
132             sessionMap.put(prefix, map);
133         }
134         return map;
135     }
136 }