Search in sources :

Example 11 with ToOneProperty

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

the class ObjectDetachOperation method detach.

/**
 * "Detaches" an object from its context by creating an unattached copy. The copy is
 * created using target descriptor of this operation that may be different from the
 * object descriptor passed to this method.
 */
public Object detach(Object object, ClassDescriptor descriptor, final PrefetchTreeNode prefetchTree) {
    if (!(object instanceof Persistent)) {
        throw new CayenneRuntimeException("Expected Persistent, got: %s", object);
    }
    final Persistent source = (Persistent) object;
    ObjectId id = source.getObjectId();
    // sanity check
    if (id == null) {
        throw new CayenneRuntimeException("Server returned an object without an id: %s", source);
    }
    Object seenTarget = seen.get(id);
    if (seenTarget != null) {
        return seenTarget;
    }
    descriptor = descriptor.getSubclassDescriptor(source.getClass());
    // presumably id's entity name should be of the right subclass.
    final ClassDescriptor targetDescriptor = targetResolver.getClassDescriptor(id.getEntityName());
    final Persistent target = (Persistent) targetDescriptor.createObject();
    target.setObjectId(id);
    seen.put(id, target);
    descriptor.visitProperties(new PropertyVisitor() {

        private void fillReverseRelationship(Object destinationTarget, ArcProperty property) {
            ArcProperty clientProperty = (ArcProperty) targetDescriptor.getProperty(property.getName());
            if (clientProperty != null) {
                ArcProperty clientReverse = clientProperty.getComplimentaryReverseArc();
                if (clientReverse instanceof ToOneProperty) {
                    clientReverse.writeProperty(destinationTarget, null, target);
                }
            }
        }

        public boolean visitToOne(ToOneProperty property) {
            if (prefetchTree != null) {
                PrefetchTreeNode child = prefetchTree.getNode(property.getName());
                if (child != null) {
                    Object destinationSource = property.readProperty(source);
                    Object destinationTarget = destinationSource != null ? detach(destinationSource, property.getTargetDescriptor(), child) : null;
                    if (destinationTarget != null) {
                        fillReverseRelationship(destinationTarget, property);
                    }
                    ToOneProperty targetProperty = (ToOneProperty) targetDescriptor.getProperty(property.getName());
                    Object oldTarget = targetProperty.isFault(target) ? null : targetProperty.readProperty(target);
                    targetProperty.writeProperty(target, oldTarget, destinationTarget);
                }
            }
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            if (prefetchTree != null) {
                PrefetchTreeNode child = prefetchTree.getNode(property.getName());
                if (child != null) {
                    Object value = property.readProperty(source);
                    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 ? detach(destinationSource, property.getTargetDescriptor(), child) : null;
                            if (destinationTarget != null) {
                                fillReverseRelationship(destinationTarget, property);
                            }
                            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 ? detach(destinationSource, property.getTargetDescriptor(), child) : null;
                            if (destinationTarget != null) {
                                fillReverseRelationship(destinationTarget, property);
                            }
                            targetCollection.add(destinationTarget);
                        }
                        targetValue = targetCollection;
                    }
                    ToManyProperty targetProperty = (ToManyProperty) targetDescriptor.getProperty(property.getName());
                    targetProperty.writeProperty(target, null, targetValue);
                }
            }
            return true;
        }

        public boolean visitAttribute(AttributeProperty property) {
            PropertyDescriptor targetProperty = targetDescriptor.getProperty(property.getName());
            targetProperty.writeProperty(target, null, property.readProperty(source));
            return true;
        }
    });
    return target;
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) 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) PrefetchTreeNode(org.apache.cayenne.query.PrefetchTreeNode) Collection(java.util.Collection) HashMap(java.util.HashMap) Map(java.util.Map) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 12 with ToOneProperty

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

the class Util method setReverse.

static void setReverse(final Persistent sourceObject, String propertyName, final Persistent targetObject) {
    ArcProperty property = (ArcProperty) Cayenne.getClassDescriptor(sourceObject).getProperty(propertyName);
    ArcProperty reverseArc = property.getComplimentaryReverseArc();
    if (reverseArc != null) {
        reverseArc.visit(new PropertyVisitor() {

            public boolean visitToMany(ToManyProperty property) {
                property.addTargetDirectly(targetObject, sourceObject);
                return false;
            }

            public boolean visitToOne(ToOneProperty property) {
                property.setTarget(targetObject, sourceObject, false);
                return false;
            }

            public boolean visitAttribute(AttributeProperty property) {
                return false;
            }
        });
        sourceObject.getObjectContext().getGraphManager().arcCreated(targetObject.getObjectId(), sourceObject.getObjectId(), reverseArc.getName());
        markAsDirty(targetObject);
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) 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 13 with ToOneProperty

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

the class ChildDiffLoader method arcDeleted.

public void arcDeleted(Object nodeId, final Object targetNodeId, Object arcId) {
    final Persistent source = findObject(nodeId);
    // changing their relationships
    if (source == null) {
        return;
    }
    ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(((ObjectId) nodeId).getEntityName());
    PropertyDescriptor property = descriptor.getProperty(arcId.toString());
    setExternalChange(Boolean.TRUE);
    try {
        property.visit(new PropertyVisitor() {

            public boolean visitAttribute(AttributeProperty property) {
                return false;
            }

            public boolean visitToMany(ToManyProperty property) {
                // connect reverse arc if the relationship is marked as
                // "runtime"
                ArcProperty reverseArc = property.getComplimentaryReverseArc();
                boolean autoConnectReverse = reverseArc != null && reverseArc.getRelationship().isRuntime();
                Persistent target = findObject(targetNodeId);
                if (target == null) {
                    // this is usually the case when a NEW object was
                    // deleted and then
                    // its
                    // relationships were manipulated; so try to locate the
                    // object in
                    // the
                    // collection ...
                    // the performance of this is rather dubious of
                    // course...
                    target = findObjectInCollection(targetNodeId, property.readProperty(source));
                }
                if (target == null) {
                // ignore?
                } else {
                    property.removeTarget(source, target, autoConnectReverse);
                }
                return false;
            }

            public boolean visitToOne(ToOneProperty property) {
                property.setTarget(source, null, false);
                return false;
            }
        });
    } finally {
        setExternalChange(Boolean.FALSE);
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 14 with ToOneProperty

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

the class ChildDiffLoader method arcCreated.

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());
    setExternalChange(Boolean.TRUE);
    try {
        property.visit(new PropertyVisitor() {

            public boolean visitAttribute(AttributeProperty property) {
                return false;
            }

            public boolean visitToMany(ToManyProperty property) {
                // connect reverse arc if the relationship is marked as
                // "runtime"
                ArcProperty reverseArc = property.getComplimentaryReverseArc();
                boolean autoConnectReverse = reverseArc != null && reverseArc.getRelationship().isRuntime();
                property.addTarget(source, target, autoConnectReverse);
                return false;
            }

            public boolean visitToOne(ToOneProperty property) {
                property.setTarget(source, target, false);
                return false;
            }
        });
    } finally {
        setExternalChange(Boolean.FALSE);
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 15 with ToOneProperty

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

the class Compiler method compileEntityResultWithPrefetch.

private EntityResult compileEntityResultWithPrefetch(EntityResult compiledResult, EJBQLExpression prefetchExpression) {
    final EntityResult result = compiledResult;
    String id = prefetchExpression.getText().toLowerCase();
    ClassDescriptor descriptor = descriptorsById.get(id);
    if (descriptor == null) {
        descriptor = descriptorsById.get(prefetchExpression.getText());
    }
    final String prefix = prefetchExpression.getText().substring(prefetchExpression.getText().indexOf(".") + 1);
    final Set<String> visited = new HashSet<String>();
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            if (visited.add(oa.getDbAttributePath())) {
                result.addObjectField(oa.getEntity().getName(), "fetch." + prefix + "." + oa.getName(), prefix + "." + oa.getDbAttributeName());
            }
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            return true;
        }

        public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                if (src.isForeignKey() && visited.add(src.getName())) {
                    result.addDbField("fetch." + prefix + "." + src.getName(), prefix + "." + src.getName());
                }
            }
            return true;
        }
    };
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        if (visited.add(pkName)) {
            result.addDbField("fetch." + prefix + "." + pkName, prefix + "." + pkName);
        }
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        if (visited.add(column.getName())) {
            result.addDbField("fetch." + prefix + "." + column.getDbAttributePath(), prefix + "." + column.getDbAttributePath());
        }
    }
    return result;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) DbAttribute(org.apache.cayenne.map.DbAttribute) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Aggregations

ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)29 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)11 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