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.cdi.impl;
20  
21  import java.util.Map;
22  import javax.enterprise.inject.spi.BeanManager;
23  import javax.faces.context.ExternalContext;
24  import javax.faces.context.FacesContext;
25  import javax.servlet.ServletContext;
26  import org.apache.myfaces.cdi.util.BeanProvider;
27  import org.apache.myfaces.cdi.util.CDIUtils;
28  import org.apache.myfaces.cdi.JsfApplicationArtifactHolder;
29  import org.apache.myfaces.cdi.view.ViewScopeBeanHolder;
30  import org.apache.myfaces.cdi.view.ViewScopeCDIMap;
31  import org.apache.myfaces.flow.cdi.FlowScopeBeanHolder;
32  import org.apache.myfaces.spi.ViewScopeProvider;
33  
34  /**
35   *
36   * @author Leonardo Uribe
37   */
38  public class CDIManagedBeanHandlerImpl extends ViewScopeProvider
39  {
40      
41      private BeanManager beanManager;
42      
43      private ViewScopeBeanHolder viewScopeBeanHolder;
44      
45      private FlowScopeBeanHolder flowScopeBeanHolder;
46      
47      public CDIManagedBeanHandlerImpl()
48      {
49          ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
50          beanManager = CDIUtils.getBeanManager(externalContext);
51          Object context = externalContext.getContext();
52          if (context instanceof ServletContext)
53          {
54              JsfApplicationArtifactHolder appBean = CDIUtils.lookup(beanManager, 
55                  JsfApplicationArtifactHolder.class);
56              appBean.setServletContext((ServletContext) context);
57          }
58      }
59      
60      private ViewScopeBeanHolder getViewScopeBeanHolder()
61      {
62          if (viewScopeBeanHolder == null)
63          {
64              viewScopeBeanHolder = BeanProvider.getContextualReference(
65                  beanManager, ViewScopeBeanHolder.class, false);
66          }
67          return viewScopeBeanHolder;
68      }
69      
70      private FlowScopeBeanHolder getFlowScopeBeanHolder()
71      {
72          if (flowScopeBeanHolder == null)
73          {
74              flowScopeBeanHolder = BeanProvider.getContextualReference(
75                  beanManager, FlowScopeBeanHolder.class, false);
76          }
77          return flowScopeBeanHolder;
78      }
79      
80      public Map<String, Object> createViewScopeMap(FacesContext facesContext, String viewScopeId)
81      {
82          return new ViewScopeCDIMap(facesContext, viewScopeId);
83      }
84      
85      public Map<String, Object> restoreViewScopeMap(FacesContext facesContext, String viewScopeId)
86      {
87          return new ViewScopeCDIMap(facesContext, viewScopeId);
88      }
89      
90      public String generateViewScopeId(FacesContext facesContext)
91      {
92          return getViewScopeBeanHolder().generateUniqueViewScopeId();
93      }
94      
95      /**
96       * 
97       */
98      public void onSessionDestroyed()
99      {
100         // In CDI case, the best way to deal with this is use a method 
101         // with @PreDestroy annotation on a session scope bean 
102         // ( ViewScopeBeanHolder.destroyBeans() ). There is no need
103         // to do anything else in this location, but it is advised
104         // in CDI the beans are destroyed at the end of the request,
105         // not when invalidateSession() is called.
106         FacesContext facesContext = FacesContext.getCurrentInstance();
107         if (facesContext != null)
108         {
109             if (facesContext.getExternalContext().getSession(false) != null)
110             {
111                 if (isViewScopeBeanHolderCreated(facesContext))
112                 {
113                     getViewScopeBeanHolder().destroyBeans();                
114                 }
115                 if (isFlowScopeBeanHolderCreated(facesContext))
116                 {
117                     getFlowScopeBeanHolder().destroyBeans();
118                 }
119             }
120         }
121     }
122     
123     private boolean isViewScopeBeanHolderCreated(FacesContext facesContext)
124     {
125         return facesContext.getExternalContext().
126             getSessionMap().containsKey(ViewScopeBeanHolder.VIEW_SCOPE_PREFIX_KEY);
127     }
128     
129     
130     private boolean isFlowScopeBeanHolderCreated(FacesContext facesContext)
131     {
132         return facesContext.getExternalContext().
133             getSessionMap().containsKey(FlowScopeBeanHolder.FLOW_SCOPE_PREFIX_KEY);
134     }
135 
136     @Override
137     public void destroyViewScopeMap(FacesContext facesContext, String viewScopeId)
138     {
139         if (facesContext.getExternalContext().getSession(false) != null)
140         {
141             if (isViewScopeBeanHolderCreated(facesContext))
142             {
143                 getViewScopeBeanHolder().destroyBeans(viewScopeId);
144             }
145         }
146     }
147 }