private Instance getChanges( Instance in, Function<Instance, Instance> oldFunction, boolean isInput) { if (in._isNew()) { return in.cloneInstance(); } Instance old = oldFunction.apply(in); return prepareChanges(in, old, oldFunction, isInput); }
/** * Allocates duplicate IDs to newly inserted instances in this organization to reference it from * other instance. * * @param in * @param entityId */ private void allocateDuplicateId(Instance in, MutableLong entityId) { if (in == null) { return; } if (in._isNew()) { long nextId = IdProvider.prepareID(entityId.longValue(), 0, in._type(), true); in._setId(nextId); entityId.increment(); } in._visit( (inst, isChild) -> { if (isChild) { allocateDuplicateId((Instance) inst, entityId); } }); }
private void setChanges( Instance dest, Instance src, Function<Instance, Instance> oldFunction, long[] changes, boolean isInput) { AModelType type = InvocationContext.get().getTypeManager().getByPrefix(dest._type()); List<AIField> fields = type.getAllFields(); for (AIField f : fields) { if (f.getName().equals("id")) { dest._setId(src.getId()); continue; } // If this field changed int index = dest._getPropertyIndex(f.getName()); if (InstanceImpl._hasBit(changes, index)) { if (f.isChild()) { setChildValue(dest, src, f, oldFunction, isInput); } else { Property<?> property = src._get(f.getName()); if (property == null) { continue; } dest._set(f.getName(), property.getValue()); } dest._markChange(index, null, null); } } }
private Instance cloneSingleChildValue( Instance value, Instance dest, AIField field, Function<Instance, Instance> oldFunction, boolean isInput) { Instance srcValue = (Instance) value; if (!srcValue.isEmbedded()) { return getChanges(srcValue, oldFunction, isInput); } Instance destValue = (Instance) dest._get(field.getName()).getValue(); if (destValue == null) { value = srcValue.cloneInstance(); } else { value = prepareChanges(srcValue, destValue, oldFunction, isInput); } return value; }
private void setChildValue( Instance dest, Instance src, AIField field, Function<Instance, Instance> oldFunction, boolean isInput) { Object value = src._get(field.getName()).getValue(); if (field.getType().isCollection()) { @SuppressWarnings("unchecked") List<Instance> coll = (List<Instance>) value; List<Instance> result = new ArrayList<Instance>(); coll.forEach(i -> result.add(getChanges(i, oldFunction, isInput))); value = result; } else { // Simply clone value with changed properties if (value != null) { value = cloneSingleChildValue((Instance) value, dest, field, oldFunction, isInput); } } dest._set(field.getName(), value); }
private Instance prepareChanges( Instance src, Instance dest, Function<Instance, Instance> oldFunction, boolean isInput) { InvocationContext context = InvocationContext.get(); Instance ch = context.getInstanceProvider().newInstance(src._type()); ch.markInSavingToDB(true); if (isInput) { if (context.isInRepRetry()) { // If in Replication retry, then version of the input will be // very old(invalid). So that make the version id of old // object.Otherwise When applying this retried version on server // will fail. ch._setVersion(dest.getVersion()); } else { ch._setVersion(src.getVersion()); } } long[] tempChanges = src._getChangesMarkers(); long[] allChanges = new long[tempChanges.length]; Arrays.fill(allChanges, -1); src._setChangesMarkers(allChanges); long[] changes = src._getChanges(dest); src._setChangesMarkers(tempChanges); setChanges(ch, isInput ? src : dest, oldFunction, changes, isInput); InstanceImpl.copyMarkers(ch._getChangesMarkers(), changes); ch._setId(src.getId()); return ch; }