Search in sources :

Example 1 with ToManyMapProperty

use of org.apache.cayenne.reflect.ToManyMapProperty in project cayenne by apache.

the class PostprocessVisitor method processObjectChange.

private void processObjectChange(DbRowOp dbRow) {
    if (dbRow.getChangeId().getEntityName().startsWith(ASTDbPath.DB_PREFIX)) {
        return;
    }
    DataRow dataRow = context.currentSnapshot(dbRow.getObject());
    if (dbRow.getObject() instanceof DataObject) {
        DataObject dataObject = (DataObject) dbRow.getObject();
        dataRow.setReplacesVersion(dataObject.getSnapshotVersion());
        dataObject.setSnapshotVersion(dataRow.getVersion());
    }
    if (updatedSnapshots == null) {
        updatedSnapshots = new HashMap<>();
    }
    updatedSnapshots.put(dbRow.getObject().getObjectId(), dataRow);
    // update Map reverse relationships
    ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(dbRow.getChangeId().getEntityName());
    for (ArcProperty arc : descriptor.getMapArcProperties()) {
        ToManyMapProperty reverseArc = (ToManyMapProperty) arc.getComplimentaryReverseArc();
        // must resolve faults... hopefully for to-one this will not cause extra fetches...
        Object source = arc.readProperty(dbRow.getObject());
        if (source != null && !reverseArc.isFault(source)) {
            remapTarget(reverseArc, source, dbRow.getObject());
        }
    }
}
Also used : DataObject(org.apache.cayenne.DataObject) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ToManyMapProperty(org.apache.cayenne.reflect.ToManyMapProperty) DataObject(org.apache.cayenne.DataObject) DataRow(org.apache.cayenne.DataRow)

Example 2 with ToManyMapProperty

use of org.apache.cayenne.reflect.ToManyMapProperty in project cayenne by apache.

the class DeepMergeOperation method merge.

private <T extends Persistent> T merge(final T peerInParentContext, ClassDescriptor descriptor, final Map<ObjectId, Persistent> seen) {
    ObjectId id = peerInParentContext.getObjectId();
    // sanity check
    if (id == null) {
        throw new CayenneRuntimeException("Server returned an object without an id: %s", peerInParentContext);
    }
    Persistent seenTarget = seen.get(id);
    if (seenTarget != null) {
        return (T) seenTarget;
    }
    final T target = shallowMergeOperation.merge(peerInParentContext);
    seen.put(id, target);
    descriptor = descriptor.getSubclassDescriptor(peerInParentContext.getClass());
    descriptor.visitProperties(new PropertyVisitor() {

        public boolean visitToOne(ToOneProperty property) {
            if (!property.isFault(peerInParentContext)) {
                Persistent destinationSource = (Persistent) property.readProperty(peerInParentContext);
                Object destinationTarget = destinationSource != null ? merge(destinationSource, property.getTargetDescriptor(), seen) : null;
                Object oldTarget = property.isFault(target) ? null : property.readProperty(target);
                property.writePropertyDirectly(target, oldTarget, destinationTarget);
            }
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            if (!property.isFault(peerInParentContext)) {
                Object value = property.readProperty(peerInParentContext);
                Object targetValue;
                if (property instanceof ToManyMapProperty) {
                    Map<?, ?> map = (Map) value;
                    Map targetMap = new HashMap();
                    for (Entry entry : map.entrySet()) {
                        Object destinationSource = entry.getValue();
                        Object destinationTarget = destinationSource != null ? merge((Persistent) destinationSource, property.getTargetDescriptor(), seen) : null;
                        targetMap.put(entry.getKey(), destinationTarget);
                    }
                    targetValue = targetMap;
                } else {
                    Collection collection = (Collection) value;
                    Collection targetCollection = new ArrayList(collection.size());
                    for (Object destinationSource : collection) {
                        Object destinationTarget = destinationSource != null ? merge((Persistent) destinationSource, property.getTargetDescriptor(), seen) : null;
                        targetCollection.add(destinationTarget);
                    }
                    targetValue = targetCollection;
                }
                property.writePropertyDirectly(target, null, targetValue);
            }
            return true;
        }

        public boolean visitAttribute(AttributeProperty property) {
            return true;
        }
    });
    return target;
}
Also used : ObjectId(org.apache.cayenne.ObjectId) HashMap(java.util.HashMap) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) ArrayList(java.util.ArrayList) ToManyMapProperty(org.apache.cayenne.reflect.ToManyMapProperty) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) Entry(java.util.Map.Entry) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Collection(java.util.Collection) HashMap(java.util.HashMap) Map(java.util.Map) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 3 with ToManyMapProperty

use of org.apache.cayenne.reflect.ToManyMapProperty in project cayenne by apache.

the class CayenneContextGraphManager method remapTargets.

/**
 * Remaps keys in to-many map relationships that contain dirty objects with
 * potentially modified properties.
 */
private void remapTargets() {
    Iterator<Object> it = stateLog.dirtyIds().iterator();
    EntityResolver resolver = context.getEntityResolver();
    while (it.hasNext()) {
        ObjectId id = (ObjectId) it.next();
        ClassDescriptor descriptor = resolver.getClassDescriptor(id.getEntityName());
        Collection<ArcProperty> mapArcProperties = descriptor.getMapArcProperties();
        if (!mapArcProperties.isEmpty()) {
            Object object = getNode(id);
            for (ArcProperty arc : mapArcProperties) {
                ToManyMapProperty reverseArc = (ToManyMapProperty) arc.getComplimentaryReverseArc();
                Object source = arc.readPropertyDirectly(object);
                if (source != null && !reverseArc.isFault(source)) {
                    remapTarget(reverseArc, source, object);
                }
            }
        }
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ToManyMapProperty(org.apache.cayenne.reflect.ToManyMapProperty) EntityResolver(org.apache.cayenne.map.EntityResolver)

Example 4 with ToManyMapProperty

use of org.apache.cayenne.reflect.ToManyMapProperty in project cayenne by apache.

the class DataDomainSyncBucket method postprocess.

void postprocess() {
    if (!objectsByDescriptor.isEmpty()) {
        CompoundDiff result = parent.getResultDiff();
        Map<ObjectId, DataRow> modifiedSnapshots = parent.getResultModifiedSnapshots();
        Collection<ObjectId> deletedIds = parent.getResultDeletedIds();
        for (Map.Entry<ClassDescriptor, List<Persistent>> entry : objectsByDescriptor.entrySet()) {
            ClassDescriptor descriptor = entry.getKey();
            for (Persistent object : entry.getValue()) {
                ObjectId id = object.getObjectId();
                ObjectId finalId;
                // record id change and update attributes for generated ids
                if (id.isReplacementIdAttached()) {
                    Map<String, Object> replacement = id.getReplacementIdMap();
                    for (AttributeProperty property : descriptor.getIdProperties()) {
                        Object value = replacement.get(property.getAttribute().getDbAttributeName());
                        // if the id wasn't generated. We may need to optimize it...
                        if (value != null) {
                            property.writePropertyDirectly(object, null, value);
                        }
                    }
                    ObjectId replacementId = id.createReplacementId();
                    result.add(new NodeIdChangeOperation(id, replacementId));
                    // DataRowCache has no notion of replaced id...
                    if (!id.isTemporary()) {
                        deletedIds.add(id);
                    }
                    finalId = replacementId;
                } else if (id.isTemporary()) {
                    throw new CayenneRuntimeException("Temporary ID hasn't been replaced on commit: %s", object);
                } else {
                    finalId = id;
                }
                // do not take the snapshot until generated columns are processed (see code above)
                DataRow dataRow = parent.getContext().currentSnapshot(object);
                if (object instanceof DataObject) {
                    DataObject dataObject = (DataObject) object;
                    dataRow.setReplacesVersion(dataObject.getSnapshotVersion());
                    dataObject.setSnapshotVersion(dataRow.getVersion());
                }
                modifiedSnapshots.put(finalId, dataRow);
                // update Map reverse relationships
                for (ArcProperty arc : descriptor.getMapArcProperties()) {
                    ToManyMapProperty reverseArc = (ToManyMapProperty) arc.getComplimentaryReverseArc();
                    // must resolve faults... hopefully for to-one this will not cause extra fetches...
                    Object source = arc.readProperty(object);
                    if (source != null && !reverseArc.isFault(source)) {
                        remapTarget(reverseArc, source, object);
                    }
                }
            }
        }
    }
}
Also used : NodeIdChangeOperation(org.apache.cayenne.graph.NodeIdChangeOperation) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjectId(org.apache.cayenne.ObjectId) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) ToManyMapProperty(org.apache.cayenne.reflect.ToManyMapProperty) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) DataRow(org.apache.cayenne.DataRow) DataObject(org.apache.cayenne.DataObject) ArrayList(java.util.ArrayList) List(java.util.List) DataObject(org.apache.cayenne.DataObject) HashMap(java.util.HashMap) Map(java.util.Map) CompoundDiff(org.apache.cayenne.graph.CompoundDiff)

Example 5 with ToManyMapProperty

use of org.apache.cayenne.reflect.ToManyMapProperty in project cayenne by apache.

the class PersistentObject method getMapKey.

/**
 * Returns a map key for a given to-many map relationship and a target object.
 *
 * @since 3.0
 */
protected Object getMapKey(String relationshipName, Object value) {
    EntityResolver resolver = objectContext.getEntityResolver();
    ClassDescriptor descriptor = resolver.getClassDescriptor(objectId.getEntityName());
    if (descriptor == null) {
        throw new IllegalStateException("DataObject's entity is unmapped, objectId: " + objectId);
    }
    PropertyDescriptor property = descriptor.getProperty(relationshipName);
    if (property instanceof ToManyMapProperty) {
        return ((ToManyMapProperty) property).getMapKey(value);
    }
    throw new IllegalArgumentException("Relationship '" + relationshipName + "' is not a to-many Map");
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) ToManyMapProperty(org.apache.cayenne.reflect.ToManyMapProperty) EntityResolver(org.apache.cayenne.map.EntityResolver)

Aggregations

ToManyMapProperty (org.apache.cayenne.reflect.ToManyMapProperty)5 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)4 ArcProperty (org.apache.cayenne.reflect.ArcProperty)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)2 DataObject (org.apache.cayenne.DataObject)2 DataRow (org.apache.cayenne.DataRow)2 ObjectId (org.apache.cayenne.ObjectId)2 Persistent (org.apache.cayenne.Persistent)2 EntityResolver (org.apache.cayenne.map.EntityResolver)2 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)2 Collection (java.util.Collection)1 List (java.util.List)1 Entry (java.util.Map.Entry)1 CompoundDiff (org.apache.cayenne.graph.CompoundDiff)1 NodeIdChangeOperation (org.apache.cayenne.graph.NodeIdChangeOperation)1 PropertyDescriptor (org.apache.cayenne.reflect.PropertyDescriptor)1 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)1