Upstream version 5.34.97.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / InMemorySharedPreferences.java
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.xwalk.core;
6
7 import android.content.SharedPreferences;
8
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.Map;
12 import java.util.Set;
13
14 /**
15  * An implementation of SharedPreferences that can be used to create XWalkBrowserContext.
16  * <p/>
17  * It keeps all state in memory, and there is no difference between apply() and commit().
18  */
19 public class InMemorySharedPreferences implements SharedPreferences {
20
21     // Guarded on its own monitor.
22     private final Map<String, Object> mData;
23
24     public InMemorySharedPreferences() {
25         mData = new HashMap<String, Object>();
26     }
27
28     public InMemorySharedPreferences(Map<String, Object> data) {
29         mData = data;
30     }
31
32     @Override
33     public Map<String, ?> getAll() {
34         synchronized (mData) {
35             return Collections.unmodifiableMap(mData);
36         }
37     }
38
39     @Override
40     public String getString(String key, String defValue) {
41         synchronized (mData) {
42             if (mData.containsKey(key)) {
43                 return (String) mData.get(key);
44             }
45         }
46         return defValue;
47     }
48
49     @SuppressWarnings("unchecked")
50     @Override
51     public Set<String> getStringSet(String key, Set<String> defValues) {
52         synchronized (mData) {
53             if (mData.containsKey(key)) {
54                 return Collections.unmodifiableSet((Set<String>) mData.get(key));
55             }
56         }
57         return defValues;
58     }
59
60     @Override
61     public int getInt(String key, int defValue) {
62         synchronized (mData) {
63             if (mData.containsKey(key)) {
64                 return (Integer) mData.get(key);
65             }
66         }
67         return defValue;
68     }
69
70     @Override
71     public long getLong(String key, long defValue) {
72         synchronized (mData) {
73             if (mData.containsKey(key)) {
74                 return (Long) mData.get(key);
75             }
76         }
77         return defValue;
78     }
79
80     @Override
81     public float getFloat(String key, float defValue) {
82         synchronized (mData) {
83             if (mData.containsKey(key)) {
84                 return (Float) mData.get(key);
85             }
86         }
87         return defValue;
88     }
89
90     @Override
91     public boolean getBoolean(String key, boolean defValue) {
92         synchronized (mData) {
93             if (mData.containsKey(key)) {
94                 return (Boolean) mData.get(key);
95             }
96         }
97         return defValue;
98     }
99
100     @Override
101     public boolean contains(String key) {
102         synchronized (mData) {
103             return mData.containsKey(key);
104         }
105     }
106
107     @Override
108     public SharedPreferences.Editor edit() {
109         return new InMemoryEditor();
110     }
111
112     @Override
113     public void registerOnSharedPreferenceChangeListener(
114             SharedPreferences.OnSharedPreferenceChangeListener
115                     listener) {
116         throw new UnsupportedOperationException();
117     }
118
119     @Override
120     public void unregisterOnSharedPreferenceChangeListener(
121             SharedPreferences.OnSharedPreferenceChangeListener listener) {
122         throw new UnsupportedOperationException();
123     }
124
125     private class InMemoryEditor implements SharedPreferences.Editor {
126
127         // All guarded by |mChanges|.
128         private boolean mClearCalled;
129         private volatile boolean mApplyCalled;
130         private final Map<String, Object> mChanges = new HashMap<String, Object>();
131
132         @Override
133         public SharedPreferences.Editor putString(String key, String value) {
134             synchronized (mChanges) {
135                 if (mApplyCalled) throw new IllegalStateException();
136                 mChanges.put(key, value);
137                 return this;
138             }
139         }
140
141         @Override
142         public SharedPreferences.Editor putStringSet(String key, Set<String> values) {
143             synchronized (mChanges) {
144                 if (mApplyCalled) throw new IllegalStateException();
145                 mChanges.put(key, values);
146                 return this;
147             }
148         }
149
150         @Override
151         public SharedPreferences.Editor putInt(String key, int value) {
152             synchronized (mChanges) {
153                 if (mApplyCalled) throw new IllegalStateException();
154                 mChanges.put(key, value);
155                 return this;
156             }
157         }
158
159         @Override
160         public SharedPreferences.Editor putLong(String key, long value) {
161             synchronized (mChanges) {
162                 if (mApplyCalled) throw new IllegalStateException();
163                 mChanges.put(key, value);
164                 return this;
165             }
166         }
167
168         @Override
169         public SharedPreferences.Editor putFloat(String key, float value) {
170             synchronized (mChanges) {
171                 if (mApplyCalled) throw new IllegalStateException();
172                 mChanges.put(key, value);
173                 return this;
174             }
175         }
176
177         @Override
178         public SharedPreferences.Editor putBoolean(String key, boolean value) {
179             synchronized (mChanges) {
180                 if (mApplyCalled) throw new IllegalStateException();
181                 mChanges.put(key, value);
182                 return this;
183             }
184         }
185
186         @Override
187         public SharedPreferences.Editor remove(String key) {
188             synchronized (mChanges) {
189                 if (mApplyCalled) throw new IllegalStateException();
190                 // Magic value for removes
191                 mChanges.put(key, this);
192                 return this;
193             }
194         }
195
196         @Override
197         public SharedPreferences.Editor clear() {
198             synchronized (mChanges) {
199                 if (mApplyCalled) throw new IllegalStateException();
200                 mClearCalled = true;
201                 return this;
202             }
203         }
204
205         @Override
206         public boolean commit() {
207             apply();
208             return true;
209         }
210
211         @Override
212         public void apply() {
213             synchronized (mData) {
214                 synchronized (mChanges) {
215                     if (mApplyCalled) throw new IllegalStateException();
216                     if (mClearCalled) {
217                         mData.clear();
218                     }
219                     for (Map.Entry<String, Object> entry : mChanges.entrySet()) {
220                         String key = entry.getKey();
221                         Object value = entry.getValue();
222                         if (value == this) {
223                             // Special value for removal
224                             mData.remove(key);
225                         } else {
226                             mData.put(key, value);
227                         }
228                     }
229                     // The real shared prefs clears out the temporaries allowing the caller to
230                     // reuse the Editor instance, however this is undocumented behavior and subtle
231                     // to read, so instead we just ban any future use of this instance.
232                     mApplyCalled = true;
233                 }
234             }
235         }
236     }
237
238 }