Search in sources :

Example 41 with Persistent

use of org.apache.cayenne.Persistent 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 42 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class SimpleNode method encodeScalarAsEJBQL.

/**
 * <p>
 * This is a utility method that can represent the supplied scalar as either
 * an EJBQL literal into the supplied {@link java.io.PrintWriter} or is able
 * to add the scalar to the parameters and to instead write a positional
 * parameter to the EJBQL written to the {@link java.io.PrintWriter}. If the
 * parameters are null and the scalar object is not able to be represented
 * as an EJBQL literal then the method will throw a runtime exception to
 * indicate that it has failed to produce valid EJBQL.
 * </p>
 */
protected static void encodeScalarAsEJBQL(List<Object> parameterAccumulator, Appendable out, Object scalar) throws IOException {
    if (null == scalar) {
        out.append("null");
        return;
    }
    if (scalar instanceof Boolean) {
        if ((Boolean) scalar) {
            out.append("true");
        } else {
            out.append("false");
        }
        return;
    }
    if (null != parameterAccumulator) {
        parameterAccumulator.add(scalar);
        out.append('?');
        // parameters start at 1
        out.append(Integer.toString(parameterAccumulator.size()));
        return;
    }
    if (scalar instanceof Integer || scalar instanceof Long || scalar instanceof Float || scalar instanceof Double) {
        out.append(scalar.toString());
        return;
    }
    if (scalar instanceof Persistent) {
        ObjectId id = ((Persistent) scalar).getObjectId();
        Object encode = (id != null) ? id : scalar;
        appendAsEscapedString(out, String.valueOf(encode));
        return;
    }
    if (scalar instanceof Enum<?>) {
        Enum<?> e = (Enum<?>) scalar;
        out.append("enum:");
        out.append(e.getClass().getName()).append(".").append(e.name());
        return;
    }
    if (scalar instanceof String) {
        out.append('\'');
        appendAsEscapedString(out, scalar.toString());
        out.append('\'');
        return;
    }
    throw new IllegalStateException("the scalar type '" + scalar.getClass().getSimpleName() + "' is not supported as a scalar type in EJBQL");
}
Also used : ObjectId(org.apache.cayenne.ObjectId) Persistent(org.apache.cayenne.Persistent)

Example 43 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class SimpleNode method appendScalarAsString.

/**
 * Utility method that encodes an object that is not an expression Node to
 * String.
 */
protected static void appendScalarAsString(Appendable out, Object scalar, char quoteChar) throws IOException {
    boolean quote = scalar instanceof String;
    if (quote) {
        out.append(quoteChar);
    }
    // TODO: should we use UUID here?
    if (scalar instanceof Persistent) {
        ObjectId id = ((Persistent) scalar).getObjectId();
        Object encode = (id != null) ? id : scalar;
        appendAsEscapedString(out, String.valueOf(encode));
    } else if (scalar instanceof Enum<?>) {
        Enum<?> e = (Enum<?>) scalar;
        out.append("enum:");
        out.append(e.getClass().getName()).append(".").append(e.name());
    } else {
        appendAsEscapedString(out, String.valueOf(scalar));
    }
    if (quote) {
        out.append(quoteChar);
    }
}
Also used : ObjectId(org.apache.cayenne.ObjectId) Persistent(org.apache.cayenne.Persistent)

Example 44 with Persistent

use of org.apache.cayenne.Persistent in project cayenne by apache.

the class ChildDiffLoader method nodePropertyChanged.

public void nodePropertyChanged(Object nodeId, String property, Object oldValue, Object newValue) {
    // this change is for simple property, so no need to convert targets to
    // server
    // objects...
    Persistent object = findObject(nodeId);
    ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(((ObjectId) nodeId).getEntityName());
    setExternalChange(Boolean.TRUE);
    try {
        descriptor.getProperty(property).writeProperty(object, oldValue, newValue);
    } catch (Exception e) {
        throw new CayenneRuntimeException("Error setting property: " + property, e);
    } finally {
        setExternalChange(Boolean.FALSE);
    }
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) Persistent(org.apache.cayenne.Persistent) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException)

Example 45 with Persistent

use of org.apache.cayenne.Persistent 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)

Aggregations

Persistent (org.apache.cayenne.Persistent)88 ObjectId (org.apache.cayenne.ObjectId)38 Test (org.junit.Test)32 ArrayList (java.util.ArrayList)17 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)17 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)17 DataObject (org.apache.cayenne.DataObject)13 Map (java.util.Map)12 ObjEntity (org.apache.cayenne.map.ObjEntity)10 EJBQLQuery (org.apache.cayenne.query.EJBQLQuery)10 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)10 DataRow (org.apache.cayenne.DataRow)8 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)8 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)8 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)8 Collection (java.util.Collection)7 HashMap (java.util.HashMap)7 ObjectContext (org.apache.cayenne.ObjectContext)6 DbEntity (org.apache.cayenne.map.DbEntity)6 List (java.util.List)5