Skip to content

Commit d443a33

Browse files
committed
Using XML serialization
1 parent 099df71 commit d443a33

7 files changed

Lines changed: 184 additions & 171 deletions

File tree

‎AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/sharedpreferences/DefaultStringSet.java‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/**
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
116
package org.androidannotations.annotations.sharedpreferences;
217

318
import java.lang.annotation.ElementType;
@@ -14,6 +29,17 @@
1429
* The key of the preference will be the method name by default. This can be
1530
* overridden by specifying a string resource with the {@link #keyRes()}
1631
* parameter.
32+
* <p/>
33+
* <b>Implementation note:</b>
34+
* <p/>
35+
* Since {@code SharedPreferences.getStringSet} is only available from API 11,
36+
* the generated method serializes the {@code Set<String>} into a {@code String}
37+
* , and persists it with
38+
* {@link android.content.SharedPreferences.Editor#putString(String, String)
39+
* SharedPreferences.Editor#putString(String, String)} using API 10 and below.
40+
* From API 11 and up, the generated method simply uses the native
41+
* {@link android.content.SharedPreferences SharedPreferences}
42+
* {@code Set<String>} methods.
1743
*/
1844
@Retention(RetentionPolicy.CLASS)
1945
@Target(ElementType.METHOD)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package org.androidannotations.api.sharedpreferences;
17+
18+
import java.io.IOException;
19+
import java.io.StringReader;
20+
import java.io.StringWriter;
21+
import java.util.Collections;
22+
import java.util.Set;
23+
import java.util.TreeSet;
24+
25+
import org.xmlpull.v1.XmlPullParser;
26+
import org.xmlpull.v1.XmlPullParserException;
27+
import org.xmlpull.v1.XmlSerializer;
28+
29+
import android.util.Log;
30+
import android.util.Xml;
31+
32+
public final class SetXmlSerializer {
33+
34+
private static final String NAMESPACE = "";
35+
private static final String STRING_TAG = "AA_string";
36+
private static final String SET_TAG = "AA_set";
37+
38+
private SetXmlSerializer() {
39+
40+
}
41+
42+
public static String serialize(Set<String> set) {
43+
if (set == null) {
44+
set = Collections.emptySet();
45+
}
46+
47+
StringWriter writer = new StringWriter();
48+
XmlSerializer serializer = Xml.newSerializer();
49+
50+
try {
51+
serializer.setOutput(writer);
52+
serializer.startTag(NAMESPACE, SET_TAG);
53+
54+
for (String string : set) {
55+
serializer.startTag(NAMESPACE, STRING_TAG) //
56+
.text(string) //
57+
.endTag(NAMESPACE, STRING_TAG);
58+
}
59+
60+
serializer.endTag(NAMESPACE, SET_TAG) //
61+
.endDocument();
62+
63+
} catch (IllegalArgumentException e) {
64+
65+
} catch (IllegalStateException e) {
66+
67+
} catch (IOException e) {
68+
69+
}
70+
71+
return writer.toString();
72+
}
73+
74+
public static Set<String> deserialize(String data) {
75+
Set<String> stringSet = new TreeSet<String>();
76+
XmlPullParser parser = Xml.newPullParser();
77+
78+
try {
79+
parser.setInput(new StringReader(data));
80+
parser.next();
81+
parser.require(XmlPullParser.START_TAG, NAMESPACE, SET_TAG);
82+
83+
while (parser.next() != XmlPullParser.END_TAG) {
84+
parser.require(XmlPullParser.START_TAG, NAMESPACE, STRING_TAG);
85+
86+
parser.next();
87+
parser.require(XmlPullParser.TEXT, null, null);
88+
stringSet.add(parser.getText());
89+
90+
parser.next();
91+
parser.require(XmlPullParser.END_TAG, null, STRING_TAG);
92+
}
93+
} catch (XmlPullParserException e) {
94+
Log.w("getStringSet", e);
95+
return null;
96+
} catch (IOException e) {
97+
Log.w("getStringSet", e);
98+
return null;
99+
}
100+
101+
return stringSet;
102+
}
103+
}

‎AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/api/sharedpreferences/SharedPreferencesCompat.java‎

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,74 @@
1717

1818
import java.lang.reflect.InvocationTargetException;
1919
import java.lang.reflect.Method;
20+
import java.util.Set;
2021

2122
import android.content.SharedPreferences;
22-
import android.content.SharedPreferences.Editor;
2323

2424
/**
25-
* Reflection utils to call SharedPreferences$Editor.apply when possible,
26-
* falling back to commit when apply isn't available.
25+
* Reflection utils to call most efficient methods of SharedPreferences and
26+
* SharedPreferences$Editor or fall back to another implementations.
2727
*/
2828
public abstract class SharedPreferencesCompat {
2929

3030
private SharedPreferencesCompat() {
3131
}
3232

33-
private static final Method sApplyMethod = findApplyMethod();
33+
private static final Method sApplyMethod = findMethod(SharedPreferences.Editor.class, "apply");
34+
private static final Method sGetStringSetMethod = findMethod(SharedPreferences.class, "getStringSet", String.class, Set.class);
35+
private static final Method sPutStringSetMethod = findMethod(SharedPreferences.Editor.class, "putStringSet", String.class, Set.class);
3436

35-
private static Method findApplyMethod() {
37+
public static void apply(SharedPreferences.Editor editor) {
38+
try {
39+
invoke(sApplyMethod, editor);
40+
return;
41+
} catch (NoSuchMethodException e) {
42+
editor.commit();
43+
}
44+
}
45+
46+
public static Set<String> getStringSet(SharedPreferences preferences, String key, Set<String> defValues) {
3647
try {
37-
Class<Editor> cls = SharedPreferences.Editor.class;
38-
return cls.getMethod("apply");
48+
return invoke(sGetStringSetMethod, preferences, key, defValues);
49+
} catch (NoSuchMethodException e) {
50+
String serializedSet = preferences.getString(key, null);
51+
return SetXmlSerializer.deserialize(serializedSet);
52+
}
53+
}
54+
55+
public static void putStringSet(SharedPreferences.Editor editor, String key, Set<String> values) {
56+
try {
57+
invoke(sPutStringSetMethod, editor, key, values);
58+
} catch (NoSuchMethodException e1) {
59+
editor.putString(key, SetXmlSerializer.serialize(values));
60+
}
61+
}
62+
63+
private static Method findMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
64+
try {
65+
return clazz.getMethod(name, parameterTypes);
3966
} catch (NoSuchMethodException unused) {
4067
// fall through
4168
}
4269
return null;
4370
}
4471

45-
public static void apply(SharedPreferences.Editor editor) {
46-
if (sApplyMethod != null) {
47-
try {
48-
sApplyMethod.invoke(editor);
49-
return;
50-
} catch (InvocationTargetException unused) {
51-
// fall through
52-
} catch (IllegalAccessException unused) {
53-
// fall through
54-
}
72+
@SuppressWarnings("unchecked")
73+
public static <T> T invoke(Method method, Object obj, Object... args) throws NoSuchMethodException {
74+
if (method == null) {
75+
throw new NoSuchMethodException();
76+
}
77+
78+
try {
79+
return (T) method.invoke(obj, args);
80+
} catch (IllegalAccessException e) {
81+
// fall through
82+
} catch (IllegalArgumentException e) {
83+
// fall through
84+
} catch (InvocationTargetException e) {
85+
// fall through
5586
}
56-
editor.commit();
87+
88+
throw new NoSuchMethodException(method.getName());
5789
}
5890
}

‎AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/api/sharedpreferences/StringSetPrefEditorField.java‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (C) 2010-2012 eBusiness Information, Excilys Group
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
55
* use this file except in compliance with the License. You may obtain a copy of
@@ -24,8 +24,7 @@ public final class StringSetPrefEditorField<T extends EditorHelper<T>> extends A
2424
}
2525

2626
public T put(Set<String> value) {
27-
StringSetPrefField.setValue(editorHelper.getEditor(), key, value);
28-
27+
SharedPreferencesCompat.putStringSet(editorHelper.getEditor(), key, value);
2928
return editorHelper;
3029
}
3130
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (C) 2010-2013 eBusiness Information, Excilys Group
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
55
* use this file except in compliance with the License. You may obtain a copy of
@@ -15,14 +15,9 @@
1515
*/
1616
package org.androidannotations.api.sharedpreferences;
1717

18-
import java.io.IOException;
19-
import java.io.Serializable;
2018
import java.util.Set;
2119

22-
import org.apache.pig.impl.util.ObjectSerializer;
23-
2420
import android.content.SharedPreferences;
25-
import android.content.SharedPreferences.Editor;
2621

2722
public final class StringSetPrefField extends AbstractPrefField {
2823

@@ -37,39 +32,13 @@ public Set<String> get() {
3732
return getOr(defaultValue);
3833
}
3934

40-
@SuppressWarnings("unchecked")
4135
public Set<String> getOr(Set<String> defaultValue) {
42-
Object obj;
43-
try {
44-
obj = ObjectSerializer.deserialize(sharedPreferences.getString(key, null));
45-
} catch (IOException e) {
46-
return null;
47-
}
48-
49-
if (obj == null) {
50-
return defaultValue;
51-
}
52-
53-
if (!(obj instanceof Set<?>)) {
54-
return defaultValue;
55-
}
56-
57-
// No way to check further.
58-
59-
return (Set<String>) obj;
36+
return SharedPreferencesCompat.getStringSet(sharedPreferences, key, defaultValue);
6037
}
6138

6239
public void put(Set<String> value) {
6340
SharedPreferences.Editor editor = sharedPreferences.edit();
64-
setValue(editor, key, value);
41+
SharedPreferencesCompat.putStringSet(editor, key, value);
6542
apply(editor);
6643
}
67-
68-
static void setValue(Editor editor, String key, Set<String> value) {
69-
try {
70-
editor.putString(key, ObjectSerializer.serialize((Serializable) value));
71-
} catch (IOException e) {
72-
throw new RuntimeException("Argument for key `" + key + "` does not implement the Serializable interface");
73-
}
74-
}
7544
}

‎AndroidAnnotations/androidannotations-api/src/main/java/org/apache/pig/impl/util/ObjectSerializer.java‎

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)