Search in sources :

Example 26 with ToManyProperty

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;
        }
    });
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) ObjectId(org.apache.cayenne.ObjectId) DbRelationship(org.apache.cayenne.map.DbRelationship) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 27 with ToManyProperty

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];
}
Also used : ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Fault(org.apache.cayenne.Fault) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 28 with ToManyProperty

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);
        }
    }
}
Also used : DataObject(org.apache.cayenne.DataObject) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) ObjectId(org.apache.cayenne.ObjectId) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 29 with ToManyProperty

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);
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 30 with ToManyProperty

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);
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty)

Aggregations

ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)31 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)29 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)28 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)28 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)21 ArcProperty (org.apache.cayenne.reflect.ArcProperty)13 ObjRelationship (org.apache.cayenne.map.ObjRelationship)9 Persistent (org.apache.cayenne.Persistent)8 DbRelationship (org.apache.cayenne.map.DbRelationship)8 ObjAttribute (org.apache.cayenne.map.ObjAttribute)8 PropertyDescriptor (org.apache.cayenne.reflect.PropertyDescriptor)8 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)7 DbJoin (org.apache.cayenne.map.DbJoin)7 ObjEntity (org.apache.cayenne.map.ObjEntity)7 ObjectId (org.apache.cayenne.ObjectId)6 DbAttribute (org.apache.cayenne.map.DbAttribute)6 HashSet (java.util.HashSet)4 Map (java.util.Map)4 ArrayList (java.util.ArrayList)3 Collection (java.util.Collection)3