Skip to content

Commit f8e558f

Browse files
committed
initial fix for #3809
1 parent 67e6e4b commit f8e558f

3 files changed

Lines changed: 104 additions & 19 deletions

File tree

realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,23 @@ private void emitConstructor(JavaWriter writer) throws IOException {
229229
// FooRealmProxy(ColumnInfo)
230230
writer.beginConstructor(EnumSet.noneOf(Modifier.class));
231231
writer.beginControlFlow("if (proxyState == null)")
232-
.emitStatement("injectObjectContext()")
233-
.endControlFlow();
232+
.emitStatement("injectObjectContext()");
233+
boolean isFirstRealmListField = true;
234+
for (VariableElement field : metadata.getFields()) {
235+
if (!Utils.isRealmList(field)) {
236+
continue;
237+
}
238+
if (isFirstRealmListField) {
239+
writer.nextControlFlow("else");
240+
isFirstRealmListField = false;
241+
}
242+
final String realmListCacheFieldName = field.getSimpleName().toString() + "RealmList";
243+
writer.beginControlFlow("if (%1$s != null)", realmListCacheFieldName);
244+
writer.emitStatement("%1$s.setIgnoreModification(false)", realmListCacheFieldName);
245+
writer.endControlFlow();
246+
}
247+
writer.endControlFlow();
248+
234249
writer.emitStatement("proxyState.setConstructionFinished()");
235250
writer.endConstructor();
236251
writer.emitEmptyLine();
@@ -404,6 +419,12 @@ public void emit(JavaWriter writer) throws IOException {
404419
writer.emitStatement("LinkView linkView = proxyState.getRow$realm().getLinkList(%s)", fieldIndexVariableReference(field));
405420
writer.emitStatement(fieldName + "RealmList = new RealmList<%s>(%s.class, linkView, proxyState.getRealm$realm())",
406421
genericType, genericType);
422+
writer.beginControlFlow("if (proxyState.isUnderConstruction())");
423+
writer.beginControlFlow("if (!proxyState.getAcceptDefaultValue$realm() || proxyState.getExcludeFields$realm().contains(\"%1$s\"))",
424+
fieldName);
425+
writer.emitStatement("%1$sRealmList.setIgnoreModification(true)", fieldName);
426+
writer.endControlFlow();
427+
writer.endControlFlow();
407428
writer.emitStatement("return " + fieldName + "RealmList");
408429
writer.endControlFlow();
409430

realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ public final AllTypesColumnInfo clone() {
112112
AllTypesRealmProxy() {
113113
if (proxyState == null) {
114114
injectObjectContext();
115+
} else {
116+
if (columnRealmListRealmList != null) {
117+
columnRealmListRealmList.setIgnoreModification(false);
118+
}
115119
}
116120
proxyState.setConstructionFinished();
117121
}
@@ -416,6 +420,11 @@ private void injectObjectContext() {
416420
} else {
417421
LinkView linkView = proxyState.getRow$realm().getLinkList(columnInfo.columnRealmListIndex);
418422
columnRealmListRealmList = new RealmList<some.test.AllTypes>(some.test.AllTypes.class, linkView, proxyState.getRealm$realm());
423+
if (proxyState.isUnderConstruction()) {
424+
if (!proxyState.getAcceptDefaultValue$realm() || proxyState.getExcludeFields$realm().contains("columnRealmList")) {
425+
columnRealmListRealmList.setIgnoreModification(true);
426+
}
427+
}
419428
return columnRealmListRealmList;
420429
}
421430
}

realm/realm-library/src/main/java/io/realm/RealmList.java

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public final class RealmList<E extends RealmModel> extends AbstractList<E> imple
6161
protected LinkView view;
6262
protected BaseRealm realm;
6363
private List<E> unmanagedList;
64+
private boolean ignoreModification;
6465

6566
/**
6667
* Creates a RealmList in unmanaged mode, where the elements are not controlled by a Realm.
@@ -113,6 +114,10 @@ public RealmList(E... objects) {
113114
this.className = className;
114115
}
115116

117+
void setIgnoreModification(boolean ignoreModification) {
118+
this.ignoreModification = ignoreModification;
119+
}
120+
116121
/**
117122
* {@inheritDoc}
118123
*/
@@ -160,6 +165,10 @@ private boolean isAttached() {
160165
@Override
161166
public void add(int location, E object) {
162167
checkValidObject(object);
168+
if (ignoreModification) {
169+
return;
170+
}
171+
163172
if (managedMode) {
164173
checkValidView();
165174
if (location < 0 || location > size()) {
@@ -192,6 +201,9 @@ public void add(int location, E object) {
192201
@Override
193202
public boolean add(E object) {
194203
checkValidObject(object);
204+
if (ignoreModification) {
205+
return true;
206+
}
195207
if (managedMode) {
196208
checkValidView();
197209
RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(object);
@@ -226,12 +238,18 @@ public E set(int location, E object) {
226238
E oldObject;
227239
if (managedMode) {
228240
checkValidView();
229-
RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(object);
230241
oldObject = get(location);
231-
view.set(location, proxy.realmGet$proxyState().getRow$realm().getIndex());
242+
if (!ignoreModification) {
243+
RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(object);
244+
view.set(location, proxy.realmGet$proxyState().getRow$realm().getIndex());
245+
}
232246
return oldObject;
233247
} else {
234-
oldObject = unmanagedList.set(location, object);
248+
if (ignoreModification) {
249+
oldObject = unmanagedList.get(location);
250+
} else {
251+
oldObject = unmanagedList.set(location, object);
252+
}
235253
}
236254
return oldObject;
237255
}
@@ -294,15 +312,19 @@ private E copyToRealmIfNeeded(E object) {
294312
public void move(int oldPos, int newPos) {
295313
if (managedMode) {
296314
checkValidView();
297-
view.move(oldPos, newPos);
315+
if (!ignoreModification) {
316+
view.move(oldPos, newPos);
317+
}
298318
} else {
299319
checkIndex(oldPos);
300320
checkIndex(newPos);
301-
E object = unmanagedList.remove(oldPos);
302-
if (newPos > oldPos) {
303-
unmanagedList.add(newPos - 1, object);
304-
} else {
305-
unmanagedList.add(newPos, object);
321+
if (!ignoreModification) {
322+
E object = unmanagedList.remove(oldPos);
323+
if (newPos > oldPos) {
324+
unmanagedList.add(newPos - 1, object);
325+
} else {
326+
unmanagedList.add(newPos, object);
327+
}
306328
}
307329
}
308330
}
@@ -319,11 +341,16 @@ public void move(int oldPos, int newPos) {
319341
public void clear() {
320342
if (managedMode) {
321343
checkValidView();
322-
view.clear();
344+
if (!ignoreModification) {
345+
view.clear();
346+
modCount++;
347+
}
323348
} else {
324-
unmanagedList.clear();
349+
if (!ignoreModification) {
350+
unmanagedList.clear();
351+
modCount++;
352+
}
325353
}
326-
modCount++;
327354
}
328355

329356
/**
@@ -340,11 +367,18 @@ public E remove(int location) {
340367
if (managedMode) {
341368
checkValidView();
342369
removedItem = get(location);
343-
view.remove(location);
370+
if (!ignoreModification) {
371+
view.remove(location);
372+
modCount++;
373+
}
344374
} else {
345-
removedItem = unmanagedList.remove(location);
375+
if (ignoreModification) {
376+
removedItem = unmanagedList.get(location);
377+
} else {
378+
removedItem = unmanagedList.remove(location);
379+
modCount++;
380+
}
346381
}
347-
modCount++;
348382
return removedItem;
349383
}
350384

@@ -367,6 +401,9 @@ public E remove(int location) {
367401
*/
368402
@Override
369403
public boolean remove(Object object) {
404+
if (ignoreModification) {
405+
return false;
406+
}
370407
if (managedMode && !realm.isInTransaction()) {
371408
throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR);
372409
}
@@ -391,6 +428,9 @@ public boolean remove(Object object) {
391428
*/
392429
@Override
393430
public boolean removeAll(Collection<?> collection) {
431+
if (ignoreModification) {
432+
return false;
433+
}
394434
if (managedMode && !realm.isInTransaction()) {
395435
throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR);
396436
}
@@ -402,10 +442,10 @@ public boolean removeAll(Collection<?> collection) {
402442
*/
403443
@Override
404444
public boolean deleteFirstFromRealm() {
445+
// no need to check ignoreModification since deleteFromRealm does.
405446
if (managedMode) {
406447
if (size() > 0) {
407448
deleteFromRealm(0);
408-
modCount++;
409449
return true;
410450
} else {
411451
return false;
@@ -420,10 +460,10 @@ public boolean deleteFirstFromRealm() {
420460
*/
421461
@Override
422462
public boolean deleteLastFromRealm() {
463+
// no need to check ignoreModification since deleteFromRealm does.
423464
if (managedMode) {
424465
if (size() > 0) {
425466
deleteFromRealm(size() - 1);
426-
modCount++;
427467
return true;
428468
} else {
429469
return false;
@@ -561,6 +601,9 @@ public RealmResults<E> sort(String[] fieldNames, Sort[] sortOrders) {
561601
public void deleteFromRealm(int location) {
562602
if (managedMode) {
563603
checkValidView();
604+
if (ignoreModification) {
605+
return;
606+
}
564607
view.removeTargetRow(location);
565608
modCount++;
566609
} else {
@@ -680,6 +723,9 @@ public Date minDate(String fieldName) {
680723
public boolean deleteAllFromRealm() {
681724
if (managedMode) {
682725
checkValidView();
726+
if (ignoreModification) {
727+
return false;
728+
}
683729
if (size() > 0) {
684730
view.removeAllTargetRows();
685731
modCount++;
@@ -867,6 +913,9 @@ public void remove() {
867913
throw new IllegalStateException("Cannot call remove() twice. Must call next() in between.");
868914
}
869915
checkConcurrentModification();
916+
if (ignoreModification) {
917+
return;
918+
}
870919

871920
try {
872921
RealmList.this.remove(lastRet);
@@ -950,6 +999,9 @@ public void set(E e) {
950999
}
9511000
checkConcurrentModification();
9521001

1002+
if (ignoreModification) {
1003+
return;
1004+
}
9531005
try {
9541006
RealmList.this.set(lastRet, e);
9551007
expectedModCount = modCount;
@@ -967,6 +1019,9 @@ public void set(E e) {
9671019
public void add(E e) {
9681020
realm.checkIfValid();
9691021
checkConcurrentModification();
1022+
if (ignoreModification) {
1023+
return;
1024+
}
9701025
try {
9711026
int i = cursor;
9721027
RealmList.this.add(i, e);

0 commit comments

Comments
 (0)