Skip to content

Commit aaf740a

Browse files
authored
Merge pull request #625 from natario1/parcelable-object
Enable Parcelable object on main ParseObject
2 parents 53b05e9 + e06280a commit aaf740a

23 files changed

+1377
-62
lines changed

Parse/src/main/java/com/parse/ParseACL.java

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@
88
*/
99
package com.parse;
1010

11+
import android.os.Parcel;
12+
import android.os.Parcelable;
13+
1114
import org.json.JSONException;
1215
import org.json.JSONObject;
1316

1417
import java.lang.ref.WeakReference;
1518
import java.util.HashMap;
1619
import java.util.Map;
20+
import java.util.Set;
1721

1822
/**
1923
* A {@code ParseACL} is used to control which users can access or modify a particular object. Each
@@ -22,7 +26,7 @@
2226
* permissions to "the public" so that, for example, any user could read a particular object but
2327
* only a particular set of users could write to that object.
2428
*/
25-
public class ParseACL {
29+
public class ParseACL implements Parcelable {
2630
private static final String PUBLIC_KEY = "*";
2731
private final static String UNRESOLVED_KEY = "*unresolved";
2832
private static final String KEY_ROLE_PREFIX = "role:";
@@ -61,6 +65,11 @@ private static class Permissions {
6165
return json;
6266
}
6367

68+
/* package */ void toParcel(Parcel parcel) {
69+
parcel.writeByte(readPermission ? (byte) 1 : 0);
70+
parcel.writeByte(writePermission ? (byte) 1 : 0);
71+
}
72+
6473
/* package */ boolean getReadPermission() {
6574
return readPermission;
6675
}
@@ -74,6 +83,10 @@ private static class Permissions {
7483
boolean write = object.optBoolean(WRITE_PERMISSION, false);
7584
return new Permissions(read, write);
7685
}
86+
87+
/* package */ static Permissions createPermissionsFromParcel(Parcel parcel) {
88+
return new Permissions(parcel.readByte() == 1, parcel.readByte() == 1);
89+
}
7790
}
7891

7992
private static ParseDefaultACLController getDefaultACLController() {
@@ -205,7 +218,7 @@ public ParseACL(ParseUser owner) {
205218
}
206219

207220
/* package for tests */ void resolveUser(ParseUser user) {
208-
if (user != unresolvedUser) {
221+
if (!isUnresolvedUser(user)) {
209222
return;
210223
}
211224
if (permissionsById.containsKey(UNRESOLVED_KEY)) {
@@ -336,20 +349,27 @@ private void setUnresolvedWriteAccess(ParseUser user, boolean allowed) {
336349
private void prepareUnresolvedUser(ParseUser user) {
337350
// Registers a listener for the user so that when it is saved, the
338351
// unresolved ACL will be resolved.
339-
if (this.unresolvedUser != user) {
352+
if (!isUnresolvedUser(user)) {
340353
permissionsById.remove(UNRESOLVED_KEY);
341354
unresolvedUser = user;
342-
user.registerSaveListener(new UserResolutionListener(this));
355+
unresolvedUser.registerSaveListener(new UserResolutionListener(this));
343356
}
344357
}
345358

359+
private boolean isUnresolvedUser(ParseUser other) {
360+
// This might be a different instance, but if they have the same local id, assume it's correct.
361+
if (other == null || unresolvedUser == null) return false;
362+
return other == unresolvedUser || (other.getObjectId() == null &&
363+
other.getOrCreateLocalId().equals(unresolvedUser.getOrCreateLocalId()));
364+
}
365+
346366
/**
347367
* Get whether the given user id is *explicitly* allowed to read this object. Even if this returns
348368
* {@code false}, the user may still be able to access it if getPublicReadAccess returns
349369
* {@code true} or a role that the user belongs to has read access.
350370
*/
351371
public boolean getReadAccess(ParseUser user) {
352-
if (user == unresolvedUser) {
372+
if (isUnresolvedUser(user)) {
353373
return getReadAccess(UNRESOLVED_KEY);
354374
}
355375
if (user.isLazy()) {
@@ -381,7 +401,7 @@ public void setWriteAccess(ParseUser user, boolean allowed) {
381401
* {@code true} or a role that the user belongs to has write access.
382402
*/
383403
public boolean getWriteAccess(ParseUser user) {
384-
if (user == unresolvedUser) {
404+
if (isUnresolvedUser(user)) {
385405
return getWriteAccess(UNRESOLVED_KEY);
386406
}
387407
if (user.isLazy()) {
@@ -536,4 +556,56 @@ public void done(ParseObject object, ParseException e) {
536556
/* package for tests */ Map<String, Permissions> getPermissionsById() {
537557
return permissionsById;
538558
}
559+
560+
@Override
561+
public int describeContents() {
562+
return 0;
563+
}
564+
565+
@Override
566+
public void writeToParcel(Parcel dest, int flags) {
567+
writeToParcel(dest, new ParseObjectParcelEncoder());
568+
}
569+
570+
/* package */ void writeToParcel(Parcel dest, ParseParcelEncoder encoder) {
571+
dest.writeByte(shared ? (byte) 1 : 0);
572+
dest.writeInt(permissionsById.size());
573+
Set<String> keys = permissionsById.keySet();
574+
for (String key : keys) {
575+
dest.writeString(key);
576+
Permissions permissions = permissionsById.get(key);
577+
permissions.toParcel(dest);
578+
}
579+
dest.writeByte(unresolvedUser != null ? (byte) 1 : 0);
580+
if (unresolvedUser != null) {
581+
// Encoder will create a local id for unresolvedUser, so we recognize it after unparcel.
582+
encoder.encode(unresolvedUser, dest);
583+
}
584+
}
585+
586+
public final static Creator<ParseACL> CREATOR = new Creator<ParseACL>() {
587+
@Override
588+
public ParseACL createFromParcel(Parcel source) {
589+
return new ParseACL(source, new ParseObjectParcelDecoder());
590+
}
591+
592+
@Override
593+
public ParseACL[] newArray(int size) {
594+
return new ParseACL[size];
595+
}
596+
};
597+
598+
/* package */ ParseACL(Parcel source, ParseParcelDecoder decoder) {
599+
shared = source.readByte() == 1;
600+
int size = source.readInt();
601+
for (int i = 0; i < size; i++) {
602+
String key = source.readString();
603+
Permissions permissions = Permissions.createPermissionsFromParcel(source);
604+
permissionsById.put(key, permissions);
605+
}
606+
if (source.readByte() == 1) {
607+
unresolvedUser = (ParseUser) decoder.decode(source);
608+
unresolvedUser.registerSaveListener(new UserResolutionListener(this));
609+
}
610+
}
539611
}

Parse/src/main/java/com/parse/ParseAddOperation.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99
package com.parse;
1010

11+
import android.os.Parcel;
12+
1113
import java.util.ArrayList;
1214
import java.util.Collection;
1315
import java.util.List;
@@ -20,6 +22,8 @@
2022
* An operation that adds a new element to an array field.
2123
*/
2224
/** package */ class ParseAddOperation implements ParseFieldOperation {
25+
/* package */ final static String OP_NAME = "Add";
26+
2327
protected final ArrayList<Object> objects = new ArrayList<>();
2428

2529
public ParseAddOperation(Collection<?> coll) {
@@ -29,12 +33,21 @@ public ParseAddOperation(Collection<?> coll) {
2933
@Override
3034
public JSONObject encode(ParseEncoder objectEncoder) throws JSONException {
3135
JSONObject output = new JSONObject();
32-
output.put("__op", "Add");
36+
output.put("__op", OP_NAME);
3337
output.put("objects", objectEncoder.encode(objects));
3438
return output;
3539
}
3640

3741
@Override
42+
public void encode(Parcel dest, ParseParcelEncoder parcelableEncoder) {
43+
dest.writeString(OP_NAME);
44+
dest.writeInt(objects.size());
45+
for (Object object : objects) {
46+
parcelableEncoder.encode(object, dest);
47+
}
48+
}
49+
50+
@Override
3851
public ParseFieldOperation mergeWithPrevious(ParseFieldOperation previous) {
3952
if (previous == null) {
4053
return this;

Parse/src/main/java/com/parse/ParseAddUniqueOperation.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99
package com.parse;
1010

11+
import android.os.Parcel;
12+
1113
import org.json.JSONArray;
1214
import org.json.JSONException;
1315
import org.json.JSONObject;
@@ -22,6 +24,8 @@
2224
* An operation that adds a new element to an array field, only if it wasn't already present.
2325
*/
2426
/** package */ class ParseAddUniqueOperation implements ParseFieldOperation {
27+
/* package */ final static String OP_NAME = "AddUnique";
28+
2529
protected final LinkedHashSet<Object> objects = new LinkedHashSet<>();
2630

2731
public ParseAddUniqueOperation(Collection<?> col) {
@@ -31,12 +35,21 @@ public ParseAddUniqueOperation(Collection<?> col) {
3135
@Override
3236
public JSONObject encode(ParseEncoder objectEncoder) throws JSONException {
3337
JSONObject output = new JSONObject();
34-
output.put("__op", "AddUnique");
38+
output.put("__op", OP_NAME);
3539
output.put("objects", objectEncoder.encode(new ArrayList<>(objects)));
3640
return output;
3741
}
3842

3943
@Override
44+
public void encode(Parcel dest, ParseParcelEncoder parcelableEncoder) {
45+
dest.writeString(OP_NAME);
46+
dest.writeInt(objects.size());
47+
for (Object object : objects) {
48+
parcelableEncoder.encode(object, dest);
49+
}
50+
}
51+
52+
@Override
4053
@SuppressWarnings("unchecked")
4154
public ParseFieldOperation mergeWithPrevious(ParseFieldOperation previous) {
4255
if (previous == null) {

Parse/src/main/java/com/parse/ParseDeleteOperation.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
*/
99
package com.parse;
1010

11+
import android.os.Parcel;
12+
1113
import org.json.JSONException;
1214
import org.json.JSONObject;
1315

1416
/**
1517
* An operation where a field is deleted from the object.
1618
*/
1719
/** package */ class ParseDeleteOperation implements ParseFieldOperation {
20+
/* package */ final static String OP_NAME = "Delete";
21+
1822
private static final ParseDeleteOperation defaultInstance = new ParseDeleteOperation();
1923

2024
public static ParseDeleteOperation getInstance() {
@@ -27,10 +31,15 @@ private ParseDeleteOperation() {
2731
@Override
2832
public JSONObject encode(ParseEncoder objectEncoder) throws JSONException {
2933
JSONObject output = new JSONObject();
30-
output.put("__op", "Delete");
34+
output.put("__op", OP_NAME);
3135
return output;
3236
}
3337

38+
@Override
39+
public void encode(Parcel dest, ParseParcelEncoder parcelableEncoder) {
40+
dest.writeString(OP_NAME);
41+
}
42+
3443
@Override
3544
public ParseFieldOperation mergeWithPrevious(ParseFieldOperation previous) {
3645
return this;

0 commit comments

Comments
 (0)