Search in sources :

Example 31 with ClassDescriptor

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

the class CayenneContextChildDiffLoader method arcCreated.

@Override
public void arcCreated(Object nodeId, Object targetNodeId, ArcId 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());
    property.visit(new PropertyVisitor() {

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

        public boolean visitToMany(ToManyProperty property) {
            property.addTargetDirectly(source, target);
            return false;
        }

        public boolean visitToOne(ToOneProperty property) {
            property.setTarget(source, target, false);
            return false;
        }
    });
    context.propertyChanged(source, arcId.toString(), null, target);
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) 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 32 with ClassDescriptor

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

the class CayenneContextChildDiffLoader method arcDeleted.

@Override
public void arcDeleted(Object nodeId, final Object targetNodeId, ArcId 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());
    final Persistent[] target = new Persistent[1];
    target[0] = findObject(targetNodeId);
    property.visit(new PropertyVisitor() {

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

        public boolean visitToMany(ToManyProperty property) {
            if (target[0] == 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[0] = findObjectInCollection(targetNodeId, property.readProperty(source));
            }
            if (target[0] != null) {
                property.removeTargetDirectly(source, target[0]);
            }
            return false;
        }

        public boolean visitToOne(ToOneProperty property) {
            property.setTarget(source, null, false);
            return false;
        }
    });
    context.propertyChanged(source, arcId.toString(), target[0], null);
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) 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 33 with ClassDescriptor

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

the class EJBQLPathAnaliserTranslator method visitSize.

@Override
public boolean visitSize(EJBQLExpression expression) {
    if (expression.getChildrenCount() != 1) {
        throw new EJBQLException("SIZE must have exactly one child, got: " + expression.getChildrenCount());
    }
    if (!(expression.getChild(0) instanceof EJBQLPath)) {
        throw new EJBQLException("First child of SIZE must be a collection path, got: " + expression.getChild(1));
    }
    QuotingStrategy quoter = context.getQuotingStrategy();
    EJBQLPath path = (EJBQLPath) expression.getChild(0);
    String id = path.getAbsolutePath();
    String correlatedEntityId = path.getId();
    ClassDescriptor correlatedEntityDescriptor = context.getEntityDescriptor(correlatedEntityId);
    String correlatedTableName = quoter.quotedFullyQualifiedName(correlatedEntityDescriptor.getEntity().getDbEntity());
    String correlatedTableAlias = context.getTableAlias(correlatedEntityId, correlatedTableName);
    String subqueryId = context.createIdAlias(id);
    ClassDescriptor targetDescriptor = context.getEntityDescriptor(subqueryId);
    if (expression.isNegated()) {
        context.append(" NOT");
    }
    context.append(" EXISTS (SELECT 1 FROM ");
    String subqueryTableName = quoter.quotedFullyQualifiedName(targetDescriptor.getEntity().getDbEntity());
    String subqueryRootAlias = context.getTableAlias(subqueryId, subqueryTableName);
    ObjRelationship relationship = correlatedEntityDescriptor.getEntity().getRelationship(path.getRelativePath());
    if (relationship.getDbRelationshipPath().contains(".")) {
        // if the DbRelationshipPath contains '.', the relationship is
        // flattened
        subqueryRootAlias = processFlattenedRelationShip(subqueryRootAlias, relationship);
    } else {
        // not using "AS" to separate table name and alias name - OpenBase
        // doesn't
        // support "AS", and the rest of the databases do not care
        context.append(subqueryTableName).append(' ').append(subqueryRootAlias);
    }
    context.append(" WHERE");
    DbRelationship correlatedJoinRelationship = context.getIncomingRelationships(new EJBQLTableId(id)).get(0);
    Iterator<DbJoin> it = correlatedJoinRelationship.getJoins().iterator();
    while (it.hasNext()) {
        DbJoin join = it.next();
        context.append(' ').append(subqueryRootAlias).append('.').append(join.getTargetName()).append(" = ");
        context.append(correlatedTableAlias).append('.').append(quoter.quotedSourceName(join));
        if (it.hasNext()) {
            context.append(" AND");
        }
    }
    context.append(")");
    return false;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) DbRelationship(org.apache.cayenne.map.DbRelationship) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbJoin(org.apache.cayenne.map.DbJoin) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy) EJBQLPath(org.apache.cayenne.ejbql.parser.EJBQLPath)

Example 34 with ClassDescriptor

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

the class EJBQLPathAnaliserTranslator method processParameter.

private void processParameter(String boundName, EJBQLExpression expression) {
    Object object = context.getBoundParameter(boundName);
    Map<?, ?> map = null;
    if (object instanceof Persistent) {
        map = ((Persistent) object).getObjectId().getIdSnapshot();
    } else if (object instanceof ObjectId) {
        map = ((ObjectId) object).getIdSnapshot();
    } else if (object instanceof Map) {
        map = (Map<?, ?>) object;
    }
    if (map != null) {
        if (map.size() == 1) {
            context.rebindParameter(boundName, map.values().iterator().next());
        } else {
            addMultiColumnOperand(EJBQLMultiColumnOperand.getObjectOperand(context, map));
            return;
        }
    }
    if (object != null) {
        context.append(" #bind($").append(boundName).append(")");
    } else {
        String type = null;
        Node parent = ((SimpleNode) expression).jjtGetParent();
        context.pushMarker("@processParameter", true);
        EJBQLPathAnaliserTranslator translator = new EJBQLPathAnaliserTranslator(context);
        parent.visit(translator);
        translator.visitPath(parent, parent.getChildrenCount());
        String id = translator.idPath;
        if (id != null) {
            ClassDescriptor descriptor = context.getEntityDescriptor(id);
            if (descriptor == null) {
                throw new EJBQLException("Unmapped id variable: " + id);
            }
            String pathChunk = translator.lastPathComponent;
            PropertyDescriptor property = descriptor.getProperty(pathChunk);
            if (property instanceof AttributeProperty) {
                String atrType = ((AttributeProperty) property).getAttribute().getType();
                type = TypesMapping.getSqlNameByType(TypesMapping.getSqlTypeByJava(atrType));
            }
        }
        context.popMarker();
        if (type == null) {
            type = "VARCHAR";
        }
        // this is a hack to prevent execptions on DB's like Derby for
        // expressions
        // "X = NULL". The 'VARCHAR' parameter is totally bogus, but seems
        // to work on
        // all tested DB's... Also note what JPA spec, chapter 4.11 says:
        // "Comparison
        // or arithmetic operations with a NULL value always yield an
        // unknown value."
        // TODO: andrus 6/28/2007 Ideally we should track the type of the
        // current
        // expression to provide a meaningful type.
        context.append(" #bind($").append(boundName).append(" '" + type + "')");
    }
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) ObjectId(org.apache.cayenne.ObjectId) SimpleNode(org.apache.cayenne.ejbql.parser.SimpleNode) Node(org.apache.cayenne.ejbql.parser.Node) AggregateConditionNode(org.apache.cayenne.ejbql.parser.AggregateConditionNode) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) Persistent(org.apache.cayenne.Persistent) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) SimpleNode(org.apache.cayenne.ejbql.parser.SimpleNode) Map(java.util.Map)

Example 35 with ClassDescriptor

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

the class EJBQLGroupByTranslator method visitPath.

@Override
public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) {
    if (itemCount++ > 0) {
        context.append(',');
    }
    EJBQLExpressionVisitor childVisitor = new EJBQLPathTranslator(context) {

        @Override
        protected void appendMultiColumnPath(EJBQLMultiColumnOperand operand) {
            throw new EJBQLException("Can't GROUP BY on multi-column paths or objects");
        }

        @Override
        public boolean visitIdentificationVariable(EJBQLExpression expression) {
            String idVariableAbsolutePath = fullPath + "." + expression.getText();
            ClassDescriptor descriptor = context.getEntityDescriptor(idVariableAbsolutePath);
            if (descriptor != null) {
                this.lastAlias = context.getTableAlias(idVariableAbsolutePath, context.getQuotingStrategy().quotedFullyQualifiedName(descriptor.getEntity().getDbEntity()));
            }
            resolveLastPathComponent(expression.getText());
            this.fullPath = fullPath + '.' + lastPathComponent;
            return true;
        }

        @Override
        protected void processTerminatingRelationship(ObjRelationship relationship) {
            Collection<DbAttribute> dbAttr = ((ObjEntity) relationship.getTargetEntity()).getDbEntity().getAttributes();
            DbRelationship dbRelationship = relationship.getDbRelationships().get(0);
            DbEntity table = (DbEntity) dbRelationship.getTargetEntity();
            Iterator<DbAttribute> it = dbAttr.iterator();
            String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(idPath, context.getQuotingStrategy().quotedFullyQualifiedName(table));
            boolean first = true;
            while (it.hasNext()) {
                context.append(!first ? ", " : " ");
                DbAttribute dbAttribute = it.next();
                context.append(alias).append('.').append(context.getQuotingStrategy().quotedName(dbAttribute));
                first = false;
            }
        }
    };
    expression.visit(childVisitor);
    return false;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbAttribute(org.apache.cayenne.map.DbAttribute) EJBQLExpressionVisitor(org.apache.cayenne.ejbql.EJBQLExpressionVisitor) DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression)

Aggregations

ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)90 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)25 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)23 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)23 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)23 ObjEntity (org.apache.cayenne.map.ObjEntity)22 ArcProperty (org.apache.cayenne.reflect.ArcProperty)21 Persistent (org.apache.cayenne.Persistent)20 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)16 PropertyDescriptor (org.apache.cayenne.reflect.PropertyDescriptor)15 DbRelationship (org.apache.cayenne.map.DbRelationship)14 ObjRelationship (org.apache.cayenne.map.ObjRelationship)13 DataRow (org.apache.cayenne.DataRow)12 ObjectId (org.apache.cayenne.ObjectId)12 Test (org.junit.Test)12 DbAttribute (org.apache.cayenne.map.DbAttribute)10 DataObject (org.apache.cayenne.DataObject)9 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)9 DbJoin (org.apache.cayenne.map.DbJoin)9 ArrayList (java.util.ArrayList)8