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  
27  import java.util.Set;
28  
29  import javax.faces.context.FacesContext;
30  
31  import org.apache.myfaces.trinidad.bean.FacesBean;
32  import org.apache.myfaces.trinidad.bean.PropertyKey;
33  import org.apache.myfaces.trinidad.bean.PropertyMap;
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 Object saveState(FacesContext context)
180   {
181     PropertyMap map = getPropertyMap(false);
182     if (map != null)
183       return map.saveState(context);
184     return null;
185   }
186 
187   public void restoreState(
188     FacesContext context,
189     FacesBean.Type type,
190     Object state)
191   {
192     // We have to go through ourselves to restore state so that the
193     // flags will be set up correctly
194     StateUtils.restoreState(this, context, type, state, getUseStateHolder());
195   }
196 
197 
198   public boolean getUseStateHolder()
199   {
200     return _useStateHolder;
201   }
202 
203   public void setUseStateHolder(boolean useStateHolder)
204   {
205     _useStateHolder = useStateHolder;
206   }
207 
208   protected PropertyMap getPropertyMap(
209     boolean createIfNull)
210   {
211     PropertyMap map = _map;
212 
213     if (map == null && createIfNull)
214     {
215       map = _map = createMap();
216     }
217 
218     return map;
219   }
220 
221   protected PropertyMap createMap()
222   {
223     PropertyHashMap map = new PropertyHashMap();
224     map.setUseStateHolder(getUseStateHolder());
225     return map;
226   }
227 
228   private PropertyMap  _map;
229   private long         _flags;
230   private boolean      _useStateHolder;
231 }