Search in sources :

Example 1 with ArcProperty

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

the class ObjectDiff method addDiff.

void addDiff(NodeDiff diff, ObjectStore parent) {
    boolean addDiff = true;
    if (diff instanceof ArcOperation) {
        ArcOperation arcDiff = (ArcOperation) diff;
        Object targetId = arcDiff.getTargetNodeId();
        String arcId = arcDiff.getArcId().toString();
        ArcProperty property = (ArcProperty) getClassDescriptor().getProperty(arcId);
        if (property == null && arcId.startsWith(ASTDbPath.DB_PREFIX)) {
            addPhantomFkDiff(arcDiff);
            addDiff = false;
        } else if (property instanceof ToManyProperty) {
            // record flattened op changes
            ObjRelationship relationship = property.getRelationship();
            if (relationship.isFlattened()) {
                if (flatIds == null) {
                    flatIds = new HashMap<>();
                }
                ArcOperation oldOp = flatIds.put(arcDiff, arcDiff);
                // "delete" cancels "create" and vice versa...
                if (oldOp != null && oldOp.isDelete() != arcDiff.isDelete()) {
                    addDiff = false;
                    flatIds.remove(arcDiff);
                    if (otherDiffs != null) {
                        otherDiffs.remove(oldOp);
                    }
                }
            } else if (property.getComplimentaryReverseArc() == null) {
                // register complimentary arc diff
                String arc = ASTDbPath.DB_PREFIX + property.getComplimentaryReverseDbRelationshipPath();
                ArcOperation complimentartyOp = new ArcOperation(targetId, arcDiff.getNodeId(), arc, arcDiff.isDelete());
                parent.registerDiff(targetId, complimentartyOp);
            }
        } else if (property instanceof ToOneProperty) {
            if (currentArcSnapshot == null) {
                currentArcSnapshot = new HashMap<>();
            }
            currentArcSnapshot.put(arcId, targetId);
        } else {
            String message = (property == null) ? "No property for arcId " + arcId : "Unrecognized property for arcId " + arcId + ": " + property;
            throw new CayenneRuntimeException(message);
        }
    }
    if (addDiff) {
        if (otherDiffs == null) {
            otherDiffs = new ArrayList<>(3);
        }
        otherDiffs.add(diff);
    }
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) HashMap(java.util.HashMap) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 2 with ArcProperty

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

the class PrefetchProcessorJointNode method buildRowMapping.

/**
 * Configures row columns mapping for this node entity.
 */
private void buildRowMapping() {
    final Map<String, ColumnDescriptor> targetSource = new TreeMap<>();
    // build a DB path .. find parent node that terminates the joint group...
    PrefetchTreeNode jointRoot = this;
    while (jointRoot.getParent() != null && !jointRoot.isDisjointPrefetch() && !jointRoot.isDisjointByIdPrefetch()) {
        jointRoot = jointRoot.getParent();
    }
    final String prefix;
    if (jointRoot != this) {
        Expression objectPath = ExpressionFactory.exp(getPath(jointRoot));
        ASTPath translated = (ASTPath) ((PrefetchProcessorNode) jointRoot).getResolver().getEntity().translateToDbPath(objectPath);
        // make sure we do not include "db:" prefix
        prefix = translated.getOperand(0) + ".";
    } else {
        prefix = "";
    }
    if (getParent() != null && !getParent().isPhantom() && getIncoming() != null && !getIncoming().getRelationship().isFlattened()) {
        DbRelationship r = getIncoming().getRelationship().getDbRelationships().get(0);
        for (final DbJoin join : r.getJoins()) {
            appendColumn(targetSource, join.getTargetName(), prefix + join.getTargetName());
        }
    }
    ClassDescriptor descriptor = resolver.getDescriptor();
    descriptor.visitAllProperties(new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            String target = property.getAttribute().getDbAttributePath();
            appendColumn(targetSource, target, prefix + target);
            return true;
        }

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

        public boolean visitToOne(ToOneProperty property) {
            return visitRelationship(property);
        }

        private boolean visitRelationship(ArcProperty arc) {
            DbRelationship dbRel = arc.getRelationship().getDbRelationships().get(0);
            for (DbAttribute attribute : dbRel.getSourceAttributes()) {
                String target = attribute.getName();
                appendColumn(targetSource, target, prefix + target);
            }
            return true;
        }
    });
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        appendColumn(targetSource, pkName, prefix + pkName);
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        String target = column.getDbAttributePath();
        appendColumn(targetSource, target, prefix + target);
    }
    int size = targetSource.size();
    this.rowCapacity = (int) Math.ceil(size / 0.75);
    this.columns = new ColumnDescriptor[size];
    targetSource.values().toArray(columns);
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ColumnDescriptor(org.apache.cayenne.access.jdbc.ColumnDescriptor) DbAttribute(org.apache.cayenne.map.DbAttribute) TreeMap(java.util.TreeMap) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Expression(org.apache.cayenne.exp.Expression) PrefetchTreeNode(org.apache.cayenne.query.PrefetchTreeNode) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) ASTPath(org.apache.cayenne.exp.parser.ASTPath) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 3 with ArcProperty

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

the class PrefetchProcessorTreeBuilder method addNode.

boolean addNode(PrefetchProcessorNode node) {
    List rows;
    ArcProperty arc;
    ClassDescriptor descriptor;
    PrefetchProcessorNode currentNode = getParent();
    if (currentNode != null) {
        rows = (List) extraResultsByPath.get(node.getPath());
        arc = (ArcProperty) currentNode.getResolver().getDescriptor().getProperty(node.getName());
        if (arc == null) {
            throw new CayenneRuntimeException("No relationship with name '%s' found in entity '%s'", node.getName(), currentNode.getResolver().getEntity().getName());
        }
        descriptor = arc.getTargetDescriptor();
    } else {
        arc = null;
        if (this.descriptor != null) {
            descriptor = this.descriptor;
        } else {
            descriptor = queryMetadata.getClassDescriptor();
        }
        rows = mainResultRows;
    }
    node.setDataRows(rows);
    node.setIncoming(arc);
    if (node.getParent() != null && !node.isJointPrefetch()) {
        node.setResolver(new HierarchicalObjectResolverNode(node, context, descriptor, queryMetadata.isRefreshingObjects(), seen));
    } else {
        node.setResolver(new PrefetchObjectResolver(context, descriptor, queryMetadata.isRefreshingObjects(), seen));
    }
    if (node.getParent() == null || node.getParent().isPhantom()) {
        node.setParentAttachmentStrategy(new NoopParentAttachmentStrategy());
    } else if (node.isJointPrefetch()) {
        node.setParentAttachmentStrategy(new StackLookupParentAttachmentStrategy(node));
    } else if (node.getIncoming().getRelationship().isSourceIndependentFromTargetChange()) {
        node.setParentAttachmentStrategy(new JoinedIdParentAttachementStrategy(context.getGraphManager(), node));
    } else {
        node.setParentAttachmentStrategy(new ResultScanParentAttachmentStrategy(node));
    }
    if (currentNode != null) {
        currentNode.addChild(node);
    }
    node.afterInit();
    // push node on stack
    if (nodeStack.isEmpty()) {
        root = node;
    }
    nodeStack.addLast(node);
    return true;
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) List(java.util.List) LinkedList(java.util.LinkedList)

Example 4 with ArcProperty

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

the class EJBQLIdentifierColumnsTranslator method visitIdentifier.

@Override
public boolean visitIdentifier(EJBQLExpression expression) {
    Map<String, String> xfields = null;
    if (context.isAppendingResultColumns()) {
        xfields = context.nextEntityResult().getFields();
    }
    // assign whatever we have to a final ivar so that it can be accessed
    // within
    // the inner class
    final Map<String, String> fields = xfields;
    final String idVar = expression.getText();
    // append all table columns ... the trick is to follow the algorithm for
    // describing the fields in the expression compiler, so that we could
    // assign
    // columns labels from FieldResults in the order we encounter them
    // here...
    // TODO: andrus 2008/02/17 - this is a bit of a hack, think of a better
    // solution
    ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            Iterator<?> dbPathIterator = oa.getDbPathIterator();
            EJBQLJoinAppender joinAppender = null;
            String marker = null;
            EJBQLTableId lhsId = new EJBQLTableId(idVar);
            while (dbPathIterator.hasNext()) {
                Object pathPart = dbPathIterator.next();
                if (pathPart == null) {
                    throw new CayenneRuntimeException("ObjAttribute has no component: %s", oa.getName());
                } else if (pathPart instanceof DbRelationship) {
                    if (marker == null) {
                        marker = EJBQLJoinAppender.makeJoinTailMarker(idVar);
                        joinAppender = context.getTranslatorFactory().getJoinAppender(context);
                    }
                    DbRelationship dr = (DbRelationship) pathPart;
                    EJBQLTableId rhsId = new EJBQLTableId(lhsId, dr.getName());
                    joinAppender.appendOuterJoin(marker, lhsId, rhsId);
                    lhsId = rhsId;
                } else if (pathPart instanceof DbAttribute) {
                    appendColumn(idVar, oa, (DbAttribute) pathPart, fields, oa.getType());
                }
            }
            return true;
        }

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

        public boolean visitToOne(ToOneProperty property) {
            visitRelationship(property);
            return true;
        }

        private void visitRelationship(ArcProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                appendColumn(idVar, null, src, fields);
            }
        }
    };
    // EJBQL queries are polymorphic by definition - there is no distinction
    // between
    // inheritance/no-inheritance fetch
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via
    // relationships)
    DbEntity table = descriptor.getEntity().getDbEntity();
    for (DbAttribute pk : table.getPrimaryKeys()) {
        appendColumn(idVar, null, pk, fields);
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        appendColumn(idVar, column, column.getDbAttribute(), fields);
    }
    addPrefetchedColumnsIfAny(idVar);
    return false;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DbAttribute(org.apache.cayenne.map.DbAttribute) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 5 with ArcProperty

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

the class CayenneContextMergeHandler method arcCreated.

public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
    // null source or target likely means the object is not faulted yet... Faults
    // shouldn't get disturbed by adding/removing arcs
    Object source = context.internalGraphManager().getNode(nodeId);
    if (source == null) {
        // no need to connect non-existent object
        return;
    }
    // TODO (Andrus, 10/17/2005) - check for local modifications to avoid
    // overwriting...
    ArcProperty p = (ArcProperty) propertyForId(nodeId, arcId.toString());
    if (p.isFault(source)) {
        return;
    }
    Object target = context.internalGraphManager().getNode(targetNodeId);
    if (target == null) {
        target = context.createFault((ObjectId) targetNodeId);
    }
    if (p instanceof ToManyProperty) {
        ((ToManyProperty) p).addTargetDirectly(source, target);
    } else {
        p.writePropertyDirectly(source, null, target);
    }
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty)

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