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.HashMap;
22  import java.util.Map;
23  
24  import org.apache.myfaces.trinidad.bean.FacesBean;
25  import org.apache.myfaces.trinidad.bean.PropertyKey;
26  import org.apache.myfaces.trinidad.bean.PropertyMap;
27  
28  import javax.faces.context.FacesContext;
29  
30  public class PropertyHashMap extends HashMap<PropertyKey,Object>
31                               implements PropertyMap
32  {
33    public PropertyHashMap(
34      PropertyMap map)
35    {
36      super(map);
37    }
38  
39    public PropertyHashMap(
40      int   initialCapacity,
41      float loadFactor)
42    {
43      super(initialCapacity, loadFactor);
44   }
45  
46    public PropertyHashMap(
47      int initialCapacity)
48    {
49      super(initialCapacity);
50    }
51  
52    public PropertyHashMap()
53    {
54      super();
55    }
56  
57    @Override
58    public Object put(
59      PropertyKey key,
60      Object      value)
61    {
62      Object retValue = super.put(key, value);
63      if (_createDeltas())
64      {
65        if (!_equals(value, retValue))
66          _deltas.put(key, value);
67      }
68  
69      return retValue;
70    }
71  
72    @Override
73    public Object remove(
74      Object key)
75    {
76      if (_createDeltas())
77      {
78        if (!super.containsKey(key))
79          return null;
80        
81        // If this key is contained, it certainly must be a PropertyKey!
82        assert(key instanceof PropertyKey);
83        _deltas.put((PropertyKey) key, null);
84      }
85  
86      return super.remove(key);
87    }
88  
89    @Override
90    public void putAll(Map<? extends PropertyKey, ? extends Object> t)
91    {
92      if (_createDeltas())
93        _deltas.putAll(t);
94  
95      super.putAll(t);
96    }
97  
98    public Object saveState(FacesContext context)
99    {
100     if (_initialStateMarked)
101     {
102       if (_deltas == null)
103         return null;
104 
105       return StateUtils.saveState(_deltas, context, getUseStateHolder());
106     }
107     else
108     {
109       return StateUtils.saveState(this, context, getUseStateHolder());
110     }
111   }
112 
113   public void restoreState(
114     FacesContext context,
115     FacesBean.Type type,
116     Object state)
117   {
118     StateUtils.restoreState(this, context, type, state, getUseStateHolder());
119   }
120 
121 
122   protected PropertyMap createDeltaPropertyMap()
123   {
124     PropertyHashMap map = new PropertyHashMap(2);
125     map.setUseStateHolder(getUseStateHolder());
126     return map;
127   }
128 
129 
130   public boolean getUseStateHolder()
131   {
132     return _useStateHolder;
133   }
134 
135   public void setUseStateHolder(boolean useStateHolder)
136   {
137     _useStateHolder = useStateHolder;
138   }
139 
140 
141   // =-=AEW CLEAR?
142 
143   public void markInitialState()
144   {
145     _initialStateMarked = true;
146   }
147 
148 
149   private boolean _createDeltas()
150   {
151     if (_initialStateMarked)
152     {
153       if (_deltas == null)
154       {
155         _deltas = createDeltaPropertyMap();
156       }
157 
158       return true;
159     }
160     
161     return false;
162   }
163 
164   static private boolean _equals(Object a, Object b)
165   {
166     if (a == b)
167       return true;
168 
169     if (a == null)
170       return false;
171 
172     return a.equals(b);
173   }
174 
175   private transient boolean _initialStateMarked;
176   private transient PropertyMap _deltas;
177   private boolean      _useStateHolder;
178 
179   private static final long serialVersionUID = 1L;
180 }