it.unibas.spicy.model.mapping.operators.GenerateCandidateSTTGDs.java Source code

Java tutorial

Introduction

Here is the source code for it.unibas.spicy.model.mapping.operators.GenerateCandidateSTTGDs.java

Source

/*
Copyright (C) 2007-2011  Database Group - Universita' della Basilicata
Giansalvatore Mecca - giansalvatore.mecca@unibas.it
Salvatore Raunich - salrau@gmail.com
    
This file is part of ++Spicy - a Schema Mapping and Data Exchange Tool
    
++Spicy 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
any later version.
    
++Spicy 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 ++Spicy.  If not, see <http://www.gnu.org/licenses/>.
 */

package it.unibas.spicy.model.mapping.operators;

import it.unibas.spicy.model.mapping.ConstantFORule;
import it.unibas.spicy.model.mapping.MappingTask;
import it.unibas.spicy.model.mapping.FORule;
import it.unibas.spicy.model.mapping.SimpleConjunctiveQuery;
import it.unibas.spicy.model.paths.SetAlias;
import it.unibas.spicy.model.paths.VariableCorrespondence;
import it.unibas.spicy.model.paths.VariablePathExpression;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class GenerateCandidateSTTGDs {

    private static Log logger = LogFactory.getLog(GenerateCandidateSTTGDs.class);

    private NormalizeSTTGDs normalizer = new NormalizeSTTGDs();

    public List<FORule> generateCandidateTGDs(MappingTask mappingTask) {
        List<FORule> candidateTgds = new ArrayList<FORule>();

        for (SimpleConjunctiveQuery sourceView : mappingTask.getSourceProxy().getMappingData().getViews()) {
            for (SimpleConjunctiveQuery targetView : mappingTask.getTargetProxy().getMappingData().getViews()) {
                FORule tgd = new FORule(sourceView, targetView);
                candidateTgds.add(tgd);
            }
        }
        addCoveredCorrespondences(candidateTgds, mappingTask);
        //giannisk
        //remove constant correspondences from FORules with no Source correspondences
        removeCoveredCorrespondences(candidateTgds, mappingTask);
        if (logger.isDebugEnabled())
            logger.debug("Candidate mappings before pruning: " + candidateTgds.size());
        removeEmptyTGDs(candidateTgds);
        if (logger.isDebugEnabled())
            logger.debug("Candidate mappings after pruning: " + candidateTgds.size());
        List<FORule> normalizedTgds = normalizer.normalizeSTTGDs(candidateTgds);
        removeEmptyTGDs(normalizedTgds);
        Collections.sort(normalizedTgds);
        if (logger.isDebugEnabled())
            logger.debug("Candidate mappings after normalization: " + normalizedTgds.size());
        return normalizedTgds;
    }

    private void addCoveredCorrespondences(List<FORule> tgds, MappingTask mappingTask) {
        List<VariableCorrespondence> correspondences = mappingTask.getMappingData().getCorrespondences();
        for (FORule tgd : tgds) {
            for (VariableCorrespondence correspondence : correspondences) {
                if (checkCoverage(tgd, correspondence)) {
                    tgd.addCoveredCorrespondence(correspondence);
                }
            }
        }
    }

    //giannisk
    //remove constant correspondences from FORules with no Source correspondences
    private void removeCoveredCorrespondences(List<FORule> tgds, MappingTask mappingTask) {
        List<VariableCorrespondence> correspondences = mappingTask.getMappingData().getCorrespondences();
        for (FORule tgd : tgds) {
            //if FORule contains only constant correspondences
            if (!checkCoverageForSource(tgd.getCoveredCorrespondences())) {
                for (VariableCorrespondence correspondence : correspondences) {
                    //remove them
                    if (correspondence.isConstant()) {
                        tgd.removeCoveredCorrespondence(correspondence);
                    }
                }
            }
        }
    }

    public boolean checkCoverage(FORule tgd, VariableCorrespondence correspondence) {
        if (logger.isDebugEnabled())
            logger.trace("======================= Checking coverage ================\n" + tgd
                    + "\n================================= Correspondence to cover: " + correspondence);
        boolean matchesInTarget = checkMatchInTarget(correspondence.getTargetPath(), tgd.getTargetView());
        if (correspondence.isConstant()) {
            return matchesInTarget;
        } else {
            boolean matchesInSource = checkMatchesInSource(correspondence.getSourcePaths(),
                    tgd.getSimpleSourceView());
            return matchesInSource && matchesInTarget;
        }
    }

    private boolean checkMatchesInSource(List<VariablePathExpression> pathExpressions,
            SimpleConjunctiveQuery view) {
        List<SetAlias> sourceVariables = findVariablesInPaths(pathExpressions);
        for (SetAlias sourceVariable : sourceVariables) {
            if (!view.getGenerators().contains(sourceVariable)) {
                return false;
            }
        }
        return true;
    }

    private boolean checkMatchInTarget(VariablePathExpression pathExpression, SimpleConjunctiveQuery view) {
        boolean check = view.getGenerators().contains(pathExpression.getStartingVariable());
        return check;
    }

    private void removeEmptyTGDs(List<FORule> tgds) {
        for (Iterator<FORule> iterator = tgds.iterator(); iterator.hasNext();) {
            FORule tgd = iterator.next();
            if (tgd.getCoveredCorrespondences().isEmpty()) {
                if (logger.isDebugEnabled())
                    logger.trace("\n===Removing empty mapping:\n" + tgd);
                iterator.remove();
            }
        }
    }

    //giannisk
    public List<ConstantFORule> generateCandidateConstantTGDs(MappingTask mappingTask) {
        List<ConstantFORule> candidateConstantTgds = new ArrayList<ConstantFORule>();
        ////giannisk
        ////only constants
        for (SimpleConjunctiveQuery targetView : mappingTask.getTargetProxy().getMappingData().getViews()) {
            ConstantFORule tgd = new ConstantFORule(targetView);
            candidateConstantTgds.add(tgd);
        }
        addConstantCorrespondences(candidateConstantTgds, mappingTask);
        removeNonConstantCorrespondences(candidateConstantTgds);
        removeConstantEmptyTGDs(candidateConstantTgds);
        /*List<ConstantFORule> normalizedConstantTgds = normalizer.normalizeConstantSTTGDs(candidateConstantTgds);
        removeConstantEmptyTGDs(normalizedConstantTgds);
        Collections.sort(normalizedConstantTgds);
        return normalizedConstantTgds;*/
        return candidateConstantTgds;
    }

    //giannisk
    //returns false if FORule contains only constant correspondences
    public boolean checkCoverageForSource(List<VariableCorrespondence> vcs) {
        boolean flag = false;
        for (VariableCorrespondence vc : vcs) {
            if (!vc.isConstant()) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    //giannisk
    private void addConstantCorrespondences(List<ConstantFORule> tgds, MappingTask mappingTask) {
        List<VariableCorrespondence> correspondences = mappingTask.getMappingData().getCorrespondences();
        for (ConstantFORule tgd : tgds) {
            for (VariableCorrespondence correspondence : correspondences) {
                if (checkConstantCoverage(tgd, correspondence)
                        && !tgd.getCoveredCorrespondences().contains(correspondence)) {
                    tgd.addCoveredCorrespondence(correspondence);
                }
            }
        }
    }

    //giannisk
    //remove the tgd rule from the list if it doesn't contain only constant correspondences
    private void removeNonConstantCorrespondences(List<ConstantFORule> tgds) {
        for (Iterator<ConstantFORule> iterator = tgds.iterator(); iterator.hasNext();) {
            ConstantFORule tgd = iterator.next();
            //if FORule does not contain only constant correspondences
            if (!tgd.getCoveredCorrespondences().isEmpty()) {
                if (checkCoverageForSource(tgd.getCoveredCorrespondences())) {
                    //remove them
                    iterator.remove();
                }
            }
        }
    }

    //giannisk
    public boolean checkConstantCoverage(ConstantFORule tgd, VariableCorrespondence correspondence) {
        if (logger.isDebugEnabled())
            logger.trace("======================= Checking coverage ================\n" + tgd
                    + "\n================================= Correspondence to cover: " + correspondence);
        return checkMatchInTarget(correspondence.getTargetPath(), tgd.getTargetView());
    }

    public static List<SetAlias> findVariablesInPaths(List<VariablePathExpression> pathExpressions) {
        Map<SetAlias, SetAlias> map = new HashMap<SetAlias, SetAlias>();
        for (VariablePathExpression pathExpression : pathExpressions) {
            SetAlias pathVariable = pathExpression.getStartingVariable();
            map.put(pathVariable, pathVariable);
        }
        List<SetAlias> result = new ArrayList<SetAlias>(map.values());
        Collections.sort(result);
        return result;
    }

    //giannisk
    private void removeConstantEmptyTGDs(List<ConstantFORule> tgds) {
        for (Iterator<ConstantFORule> iterator = tgds.iterator(); iterator.hasNext();) {
            ConstantFORule tgd = iterator.next();
            if (tgd.getCoveredCorrespondences().isEmpty()) {
                if (logger.isDebugEnabled())
                    logger.trace("\n===Removing empty mapping:\n" + tgd);
                iterator.remove();
            }
        }
    }

}