Skip to content

Commit 2e1b9da

Browse files
committed
initial fix for #3809
1 parent 1ad27e2 commit 2e1b9da

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 class RealmList<E extends RealmModel> extends AbstractList<E> implements
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);
@@ -227,12 +239,18 @@ public E set(int location, E object) {
227239
E oldObject;
228240
if (managedMode) {
229241
checkValidView();
230-
RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(object);
231242
oldObject = get(location);
232-
view.set(location, proxy.realmGet$proxyState().getRow$realm().getIndex());
243+
if (!ignoreModification) {
244+
RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(object);
245+
view.set(location, proxy.realmGet$proxyState().getRow$realm().getIndex());
246+
}
233247
return oldObject;
234248
} else {
235-
oldObject = unmanagedList.set(location, object);
249+
if (ignoreModification) {
250+
oldObject = unmanagedList.get(location);
251+
} else {
252+
oldObject = unmanagedList.set(location, object);
253+
}
236254
}
237255
return oldObject;
238256
}
@@ -295,15 +313,19 @@ private E copyToRealmIfNeeded(E object) {
295313
public void move(int oldPos, int newPos) {
296314
if (managedMode) {
297315
checkValidView();
298-
view.move(oldPos, newPos);
316+
if (!ignoreModification) {
317+
view.move(oldPos, newPos);
318+
}
299319
} else {
300320
checkIndex(oldPos);
301321
checkIndex(newPos);
302-
E object = unmanagedList.remove(oldPos);
303-
if (newPos > oldPos) {
304-
unmanagedList.add(newPos - 1, object);
305-
} else {
306-
unmanagedList.add(newPos, object);
322+
if (!ignoreModification) {
323+
E object = unmanagedList.remove(oldPos);
324+
if (newPos > oldPos) {
325+
unmanagedList.add(newPos - 1, object);
326+
} else {
327+
unmanagedList.add(newPos, object);
328+
}
307329
}
308330
}
309331
}
@@ -320,11 +342,16 @@ public void move(int oldPos, int newPos) {
320342
public void clear() {
321343
if (managedMode) {
322344
checkValidView();
323-
view.clear();
345+
if (!ignoreModification) {
346+
view.clear();
347+
modCount++;
348+
}
324349
} else {
325-
unmanagedList.clear();
350+
if (!ignoreModification) {
351+
unmanagedList.clear();
352+
modCount++;
353+
}
326354
}
327-
modCount++;
328355
}
329356

330357
/**
@@ -341,11 +368,18 @@ public E remove(int location) {
341368
if (managedMode) {
342369
checkValidView();
343370
removedItem = get(location);
344-
view.remove(location);
371+
if (!ignoreModification) {
372+
view.remove(location);
373+
modCount++;
374+
}
345375
} else {
346-
removedItem = unmanagedList.remove(location);
376+
if (ignoreModification) {
377+
removedItem = unmanagedList.get(location);
378+
} else {
379+
removedItem = unmanagedList.remove(location);
380+
modCount++;
381+
}
347382
}
348-
modCount++;
349383
return removedItem;
350384
}
351385

@@ -368,6 +402,9 @@ public E remove(int location) {
368402
*/
369403
@Override
370404
public boolean remove(Object object) {
405+
if (ignoreModification) {
406+
return false;
407+
}
371408
if (managedMode && !realm.isInTransaction()) {
372409
throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR);
373410
}
@@ -392,6 +429,9 @@ public boolean remove(Object object) {
392429
*/
393430
@Override
394431
public boolean removeAll(Collection<?> collection) {
432+
if (ignoreModification) {
433+
return false;
434+
}
395435
if (managedMode && !realm.isInTransaction()) {
396436
throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR);
397437
}
@@ -403,10 +443,10 @@ public boolean removeAll(Collection<?> collection) {
403443
*/
404444
@Override
405445
public boolean deleteFirstFromRealm() {
446+
// no need to check ignoreModification since deleteFromRealm does.
406447
if (managedMode) {
407448
if (size() > 0) {
408449
deleteFromRealm(0);
409-
modCount++;
410450
return true;
411451
} else {
412452
return false;
@@ -421,10 +461,10 @@ public boolean deleteFirstFromRealm() {
421461
*/
422462
@Override
423463
public boolean deleteLastFromRealm() {
464+
// no need to check ignoreModification since deleteFromRealm does.
424465
if (managedMode) {
425466
if (size() > 0) {
426467
deleteFromRealm(size() - 1);
427-
modCount++;
428468
return true;
429469
} else {
430470
return false;
@@ -562,6 +602,9 @@ public RealmResults<E> sort(String[] fieldNames, Sort[] sortOrders) {
562602
public void deleteFromRealm(int location) {
563603
if (managedMode) {
564604
checkValidView();
605+
if (ignoreModification) {
606+
return;
607+
}
565608
view.removeTargetRow(location);
566609
modCount++;
567610
} else {
@@ -681,6 +724,9 @@ public Date minDate(String fieldName) {
681724
public boolean deleteAllFromRealm() {
682725
if (managedMode) {
683726
checkValidView();
727+
if (ignoreModification) {
728+
return false;
729+
}
684730
if (size() > 0) {
685731
view.removeAllTargetRows();
686732
modCount++;
@@ -875,6 +921,9 @@ public void remove() {
875921
throw new IllegalStateException("Cannot call remove() twice. Must call next() in between.");
876922
}
877923
checkConcurrentModification();
924+
if (ignoreModification) {
925+
return;
926+
}
878927

879928
try {
880929
RealmList.this.remove(lastRet);
@@ -958,6 +1007,9 @@ public void set(E e) {
9581007
}
9591008
checkConcurrentModification();
9601009

1010+
if (ignoreModification) {
1011+
return;
1012+
}
9611013
try {
9621014
RealmList.this.set(lastRet, e);
9631015
expectedModCount = modCount;
@@ -975,6 +1027,9 @@ public void set(E e) {
9751027
public void add(E e) {
9761028
realm.checkIfValid();
9771029
checkConcurrentModification();
1030+
if (ignoreModification) {
1031+
return;
1032+
}
9781033
try {
9791034
int i = cursor;
9801035
RealmList.this.add(i, e);

0 commit comments

Comments
 (0)