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

it.unibz.inf.ontop.rdf4j.predefined.impl.ReferenceValueReplacer Maven / Gradle / Ivy

The newest version!
package it.unibz.inf.ontop.rdf4j.predefined.impl;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import it.unibz.inf.ontop.exception.MinorOntopInternalBugException;
import it.unibz.inf.ontop.injection.IntermediateQueryFactory;
import it.unibz.inf.ontop.iq.IQ;
import it.unibz.inf.ontop.iq.IQTree;
import it.unibz.inf.ontop.iq.UnaryIQTree;
import it.unibz.inf.ontop.iq.node.ConstructionNode;
import it.unibz.inf.ontop.iq.node.EmptyNode;
import it.unibz.inf.ontop.iq.node.NativeNode;
import it.unibz.inf.ontop.iq.node.QueryNode;
import it.unibz.inf.ontop.model.term.*;
import it.unibz.inf.ontop.substitution.Substitution;
import it.unibz.inf.ontop.substitution.SubstitutionFactory;
import it.unibz.inf.ontop.utils.ImmutableCollectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@Singleton
public class ReferenceValueReplacer {

    private static final Logger LOGGER = LoggerFactory.getLogger(ReferenceValueReplacer.class);
    private final IntermediateQueryFactory iqFactory;
    private final TermFactory termFactory;

    @Inject
    protected ReferenceValueReplacer(IntermediateQueryFactory iqFactory, TermFactory termFactory,
                                     SubstitutionFactory substitutionFactory) {
        this.iqFactory = iqFactory;
        this.termFactory = termFactory;
    }

    /**
     * ASSUMPTION: the query is possibly only composed of construction nodes and native nodes
     */
    public IQ replaceReferenceValues(IQ referenceIq, ImmutableMap bindings,
                                     ImmutableMap bindingWithReferences) {

        ImmutableMap referenceToInputMap = bindings.entrySet().stream()
                .filter(e -> bindingWithReferences.containsKey(e.getKey()))
                .filter(e -> !e.getValue().equals(bindingWithReferences.get(e.getKey())))
                .collect(ImmutableCollectors.toMap(
                        e -> bindingWithReferences.get(e.getKey()),
                        Map.Entry::getValue));

        if (referenceToInputMap.isEmpty())
            return referenceIq;

        LOGGER.debug("Reference values to be replaced: {}", referenceToInputMap);

        IQTree newTree = transform(referenceIq.getTree(), referenceToInputMap);

        return iqFactory.createIQ(referenceIq.getProjectionAtom(), newTree);
    }

    /**
     * Only applies transformations to construct nodes and native nodes
     */
    private IQTree transform(IQTree tree, ImmutableMap referenceToInputMap) {
        QueryNode rootNode = tree.getRootNode();

        if (rootNode instanceof ConstructionNode) {
            ConstructionNode constructionNode = (ConstructionNode)rootNode;

            ConstructionNode newConstructionNode = constructionNode.getSubstitution().isEmpty()
                ? constructionNode
                : iqFactory.createConstructionNode(
                        constructionNode.getVariables(),
                        constructionNode.getSubstitution().transform(t -> transformTerm(t, referenceToInputMap)));

            return iqFactory.createUnaryIQTree(
                    newConstructionNode,
                    transform(((UnaryIQTree) tree).getChild(), referenceToInputMap));

        }
        else if (rootNode instanceof NativeNode) {
            return transformNativeNode((NativeNode) rootNode, referenceToInputMap);
        }
        else if (rootNode instanceof EmptyNode) {
            return tree;
        }
        else
            throw new IllegalArgumentException("Was only expecting construction nodes and native nodes");
    }

    private ImmutableTerm transformTerm(ImmutableTerm term, ImmutableMap referenceToInputMap) {
        if (term instanceof RDFConstant) {
            RDFConstant constant = (RDFConstant) term;
            String initialValue = constant.getValue();
            String newValue = replaceString(constant.getValue(), referenceToInputMap);
            if (initialValue.equals(newValue))
                return constant;

            return termFactory.getRDFConstant(newValue, constant.getType());
        }
        else if (term instanceof DBConstant) {
            DBConstant constant = (DBConstant) term;
            String initialValue = constant.getValue();
            String newValue = replaceString(constant.getValue(), referenceToInputMap);
            if (initialValue.equals(newValue))
                return constant;

            return termFactory.getDBConstant(newValue, constant.getType());
        }
        else if (term instanceof ImmutableFunctionalTerm) {
            ImmutableFunctionalTerm functionalTerm = (ImmutableFunctionalTerm) term;

            ImmutableList initialTerms = functionalTerm.getTerms();

            ImmutableList newTerms = initialTerms.stream()
                    .map(t -> transformTerm(t, referenceToInputMap))
                    .collect(ImmutableCollectors.toList());

            return initialTerms.equals(newTerms)
                    ? functionalTerm
                    : termFactory.getImmutableFunctionalTerm(functionalTerm.getFunctionSymbol(), newTerms);
        }
        else
            return term;
    }

    private String replaceString(String str, ImmutableMap referenceToInputMap) {
        return referenceToInputMap.entrySet().stream()
                .reduce(str, (s, e) -> s.replaceAll(e.getKey(), e.getValue()),
                        (s1, s2) -> {
                            throw new MinorOntopInternalBugException("Not expected to be run in //");
                        });
    }

    private IQTree transformNativeNode(NativeNode nativeNode, ImmutableMap referenceToInputMap) {
        String newQueryString = replaceString(nativeNode.getNativeQueryString(), referenceToInputMap);

        return iqFactory.createNativeNode(nativeNode.getVariables(),
                nativeNode.getTypeMap(),
                nativeNode.getColumnNames(),
                newQueryString,
                nativeNode.getVariableNullability());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy