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());
}
}
}
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;
}
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);
}
}
}
}
}
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);
}
}
}
}
}
}
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");
}
Aggregations