com.evolveum.midpoint.repo.sql.query2.restriction.Restriction.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.repo.sql.query2.restriction.Restriction.java

Source

/*
 * Copyright (c) 2010-2015 Evolveum
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.evolveum.midpoint.repo.sql.query2.restriction;

import com.evolveum.midpoint.prism.query.NotFilter;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.repo.sql.query.QueryException;
import com.evolveum.midpoint.repo.sql.query2.resolution.HqlEntityInstance;
import com.evolveum.midpoint.repo.sql.query2.InterpretationContext;
import com.evolveum.midpoint.repo.sql.query2.resolution.ItemPathResolver;
import com.evolveum.midpoint.repo.sql.query2.definition.JpaEntityDefinition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.Condition;
import org.apache.commons.lang.Validate;

/**
 *  An image of an ObjectFilter, forming a restriction tree.
 *  Preserves some state related to the interpretation (translation).
 *  Provides functionality related to the translation.
 *
 *  As for the state, we maintain (or, more precisely, we are able to determine) the following:
 *   - base HQL property path for the restriction
 *   - base EntityDefinition for the restriction
 *   - chain of translation states that led to the starting HQL property path (if applicable)
 *  This is stored in baseHqlEntity.
 *
 *  Most restrictions do not change the above properties when propagating them to their children.
 *  However, Type and Exists restrictions do.
 *  The former changes EntityDefinition, the latter all three.
 *
 *  Also, item-related restrictions may, at their own discretion, use an EntityDefinition that
 *  points to a subclass of the one provided by the parent restriction. They do that if the item
 *  referenced (e.g. location) is not available in the provided entity (e.g. RObject or RFocus or RAbstractRole),
 *  but has to be found deeper.
 *
 *  There is one known problem in this respect, though: locality attribute. It is present in UserType as well as
 *  in OrgType. So, if having query like ObjectType: Equals(locality, 'abc') it might be narrowed
 *  as o.localityUser or o.locality. (Maybe there are other attributes like that, I don't know.)
 *
 * @author lazyman
 * @author mederly
 */
public abstract class Restriction<T extends ObjectFilter> {

    final protected InterpretationContext context;
    final protected Restriction parent;
    final protected T filter;

    /**
     * Content of ItemPathResolutionStartInformation:
     *
     * (1) Entity definition to be used as "root" by this restriction and its children.
     *
     * Looks a bit weird, but entity definition is provided to the restriction by the caller (query interpreter).
     * Actually, the caller has to determine it, because it needs it to know what restriction to instantiate.
     *
     * (2) HQL property path of the object to which this restriction is to be applied.
     *
     * Usually, e.g. for simple cases like UserType: name, UserType: activation/administrativeStatus etc. the root
     * is the query primary entity alias (e.g. u in "RUser u").
     *
     * For "Exists" filters children the base corresponds to the base item pointed to by the filter.
     * E.g.
     *  - in "UserType: Exists (assignment)" it is "a" (provided that there is
     *    "RUser u left join u.assignments a with ..." already defined).
     *  - in "UserType: Exists (assignment/activation)" it is "a.activation"
     *    [although note that using single-valued properties as last path item
     *    in "Exists" filter is only a syntactic sugar]
     *
     * (3) List of translation steps that had led to the HQL property path. Useful for following ".."
     * segments in item paths.
     *
     */
    final protected HqlEntityInstance baseHqlEntity;

    public Restriction(InterpretationContext context, T filter, JpaEntityDefinition baseEntityDefinition,
            Restriction parent) {
        Validate.notNull(context, "context");
        Validate.notNull(filter, "filter");
        Validate.notNull(baseEntityDefinition, "baseEntityDefinition");
        this.context = context;
        this.filter = filter;
        this.parent = parent;
        if (parent != null) {
            baseHqlEntity = parent.getBaseHqlEntityForChildren().narrowFor(baseEntityDefinition);
        } else {
            baseHqlEntity = new HqlEntityInstance(context.getPrimaryEntityAlias(), baseEntityDefinition, null);
        }
    }

    public T getFilter() {
        return filter;
    }

    public InterpretationContext getContext() {
        return context;
    }

    public Restriction getParent() {
        return parent;
    }

    public HqlEntityInstance getBaseHqlEntity() {
        return baseHqlEntity;
    }

    public abstract Condition interpret() throws QueryException;

    protected boolean isNegated() {
        return filter instanceof NotFilter || (parent != null && parent.isNegated());
    }

    protected String nameOf(Enum e) {
        return e.getClass().getName() + "." + e.name();
    }

    public HqlEntityInstance getBaseHqlEntityForChildren() {
        return getBaseHqlEntity();
    }

    protected ItemPathResolver getItemPathResolver() {
        return getContext().getItemPathResolver();
    }

}