Search in sources :

Example 16 with ArcProperty

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

the class Compiler method compile.

CompiledExpression compile(String source, EJBQLExpression parsed) {
    parsed.visit(new CompilationVisitor());
    Map<EJBQLPath, Integer> pathsInSelect = new HashMap<>();
    for (int i = 0; i < parsed.getChildrenCount(); i++) {
        if (parsed.getChild(i) instanceof EJBQLSelectClause) {
            EJBQLExpression parsedTemp = parsed.getChild(i);
            boolean stop = false;
            while (parsedTemp.getChildrenCount() > 0 && !stop) {
                EJBQLExpression newParsedTemp = null;
                for (int j = 0; j < parsedTemp.getChildrenCount(); j++) {
                    if (parsedTemp.getChild(j) instanceof EJBQLSelectExpression) {
                        for (int k = 0; k < parsedTemp.getChild(j).getChildrenCount(); k++) {
                            if (parsedTemp.getChild(j).getChild(k) instanceof EJBQLPath) {
                                pathsInSelect.put((EJBQLPath) parsedTemp.getChild(j).getChild(k), j);
                            }
                        }
                    } else {
                        if (parsedTemp.getChild(j).getChildrenCount() == 0) {
                            stop = true;
                        } else {
                            newParsedTemp = parsedTemp.getChild(j);
                        }
                    }
                }
                if (!stop && newParsedTemp != null) {
                    parsedTemp = newParsedTemp;
                } else {
                    stop = true;
                }
            }
        }
    }
    // postprocess paths, now that all id vars are resolved
    if (paths != null) {
        for (EJBQLPath path : paths) {
            String id = normalizeIdPath(path.getId());
            ClassDescriptor descriptor = descriptorsById.get(id);
            if (descriptor == null) {
                throw new EJBQLException("Unmapped id variable: " + id);
            }
            StringBuilder buffer = new StringBuilder(id);
            ObjRelationship incoming = null;
            String pathRelationshipString = "";
            for (int i = 1; i < path.getChildrenCount(); i++) {
                String pathChunk = path.getChild(i).getText();
                if (pathChunk.endsWith(Entity.OUTER_JOIN_INDICATOR)) {
                    pathChunk = pathChunk.substring(0, pathChunk.length() - 1);
                }
                buffer.append('.').append(pathChunk);
                PropertyDescriptor property = descriptor.getProperty(pathChunk);
                if (property instanceof ArcProperty) {
                    incoming = ((ArcProperty) property).getRelationship();
                    descriptor = ((ArcProperty) property).getTargetDescriptor();
                    pathRelationshipString = buffer.substring(0, buffer.length());
                    descriptorsById.put(pathRelationshipString, descriptor);
                    incomingById.put(pathRelationshipString, incoming);
                }
            }
            if (pathsInSelect.size() > 0 && incoming != null && pathRelationshipString.length() > 0 && pathRelationshipString.equals(buffer.toString())) {
                EJBQLIdentifier ident = new EJBQLIdentifier(0);
                ident.text = pathRelationshipString;
                Integer integer = pathsInSelect.get(path);
                if (integer != null) {
                    resultComponents.remove(integer.intValue());
                    resultComponents.add(integer, ident);
                    rootId = pathRelationshipString;
                }
            }
        }
    }
    CompiledExpression compiled = new CompiledExpression();
    compiled.setExpression(parsed);
    compiled.setSource(source);
    compiled.setRootId(rootId);
    compiled.setDescriptorsById(descriptorsById);
    compiled.setIncomingById(incomingById);
    compiled.setPrefetchTree(prefetchTree);
    if (resultComponents != null) {
        SQLResult mapping = new SQLResult();
        for (int i = 0; i < resultComponents.size(); i++) {
            Object nextMapping = resultComponents.get(i);
            if (nextMapping instanceof String) {
                mapping.addColumnResult((String) nextMapping);
            } else if (nextMapping instanceof EJBQLExpression) {
                EntityResult compileEntityResult = compileEntityResult((EJBQLExpression) nextMapping, i);
                if (prefetchTree != null) {
                    for (PrefetchTreeNode prefetch : prefetchTree.getChildren()) {
                        if (((EJBQLExpression) nextMapping).getText().equals(prefetch.getEjbqlPathEntityId())) {
                            EJBQLIdentifier ident = new EJBQLIdentifier(0);
                            ident.text = prefetch.getEjbqlPathEntityId() + "." + prefetch.getPath();
                            compileEntityResult = compileEntityResultWithPrefetch(compileEntityResult, ident);
                        }
                    }
                }
                mapping.addEntityResult(compileEntityResult);
            }
        }
        compiled.setResult(mapping);
    }
    return compiled;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) HashMap(java.util.HashMap) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) EntityResult(org.apache.cayenne.map.EntityResult) EJBQLCompiledExpression(org.apache.cayenne.ejbql.EJBQLCompiledExpression) SQLResult(org.apache.cayenne.map.SQLResult) PrefetchTreeNode(org.apache.cayenne.query.PrefetchTreeNode) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression)

Example 17 with ArcProperty

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

the class ObjectContextGraphAction method handlePropertyChange.

/**
 * Handles property change in a Persistent object, routing to either
 * {@link #handleArcPropertyChange(Persistent, ArcProperty, Object, Object)} or
 * {@link #handleSimplePropertyChange(Persistent, String, Object, Object)}.
 */
public void handlePropertyChange(Persistent object, String propertyName, Object oldValue, Object newValue) {
    // translate ObjectContext generic property change callback to GraphManager terms
    // (simple properties vs. relationships)
    ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(object.getObjectId().getEntityName());
    PropertyDescriptor property = descriptor.getProperty(propertyName);
    if (property instanceof ArcProperty) {
        handleArcPropertyChange(object, (ArcProperty) property, oldValue, newValue);
    } else {
        handleSimplePropertyChange(object, propertyName, oldValue, newValue);
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor)

Example 18 with ArcProperty

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

the class Util method unsetReverse.

static void unsetReverse(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.removeTargetDirectly(targetObject, sourceObject);
                return false;
            }

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

            public boolean visitAttribute(AttributeProperty property) {
                return false;
            }
        });
        sourceObject.getObjectContext().getGraphManager().arcDeleted(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 19 with ArcProperty

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

the class ObjectContextDeleteAction method processDeleteRules.

private void processDeleteRules(final Persistent object, int oldState) throws DeleteDenyException {
    ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(object.getObjectId().getEntityName());
    for (final ObjRelationship relationship : descriptor.getEntity().getRelationships()) {
        boolean processFlattened = relationship.isFlattened() && relationship.isToDependentEntity() && !relationship.isReadOnly();
        // first check for no action... bail out if no flattened processing is needed
        if (relationship.getDeleteRule() == DeleteRule.NO_ACTION && !processFlattened) {
            continue;
        }
        ArcProperty property = (ArcProperty) descriptor.getProperty(relationship.getName());
        final Collection<Persistent> relatedObjects = toCollection(property.readProperty(object));
        // no related object, bail out
        if (relatedObjects.size() == 0) {
            continue;
        }
        // process DENY rule first...
        if (relationship.getDeleteRule() == DeleteRule.DENY) {
            object.setPersistenceState(oldState);
            String message = relatedObjects.size() == 1 ? "1 related object" : relatedObjects.size() + " related objects";
            throw new DeleteDenyException(object, relationship.getName(), message);
        }
        // object graph
        if (processFlattened) {
            for (Persistent relatedObject : relatedObjects) {
                context.getGraphManager().arcDeleted(object.getObjectId(), relatedObject.getObjectId(), relationship.getName());
            }
        }
        // process remaining rules
        switch(relationship.getDeleteRule()) {
            case DeleteRule.NO_ACTION:
                break;
            case DeleteRule.NULLIFY:
                ArcProperty reverseArc = property.getComplimentaryReverseArc();
                if (reverseArc == null) {
                    // nothing we can do here
                    break;
                }
                reverseArc.visit(new PropertyVisitor() {

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

                    public boolean visitToMany(ToManyProperty property) {
                        for (Persistent relatedObject : relatedObjects) {
                            property.removeTarget(relatedObject, object, true);
                        }
                        return false;
                    }

                    public boolean visitToOne(ToOneProperty property) {
                        // nullify the reverse relationship
                        for (Persistent relatedObject : relatedObjects) {
                            property.setTarget(relatedObject, null, true);
                        }
                        return false;
                    }
                });
                break;
            case DeleteRule.CASCADE:
                // Delete all related objects
                for (Persistent relatedObject : relatedObjects) {
                    performDelete(relatedObject);
                }
                break;
            default:
                object.setPersistenceState(oldState);
                throw new CayenneRuntimeException("Invalid delete rule %s", relationship.getDeleteRule());
        }
    }
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 20 with ArcProperty

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

Aggregations

ArcProperty (org.apache.cayenne.reflect.ArcProperty)23 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)18 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)13 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)11 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)11 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)10 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)6 Persistent (org.apache.cayenne.Persistent)5 ObjRelationship (org.apache.cayenne.map.ObjRelationship)5 PropertyDescriptor (org.apache.cayenne.reflect.PropertyDescriptor)5 HashMap (java.util.HashMap)4 PrefetchTreeNode (org.apache.cayenne.query.PrefetchTreeNode)4 Test (org.junit.Test)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Map (java.util.Map)3 ObjectId (org.apache.cayenne.ObjectId)3 DbAttribute (org.apache.cayenne.map.DbAttribute)3 DbJoin (org.apache.cayenne.map.DbJoin)3 DbRelationship (org.apache.cayenne.map.DbRelationship)3