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  
20  package org.apache.myfaces.cdi.view;
21  
22  
23  import javax.enterprise.context.spi.Contextual;
24  import javax.enterprise.context.spi.CreationalContext;
25  import javax.enterprise.inject.spi.BeanManager;
26  import javax.enterprise.inject.spi.PassivationCapable;
27  import java.io.Serializable;
28  import java.util.HashMap;
29  import java.util.Map;
30  import javax.enterprise.inject.spi.Bean;
31  import javax.faces.context.FacesContext;
32  import org.apache.myfaces.cdi.util.CDIUtils;
33  import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
34  
35  /**
36   * This Storage holds all information needed for storing
37   * View Scope instances in a context.
38   * 
39   * This scope requires passivation and is not concurrent.
40   */
41  public class ViewScopeContextualStorage implements Serializable
42  {
43      private static final long serialVersionUID = 1L;
44  
45      private final Map<Object, ContextualInstanceInfo<?>> contextualInstances;
46      
47      private final Map<String, Object> nameBeanKeyMap;
48      
49      private transient BeanManager beanManager;
50      
51      private transient volatile boolean deactivated;
52  
53      /**
54       * @param beanManager is needed for serialisation
55       */
56      public ViewScopeContextualStorage(BeanManager beanManager)
57      {
58          this.beanManager = beanManager;
59          contextualInstances = new HashMap<Object, ContextualInstanceInfo<?>>();
60          nameBeanKeyMap = new HashMap<String, Object>();
61          deactivated = false;
62      }
63  
64      /**
65       * @return the underlying storage map.
66       */
67      public Map<Object, ContextualInstanceInfo<?>> getStorage()
68      {
69          return contextualInstances;
70      }
71      
72      public Map<String, Object> getNameBeanKeyMap()
73      {
74          return nameBeanKeyMap;
75      }
76  
77      /**
78       *
79       * @param bean
80       * @param creationalContext
81       * @param <T>
82       * @return
83       */
84      public <T> T createContextualInstance(Contextual<T> bean, CreationalContext<T> creationalContext)
85      {
86          Object beanKey = getBeanKey(bean);
87  
88          // simply create the contextual instance
89          ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
90          instanceInfo.setCreationalContext(creationalContext);
91          instanceInfo.setContextualInstance(bean.create(creationalContext));
92  
93          contextualInstances.put(beanKey, instanceInfo);
94          if(bean instanceof Bean)
95          {
96              String name = ((Bean<T>) bean).getName();
97              if (name != null)
98              {
99                  nameBeanKeyMap.put(name, beanKey);
100             }
101         }
102 
103         return instanceInfo.getContextualInstance();
104     }
105 
106     /**
107      * If the context is a passivating scope then we return
108      * the passivationId of the Bean. Otherwise we use
109      * the Bean directly.
110      * @return the key to use in the context map
111      */
112     public <T> Object getBeanKey(Contextual<T> bean)
113     {
114         return ((PassivationCapable) bean).getId();
115     }
116 
117     /**
118      * Restores the Bean from its beanKey.
119      * @see #getBeanKey(javax.enterprise.context.spi.Contextual)
120      */
121     public Contextual<?> getBean(FacesContext context, Object beanKey)
122     {
123         if (beanManager == null)
124         {
125             beanManager = CDIUtils.getBeanManager(context.getExternalContext());
126         }
127         return beanManager.getPassivationCapableBean((String) beanKey);
128     }
129     
130     public boolean isActive()
131     {
132         return !deactivated;
133     }
134     
135     public void deactivate()
136     {
137         deactivated = true;
138     }
139 }