All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.lightblue.assoc.Conjunct Maven / Gradle / Ivy

There is a newer version: 2.18.0
Show newest version
/*
 Copyright 2013 Red Hat, Inc. and/or its affiliates.

 This file is part of lightblue.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see .
 */
package com.redhat.lightblue.assoc;

import java.io.Serializable;

import java.util.List;
import java.util.Set;
import java.util.HashSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redhat.lightblue.query.QueryExpression;
import com.redhat.lightblue.query.FieldInfo;

import com.redhat.lightblue.metadata.CompositeMetadata;
import com.redhat.lightblue.metadata.ResolvedReferenceField;

import com.redhat.lightblue.util.Path;

/**
 * A query clause that cannot be further broken into conjuncts of a
 * conjunctive normal form query. This class also keeps metadata
 * related to that clause, such as the referred nodes of query plan,
 * fieldinfo, etc.
 *
 * Object identity of conjuncts are preserved during query plan
 * processing. That is, a Conjunct object created for a particular
 * query plan is used again for other incarnation of that query plan,
 * only node associations are changed. So, it is possible to keep maps
 * that map a Conjunct to some other piece of data. This is important
 * in query scoring. Scoring can process conjuncts, and keep data
 * internally to prevent recomputing the cost associated with the
 * conjunct for every possible query plan.
 */
public class Conjunct implements Serializable {

    private static final long serialVersionUID=1l;
    
    private static final Logger LOGGER=LoggerFactory.getLogger(Conjunct.class);
    
    /**
     * The original query clause
     */
    private final QueryExpression clause;

    /**
     * Field info for the fields in the clause
     */
    private final ResolvedFieldInfo[] fieldInfo;
    
    /**
     * The list of distinct query plan nodes referred by the clause
     */
    private final Set referredNodes=new HashSet<>();

    /**
     * Specifies if the query belongs to the request, or one of the reference fields
     */
    private final boolean requestQuery;

    
    public Conjunct(QueryExpression q,
                    CompositeMetadata compositeMetadata,
                    QueryPlan qplan,
                    ResolvedReferenceField context) {
        this.clause=q;
        this.requestQuery=context==null;
        List finfo=ResolvedFieldInfo.getQueryFields(clause,compositeMetadata,context,qplan);
        LOGGER.debug("Conjunct for query {} with fields {}",q,finfo);
        fieldInfo=finfo.toArray(new ResolvedFieldInfo[finfo.size()]);
        for(ResolvedFieldInfo rfi:fieldInfo) {
            referredNodes.add(rfi.getFieldQueryPlanNode());
        }
    }

    /**
     * Returns true if the clause belongs to a request query, not to a reference field
     */
    public boolean isRequestQuery() {
        return requestQuery;
    }

    /**
     * Return the relative field name based on the original field name
     */
    public Path mapOriginalFieldName(Path originalFieldName) {
        ResolvedFieldInfo fi=getFieldInfoByOriginalFieldName(originalFieldName);
        if(fi==null)
            return originalFieldName;
        else
            return fi.getEntityRelativeFieldName();
    }

    /**
     * Returns the nodes referenced by this clause
     */
    public Set getReferredNodes() {
        return referredNodes;
    }


    /**
     * Returns the field information about the fields in the conjunct
     */
    public ResolvedFieldInfo[] getFieldInfo() {
        return fieldInfo;
    }

    /**
     * Return the field info by the field name of the field as used in the unmodified query
     */
    public ResolvedFieldInfo getFieldInfoByOriginalFieldName(Path p) {
        for(ResolvedFieldInfo fi:fieldInfo)
            if(fi.getFieldName().equals(p))
                return fi;
        return null;
    }

    /**
     * Returns the field info by the field name as it appears in the entity-relative query
     */
    public ResolvedFieldInfo getFieldInfoByRelativeFieldName(Path p) {
        for(ResolvedFieldInfo fi:fieldInfo)
            if(fi.getEntityRelativeFieldName().equals(p))
                return fi;
        return null;
    }

    /**
     * Returns the query clause
     */
    public QueryExpression getClause() {
        return clause;
    }

    public String toString() {
        StringBuilder bld=new StringBuilder();
        bld.append("clause=").append(clause.toString()).
            append(" entities=");
        for(QueryPlanNode n:referredNodes)
            bld.append(' ').append(n.getName());
        
        return bld.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy