Search in sources :

Example 1 with JpaLinkDefinition

use of com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition in project midpoint by Evolveum.

the class JpaAnyContainerDefinition method nextLinkDefinition.

@Override
public DataSearchResult nextLinkDefinition(ItemPath path, ItemDefinition itemDefinition, PrismContext prismContext) throws QueryException {
    if (ItemPath.asSingleName(path) == null) {
        throw new QueryException("Couldn't resolve paths other than those in the form of single name in extension/attributes container: " + path);
    }
    if (itemDefinition == null) {
        throw new QueryException("Couldn't resolve dynamically defined item path '" + path + "' without proper definition");
    }
    CollectionSpecification collSpec = itemDefinition.isSingleValue() ? null : new CollectionSpecification();
    // longs, strings, ...
    String jpaName;
    JpaDataNodeDefinition jpaNodeDefinition;
    if (itemDefinition instanceof PrismPropertyDefinition) {
        try {
            jpaName = RAnyConverter.getAnySetType(itemDefinition, prismContext);
        } catch (SchemaException e) {
            throw new QueryException(e.getMessage(), e);
        }
        // TODO
        jpaNodeDefinition = new JpaAnyPropertyDefinition(Object.class, null);
    } else if (itemDefinition instanceof PrismReferenceDefinition) {
        jpaName = "references";
        jpaNodeDefinition = new JpaAnyReferenceDefinition(Object.class, RObject.class);
    } else {
        throw new QueryException("Unsupported 'any' item: " + itemDefinition);
    }
    JpaLinkDefinition<?> linkDefinition = new JpaAnyItemLinkDefinition(itemDefinition.getName(), jpaName, collSpec, getOwnerType(), jpaNodeDefinition);
    return new DataSearchResult<>(linkDefinition, ItemPath.EMPTY_PATH);
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) QueryException(com.evolveum.midpoint.repo.sql.query.QueryException) DataSearchResult(com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult) RObject(com.evolveum.midpoint.repo.sql.data.common.RObject)

Example 2 with JpaLinkDefinition

use of com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition in project midpoint by Evolveum.

the class ItemPathResolutionState method nextState.

/**
     * Executes transition to next state. Modifies query context by adding joins as necessary.
     *
     * Precondition: !isFinal()
     * Precondition: adequate transition exists
     *
     * @param itemDefinition Target item definition (used/required only for "any" properties)
     * @param singletonOnly Collections are forbidden
     * @return destination state - always not null
     */
public ItemPathResolutionState nextState(ItemDefinition itemDefinition, boolean singletonOnly, PrismContext prismContext) throws QueryException {
    // This is brutal hack, to be thought again.
    if (remainingItemPath.startsWith(ParentPathSegment.class) && hqlDataInstance.getParentItem() != null) {
        return new ItemPathResolutionState(remainingItemPath.tail(), hqlDataInstance.getParentItem(), itemPathResolver);
    }
    DataSearchResult<?> result = hqlDataInstance.getJpaDefinition().nextLinkDefinition(remainingItemPath, itemDefinition, prismContext);
    LOGGER.trace("nextLinkDefinition on '{}' returned '{}'", remainingItemPath, result != null ? result.getLinkDefinition() : "(null)");
    if (result == null) {
        // sorry we failed (however, this should be caught before -> so IllegalStateException)
        throw new IllegalStateException("Couldn't find '" + remainingItemPath + "' in " + hqlDataInstance.getJpaDefinition());
    }
    JpaLinkDefinition linkDefinition = result.getLinkDefinition();
    String newHqlPath = hqlDataInstance.getHqlPath();
    if (linkDefinition.hasJpaRepresentation()) {
        if (singletonOnly && linkDefinition.isMultivalued()) {
            // TODO better message + context
            throw new QueryException("Collections are not allowable for right-side paths");
        }
        if (!linkDefinition.isEmbedded() || linkDefinition.isMultivalued()) {
            LOGGER.trace("Adding join for '{}' to context", linkDefinition);
            newHqlPath = itemPathResolver.addJoin(linkDefinition, hqlDataInstance.getHqlPath());
        } else {
            newHqlPath += "." + linkDefinition.getJpaName();
        }
    }
    HqlDataInstance<?> parentDataInstance;
    if (!remainingItemPath.startsWith(ParentPathSegment.class)) {
        // TODO what about other special cases? (@, ...)
        parentDataInstance = hqlDataInstance;
    } else {
        parentDataInstance = null;
    }
    return new ItemPathResolutionState(result.getRemainder(), new HqlDataInstance<>(newHqlPath, result.getTargetDefinition(), parentDataInstance), itemPathResolver);
}
Also used : JpaLinkDefinition(com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition) QueryException(com.evolveum.midpoint.repo.sql.query.QueryException) ParentPathSegment(com.evolveum.midpoint.prism.path.ParentPathSegment)

Example 3 with JpaLinkDefinition

use of com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition in project midpoint by Evolveum.

the class ItemPathResolver method addJoin.

String addJoin(JpaLinkDefinition joinedItemDefinition, String currentHqlPath) throws QueryException {
    RootHibernateQuery hibernateQuery = context.getHibernateQuery();
    String joinedItemJpaName = joinedItemDefinition.getJpaName();
    String joinedItemFullPath = currentHqlPath + "." + joinedItemJpaName;
    String joinedItemAlias;
    if (!joinedItemDefinition.isMultivalued()) {
        /*
             * Let's check if we were already here i.e. if we had already created this join.
             * This is to avoid useless creation of redundant joins for singleton items.
             *
             * But how can we be sure that item is singleton if we look only at the last segment (which is single-valued)?
             * Imagine we are creating join for single-valued entity of u.abc.(...).xyz.ent where
             * ent is single-valued and not embedded (so we are to create something like "left join u.abc.(...).xyz.ent e").
             * Then "u" is certainly a single value: either the root object, or some value pointed to by Exists restriction.
             * Also, abc, ..., xyz are surely single-valued: otherwise they would be connected by a join. So,
             * u.abc.(...).xyz.ent is a singleton.
             *
             * Look at it in other way: if e.g. xyz was multivalued, then we would have something like:
             * left join u.abc.(...).uvw.xyz x
             * left join x.ent e
             * And, therefore we would not be looking for u.abc.(...).xyz.ent.
             */
        JoinSpecification existingJoin = hibernateQuery.getPrimaryEntity().findJoinFor(joinedItemFullPath);
        if (existingJoin != null) {
            // but let's check the condition as well
            String existingAlias = existingJoin.getAlias();
            // we have to create condition for existing alias, to be matched to existing condition
            Condition conditionForExistingAlias = createJoinCondition(existingAlias, joinedItemDefinition, hibernateQuery);
            if (ObjectUtils.equals(conditionForExistingAlias, existingJoin.getCondition())) {
                LOGGER.trace("Reusing alias '{}' for joined path '{}'", existingAlias, joinedItemFullPath);
                return existingAlias;
            }
        }
    }
    joinedItemAlias = hibernateQuery.createAlias(joinedItemDefinition);
    Condition condition = createJoinCondition(joinedItemAlias, joinedItemDefinition, hibernateQuery);
    hibernateQuery.getPrimaryEntity().addJoin(new JoinSpecification(joinedItemAlias, joinedItemFullPath, condition));
    return joinedItemAlias;
}
Also used : AndCondition(com.evolveum.midpoint.repo.sql.query2.hqm.condition.AndCondition) Condition(com.evolveum.midpoint.repo.sql.query2.hqm.condition.Condition) RootHibernateQuery(com.evolveum.midpoint.repo.sql.query2.hqm.RootHibernateQuery) JoinSpecification(com.evolveum.midpoint.repo.sql.query2.hqm.JoinSpecification)

Example 4 with JpaLinkDefinition

use of com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition in project midpoint by Evolveum.

the class JpaEntityDefinition method nextLinkDefinition.

@Override
public DataSearchResult<?> nextLinkDefinition(ItemPath path, ItemDefinition<?> itemDefinition, PrismContext prismContext) throws QueryException {
    if (ItemPath.isNullOrEmpty(path)) {
        // doesn't fulfill precondition
        return null;
    }
    ItemPathSegment first = path.first();
    if (first instanceof IdItemPathSegment) {
        throw new QueryException("ID item path segments are not allowed in query: " + path);
    } else if (first instanceof ObjectReferencePathSegment) {
        throw new QueryException("'@' path segment cannot be used in the context of an entity " + this);
    }
    JpaLinkDefinition<?> link = findRawLinkDefinition(path, JpaDataNodeDefinition.class, false);
    if (link == null) {
        return null;
    } else {
        link.resolveEntityPointer();
        return new DataSearchResult<>(link, path.tail(link.getItemPath().size()));
    }
}
Also used : ItemPathSegment(com.evolveum.midpoint.prism.path.ItemPathSegment) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) QueryException(com.evolveum.midpoint.repo.sql.query.QueryException) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) DataSearchResult(com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult) ObjectReferencePathSegment(com.evolveum.midpoint.prism.path.ObjectReferencePathSegment)

Example 5 with JpaLinkDefinition

use of com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition in project midpoint by Evolveum.

the class ItemPathResolver method createJoinCondition.

private Condition createJoinCondition(String joinedItemAlias, JpaLinkDefinition joinedItemDefinition, RootHibernateQuery hibernateQuery) throws QueryException {
    Condition condition = null;
    if (joinedItemDefinition instanceof JpaAnyItemLinkDefinition) {
        JpaAnyItemLinkDefinition anyLinkDef = (JpaAnyItemLinkDefinition) joinedItemDefinition;
        AndCondition conjunction = hibernateQuery.createAnd();
        if (anyLinkDef.getOwnerType() != null) {
            // null for assignment extensions
            conjunction.add(hibernateQuery.createEq(joinedItemAlias + ".ownerType", anyLinkDef.getOwnerType()));
        }
        conjunction.add(hibernateQuery.createEq(joinedItemAlias + "." + RAnyValue.F_NAME, RUtil.qnameToString(anyLinkDef.getItemName())));
        condition = conjunction;
    } else if (joinedItemDefinition.getCollectionSpecification() instanceof VirtualCollectionSpecification) {
        VirtualCollectionSpecification vcd = (VirtualCollectionSpecification) joinedItemDefinition.getCollectionSpecification();
        List<Condition> conditions = new ArrayList<>(vcd.getAdditionalParams().length);
        for (VirtualQueryParam vqp : vcd.getAdditionalParams()) {
            // e.g. name = "assignmentOwner", type = RAssignmentOwner.class, value = "ABSTRACT_ROLE"
            Object value = createQueryParamValue(vqp);
            Condition c = hibernateQuery.createEq(joinedItemAlias + "." + vqp.name(), value);
            conditions.add(c);
        }
        if (conditions.size() > 1) {
            condition = hibernateQuery.createAnd(conditions);
        } else if (conditions.size() == 1) {
            condition = conditions.iterator().next();
        }
    }
    return condition;
}
Also used : AndCondition(com.evolveum.midpoint.repo.sql.query2.hqm.condition.AndCondition) Condition(com.evolveum.midpoint.repo.sql.query2.hqm.condition.Condition) JpaAnyItemLinkDefinition(com.evolveum.midpoint.repo.sql.query2.definition.JpaAnyItemLinkDefinition) VirtualQueryParam(com.evolveum.midpoint.repo.sql.query.definition.VirtualQueryParam) VirtualCollectionSpecification(com.evolveum.midpoint.repo.sql.query2.definition.VirtualCollectionSpecification) ArrayList(java.util.ArrayList) List(java.util.List) RObject(com.evolveum.midpoint.repo.sql.data.common.RObject) AndCondition(com.evolveum.midpoint.repo.sql.query2.hqm.condition.AndCondition)

Aggregations

QueryException (com.evolveum.midpoint.repo.sql.query.QueryException)3 RObject (com.evolveum.midpoint.repo.sql.data.common.RObject)2 AndCondition (com.evolveum.midpoint.repo.sql.query2.hqm.condition.AndCondition)2 Condition (com.evolveum.midpoint.repo.sql.query2.hqm.condition.Condition)2 DataSearchResult (com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult)2 IdItemPathSegment (com.evolveum.midpoint.prism.path.IdItemPathSegment)1 ItemPathSegment (com.evolveum.midpoint.prism.path.ItemPathSegment)1 ObjectReferencePathSegment (com.evolveum.midpoint.prism.path.ObjectReferencePathSegment)1 ParentPathSegment (com.evolveum.midpoint.prism.path.ParentPathSegment)1 VirtualQueryParam (com.evolveum.midpoint.repo.sql.query.definition.VirtualQueryParam)1 JpaAnyItemLinkDefinition (com.evolveum.midpoint.repo.sql.query2.definition.JpaAnyItemLinkDefinition)1 JpaLinkDefinition (com.evolveum.midpoint.repo.sql.query2.definition.JpaLinkDefinition)1 VirtualCollectionSpecification (com.evolveum.midpoint.repo.sql.query2.definition.VirtualCollectionSpecification)1 JoinSpecification (com.evolveum.midpoint.repo.sql.query2.hqm.JoinSpecification)1 RootHibernateQuery (com.evolveum.midpoint.repo.sql.query2.hqm.RootHibernateQuery)1 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1