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.trinidad.bean.util;
20  
21  import java.util.AbstractMap;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.Iterator;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import javax.faces.context.FacesContext;
29  
30  import org.apache.myfaces.trinidad.bean.FacesBean;
31  import org.apache.myfaces.trinidad.bean.PropertyKey;
32  import org.apache.myfaces.trinidad.bean.PropertyMap;
33  
34  
35  public class FlaggedPropertyMap extends AbstractMap<PropertyKey,Object>
36                                  implements PropertyMap
37  {
38    @Override
39    public boolean containsKey(
40      Object key)
41    {
42      PropertyKey pKey = (PropertyKey) key;
43      int index = pKey.getIndex();
44  
45      if (index >= 0 && index < 64)
46      {
47        // if we don't have the property, don't search the map
48        return ((_flags & (1L << index)) == 0);
49      }
50  
51      Map<PropertyKey, Object> map = getPropertyMap(false);
52      return (map != null) ? map.containsKey(pKey) : false;
53    }
54  
55    @Override
56    public Object get(
57      Object key)
58    {
59      PropertyKey pKey = (PropertyKey) key;
60      int index = pKey.getIndex();
61  
62      if (index >= 0 && index < 64)
63      {
64        // if we don't have the property, don't search the map
65        if ((_flags & (1L << index)) == 0)
66        {
67          return null;
68        }
69      }
70  
71      Map<PropertyKey, Object> map = getPropertyMap(false);
72      return (map != null) ? map.get(key) : null;
73    }
74  
75    @Override
76    public Object put(
77      PropertyKey key,
78      Object      value)
79    {
80      int index = key.getIndex();
81  
82      if (index >= 0 && index < 64)
83      {
84        // set the property mask
85        _flags |= (1L << index);
86      }
87  
88      Map<PropertyKey, Object> map = getPropertyMap(true);
89      return map.put(key, value);
90    }
91  
92    @Override
93    public Object remove(
94      Object key)
95    {
96      PropertyKey pKey = (PropertyKey) key;
97      int index = pKey.getIndex();
98  
99      if (index >= 0 && index < 64)
100     {
101       long propertyMask = (1L << index);
102 
103       // if we don't have the property, don't search the map
104       if ((_flags & propertyMask) == 0)
105       {
106         return null;
107       }
108 
109       // clear the property mask
110       _flags &= ~propertyMask;
111     }
112 
113     Map<PropertyKey, Object> map = getPropertyMap(false);
114     return (map != null) ? map.remove(key) : null;
115   }
116 
117   @Override
118   public void putAll(Map<? extends PropertyKey, ? extends Object> t)
119   {
120     Iterator<? extends PropertyKey> iter = t.keySet().iterator();
121 
122     PropertyKey key;
123 
124     while(iter.hasNext())
125     {
126       key = iter.next();
127       int index = key.getIndex();
128 
129       if (index >= 0 && index < 64)
130       {
131         long propertyMask = (1L << index);
132         // set the property mask
133         _flags |= propertyMask;
134       }
135     }
136 
137     Map<PropertyKey, Object> map = getPropertyMap(true);
138     map.putAll(t);
139   }
140 
141   @Override
142   public Set<Map.Entry<PropertyKey, Object>> entrySet()
143   {
144     Map<PropertyKey, Object> map = getPropertyMap(false);
145     if ((map == null) || map.isEmpty())
146       return Collections.emptySet();
147 
148     return map.entrySet();
149   }
150 
151   // TODO Optimize to take advantage of flags.
152   @Override
153   public Set<PropertyKey> keySet()
154   {
155     Map<PropertyKey, Object> map = getPropertyMap(false);
156     if ((map == null) || map.isEmpty())
157       return Collections.emptySet();
158 
159     return map.keySet();
160   }
161 
162   @Override
163   public Collection<Object> values()
164   {
165     Map<PropertyKey, Object> map = getPropertyMap(false);
166     if ((map == null) || map.isEmpty())
167       return Collections.emptySet();
168 
169     return map.values();
170   }
171 
172   public void markInitialState()
173   {
174     PropertyMap map = getPropertyMap(false);
175     if (map != null)
176       map.markInitialState();
177   }
178 
179   public void clearInitialState()
180   {
181     PropertyMap map = getPropertyMap(false);
182     if (map != null)
183       map.clearInitialState();
184   }
185 
186   public boolean initialStateMarked()
187   {
188     PropertyMap map = getPropertyMap(false);
189 
190     if (map != null)
191       return map.initialStateMarked();
192 
193     // TODO gcrawford - do something better?
194     return false;
195   }
196 
197   public Object saveState(FacesContext context)
198   {
199     PropertyMap map = getPropertyMap(false);
200     if (map != null)
201       return map.saveState(context);
202     return null;
203   }
204 
205   public void restoreState(
206     FacesContext context,
207     FacesBean.Type type,
208     Object state)
209   {
210     // We have to go through ourselves to restore state so that the
211     // flags will be set up correctly
212     StateUtils.restoreState(this, context, type, state, getUseStateHolder());
213   }
214 
215   public boolean getUseStateHolder()
216   {
217     return _useStateHolder;
218   }
219 
220   public void setUseStateHolder(boolean useStateHolder)
221   {
222     _useStateHolder = useStateHolder;
223   }
224   
225   /**
226    * Sets the the FacesBean type used by this map's owner bean
227    * @param type FacesBean type
228    */
229   public void setType(FacesBean.Type type)
230   {
231     _type = type;
232   }
233   
234   /**
235    * Retrieves FacesBean type used by this map's owner bean
236    * @return FacesBean type
237    */
238   protected FacesBean.Type getType()
239   {
240     return _type;
241   }
242 
243   protected PropertyMap getPropertyMap(
244     boolean createIfNull)
245   {
246     PropertyMap map = _map;
247 
248     if (map == null && createIfNull)
249     {
250       map = _map = createMap();
251     }
252 
253     return map;
254   }
255 
256   protected PropertyMap createMap()
257   {
258     PropertyHashMap map = new PropertyHashMap();
259     map.setUseStateHolder(getUseStateHolder());
260     map.setType(_type);
261     return map;
262   }
263 
264   private PropertyMap    _map;
265   private long           _flags;
266   private boolean        _useStateHolder;
267   private FacesBean.Type _type;
268 }