use of org.apache.cayenne.reflect.ToManyProperty in project cayenne by apache.
the class DataRowUtils method forceMergeWithSnapshot.
static void forceMergeWithSnapshot(final DataContext context, ClassDescriptor descriptor, final Persistent object, final DataRow snapshot) {
final ObjectDiff diff = context.getObjectStore().getChangesByObjectId().get(object.getObjectId());
descriptor.visitProperties(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
String dbAttrPath = property.getAttribute().getDbAttributePath();
// supports merging of partial snapshots...
// check for null is cheaper than double lookup
// for a key... so check for partial snapshot
// only if the value is null
Object newValue = snapshot.get(dbAttrPath);
if (newValue != null || snapshot.containsKey(dbAttrPath)) {
Object curValue = property.readPropertyDirectly(object);
Object oldValue = diff != null ? diff.getSnapshotValue(property.getName()) : null;
// otherwise leave it alone
if (Util.nullSafeEquals(curValue, oldValue) && !Util.nullSafeEquals(newValue, curValue)) {
property.writePropertyDirectly(object, oldValue, newValue);
}
}
return true;
}
public boolean visitToMany(ToManyProperty property) {
// noop - nothing to merge
return true;
}
public boolean visitToOne(ToOneProperty property) {
ObjRelationship relationship = property.getRelationship();
if (relationship.isToPK()) {
// otherwise leave it alone
if (!isToOneTargetModified(property, object, diff)) {
DbRelationship dbRelationship = relationship.getDbRelationships().get(0);
// snapshots
if (hasFK(dbRelationship, snapshot)) {
ObjectId id = snapshot.createTargetObjectId(relationship.getTargetEntityName(), dbRelationship);
if (diff == null || !diff.containsArcSnapshot(relationship.getName()) || !Util.nullSafeEquals(id, diff.getArcSnapshotValue(relationship.getName()))) {
if (id == null) {
property.writeProperty(object, null, null);
} else {
// .. must turn to fault instead
if (!relationship.isSourceDefiningTargetPrecenseAndType(context.getEntityResolver())) {
property.invalidate(object);
} else {
property.writeProperty(object, null, context.findOrCreateObject(id));
}
}
}
}
}
}
return true;
}
});
}
use of org.apache.cayenne.reflect.ToManyProperty in project cayenne by apache.
the class ObjectDiff method isNoop.
/**
* Checks whether at least a single property is modified.
*/
@Override
public boolean isNoop() {
// if we have no baseline to compare with, assume that there are changes
if (snapshot == null) {
return false;
}
if (flatIds != null && !flatIds.isEmpty()) {
return false;
}
if (phantomFks != null && !phantomFks.isEmpty()) {
return false;
}
int state = object.getPersistenceState();
if (state == PersistenceState.NEW || state == PersistenceState.DELETED) {
return false;
}
// check phantom mods
final boolean[] modFound = new boolean[1];
getClassDescriptor().visitProperties(new PropertyVisitor() {
@Override
public boolean visitAttribute(AttributeProperty property) {
Object oldValue = snapshot.get(property.getName());
Object newValue = property.readProperty(object);
if (!Util.nullSafeEquals(oldValue, newValue)) {
modFound[0] = true;
}
return !modFound[0];
}
@Override
public boolean visitToMany(ToManyProperty property) {
// flattened changes
return true;
}
@Override
public boolean visitToOne(ToOneProperty property) {
if (arcSnapshot == null) {
return true;
}
Object newValue = property.readPropertyDirectly(object);
if (newValue instanceof Fault) {
return true;
}
Object oldValue = arcSnapshot.get(property.getName());
if (!Util.nullSafeEquals(oldValue, newValue != null ? ((Persistent) newValue).getObjectId() : null)) {
modFound[0] = true;
}
return !modFound[0];
}
});
return !modFound[0];
}
use of org.apache.cayenne.reflect.ToManyProperty in project cayenne by apache.
the class ObjectStore method processIndirectlyModifiedIDs.
/**
* Requires external synchronization.
*
* @since 1.1
*/
void processIndirectlyModifiedIDs(Collection<ObjectId> indirectlyModifiedIDs) {
for (ObjectId oid : indirectlyModifiedIDs) {
// access object map directly - the method should be called in a synchronized context...
final DataObject object = (DataObject) objectMap.get(oid);
if (object == null || object.getPersistenceState() != PersistenceState.COMMITTED) {
continue;
}
// for now break all "independent" object relationships...
// in the future we may want to be more precise and go after modified
// relationships only, or even process updated lists without invalidating...
DataContextDelegate delegate = context.nonNullDelegate();
if (delegate.shouldMergeChanges(object, null)) {
ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(oid.getEntityName());
descriptor.visitProperties(new PropertyVisitor() {
@Override
public boolean visitToMany(ToManyProperty property) {
property.invalidate(object);
return true;
}
@Override
public boolean visitToOne(ToOneProperty property) {
if (property.getRelationship().isSourceIndependentFromTargetChange()) {
property.invalidate(object);
}
return true;
}
@Override
public boolean visitAttribute(AttributeProperty property) {
return true;
}
});
delegate.finishedProcessDelete(object);
}
}
}
use of org.apache.cayenne.reflect.ToManyProperty in project cayenne by apache.
the class CayenneContextChildDiffLoader method arcCreated.
@Override
public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
final Persistent source = findObject(nodeId);
final Persistent target = findObject(targetNodeId);
// can result in NULL target here.
if (target == null) {
return;
}
ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(((ObjectId) nodeId).getEntityName());
ArcProperty property = (ArcProperty) descriptor.getProperty(arcId.toString());
property.visit(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
return false;
}
public boolean visitToMany(ToManyProperty property) {
property.addTargetDirectly(source, target);
return false;
}
public boolean visitToOne(ToOneProperty property) {
property.setTarget(source, target, false);
return false;
}
});
context.propertyChanged(source, (String) arcId, null, target);
}
use of org.apache.cayenne.reflect.ToManyProperty in project cayenne by apache.
the class CayenneContextMergeHandler method arcDeleted.
public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
// null source or target likely means the object is not faulted yet... Faults
// shouldn't get disturbed by adding/removing arcs
Object source = context.internalGraphManager().getNode(nodeId);
if (source == null) {
// no need to disconnect non-existent object
return;
}
// (see "TODO" in 'arcCreated')
ArcProperty p = (ArcProperty) propertyForId(nodeId, arcId.toString());
if (p.isFault(source)) {
return;
}
Object target = context.internalGraphManager().getNode(targetNodeId);
if (target == null) {
target = context.createFault((ObjectId) targetNodeId);
}
if (p instanceof ToManyProperty) {
((ToManyProperty) p).removeTargetDirectly(source, target);
} else {
p.writePropertyDirectly(source, target, null);
}
}
Aggregations