it.unibas.spicy.persistence.xml.operators.UpdateDataSourceWithConstraints.java Source code

Java tutorial

Introduction

Here is the source code for it.unibas.spicy.persistence.xml.operators.UpdateDataSourceWithConstraints.java

Source

/*
Copyright (C) 2007-2011  Database Group - Universita' della Basilicata
Giansalvatore Mecca - giansalvatore.mecca@unibas.it
Salvatore Raunich - salrau@gmail.com
Alessandro Pappalardo - pappalardo.alessandro@gmail.com
Gianvito Summa - gianvito.summa@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.persistence.xml.operators;

import it.unibas.spicy.model.datasource.ForeignKeyConstraint;
import it.unibas.spicy.model.datasource.INode;
import it.unibas.spicy.model.datasource.KeyConstraint;
import it.unibas.spicy.model.mapping.IDataSourceProxy;
import it.unibas.spicy.model.paths.PathExpression;
import it.unibas.spicy.model.paths.operators.GeneratePathExpression;
import it.unibas.spicy.persistence.xml.model.XSDSchema;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class UpdateDataSourceWithConstraints {

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

    private GeneratePathExpression pathGenerator = new GeneratePathExpression();

    private Map<String, KeyConstraint> mapOfUnique = new HashMap<String, KeyConstraint>();
    private Map<String, KeyConstraint> mapOfKeys = new HashMap<String, KeyConstraint>();
    private Map<String, ForeignKeyConstraint> mapOfForeignKeys = new HashMap<String, ForeignKeyConstraint>();

    public void updateDataSource(IDataSourceProxy dataSource, XSDSchema xsdSchema) {
        // updateUniqueOrKeyConstraints must be invoked before updateWithForeignKeyConstraints
        this.processKeyConstraints(dataSource.getIntermediateSchema(), xsdSchema.getMapOfKeyConstraints());
        this.processUniqueConstraints(dataSource.getIntermediateSchema(), xsdSchema.getMapOfUniqueConstraints());
        this.processForeignKeyConstraints(dataSource.getIntermediateSchema(),
                xsdSchema.getMapOfForeignKeyConstraints());
        for (KeyConstraint keyConstraint : mapOfUnique.values()) {
            dataSource.addKeyConstraint(keyConstraint);
        }
        for (KeyConstraint keyConstraint : mapOfKeys.values()) {
            dataSource.addKeyConstraint(keyConstraint);
        }
        for (ForeignKeyConstraint foreignKeyConstraint : mapOfForeignKeys.values()) {
            dataSource.addForeignKeyConstraint(foreignKeyConstraint);
        }
    }

    private void processKeyConstraints(INode schema, Map<String, List<String[]>> mapOfKeyConstraints) {
        Set<String> keys = mapOfKeyConstraints.keySet();
        INode keyNode;
        for (String key : keys) {
            if (logger.isDebugEnabled())
                logger.debug(" -- key name: " + key);
            List<String[]> vectors = mapOfKeyConstraints.get(key);
            List<PathExpression> keyPathExpressions = new ArrayList<PathExpression>();
            FindNodeFromXPath nodeFinder = new FindNodeFromXPath();
            for (String[] vectorPaths : vectors) {
                keyNode = nodeFinder.findNode(schema, normalizeToList(vectorPaths));
                if (logger.isDebugEnabled())
                    logger.debug(" --- uniqueOrKeyNode: " + keyNode.getLabel() + " father: " + keyNode.getFather());
                PathExpression keyPathExpression = generatePathExpression(keyNode);
                keyPathExpressions.add(keyPathExpression);
            }
            addKeyConstraint(key, keyPathExpressions);
        }
    }

    private void processUniqueConstraints(INode schema, Map<String, List<String[]>> mapOfUniqueConstraints) {
        Set<String> keys = mapOfUniqueConstraints.keySet();
        INode uniqueNode;
        for (String key : keys) {
            if (logger.isDebugEnabled())
                logger.debug(" -- key name: " + key);
            List<String[]> vectors = mapOfUniqueConstraints.get(key);
            List<PathExpression> keyPathExpressions = new ArrayList<PathExpression>();
            FindNodeFromXPath nodeFinder = new FindNodeFromXPath();
            for (String[] vectorPaths : vectors) {
                uniqueNode = nodeFinder.findNode(schema, normalizeToList(vectorPaths));
                if (logger.isDebugEnabled())
                    logger.debug(" --- uniqueOrKeyNode: " + uniqueNode.getLabel() + " father: "
                            + uniqueNode.getFather());
                PathExpression keyPathExpression = generatePathExpression(uniqueNode);
                keyPathExpressions.add(keyPathExpression);
            }
            addUniqueConstraint(key, keyPathExpressions);
        }
    }

    private void processForeignKeyConstraints(INode schema,
            Map<String, List<String[]>> mapOfForeignKeyConstraints) {
        Set<String> keys = mapOfForeignKeyConstraints.keySet();
        INode foreignKeyNode;
        // constraint's keyName format: FK|PK
        for (String key : keys) {
            if (logger.isDebugEnabled())
                logger.debug(" -- key: " + key);
            if (key.indexOf("|") == -1) {
                throw new IllegalArgumentException(" foreign key name must be in format FK|PK, instead is " + key);
            }
            List<String[]> vectors = mapOfForeignKeyConstraints.get(key);
            String primaryKeyString = key.substring(key.indexOf("|") + 1);
            if (logger.isDebugEnabled())
                logger.debug(" --- FOREIGN KEY NAME: " + key + " with PRIMARY KEY NAME: " + primaryKeyString);
            List<PathExpression> foreignKeyPathExpressions = new ArrayList<PathExpression>();
            FindNodeFromXPath nodeFinder = new FindNodeFromXPath();
            for (String[] vectorPaths : vectors) {
                foreignKeyNode = nodeFinder.findNode(schema, normalizeToList(vectorPaths));
                if (logger.isDebugEnabled())
                    logger.debug(" --- foreignkey: " + foreignKeyNode.getLabel() + " father: "
                            + foreignKeyNode.getFather());
                PathExpression foreignKeyPathExpression = generatePathExpression(foreignKeyNode);
                foreignKeyPathExpressions.add(foreignKeyPathExpression);
            }
            addForeignKeyConstraint(key, foreignKeyPathExpressions, primaryKeyString);
        }
    }

    private PathExpression generatePathExpression(INode node) {
        return pathGenerator.generatePathFromRoot(node);
    }

    private List<String> normalizeToList(String[] vector) {
        String currentPath;
        ArrayList<String> listPaths = new ArrayList<String>();
        for (int i = 0; i < vector.length; i++) {
            currentPath = vector[i];
            listPaths.addAll(normalizePath(currentPath));
        }
        return listPaths;
    }

    private List<String> normalizePath(String path) {
        String currentPath = path;
        ArrayList<String> list = new ArrayList<String>();
        if (currentPath.startsWith(".")) {
            currentPath = path.substring(1);
        }
        currentPath = currentPath.replaceAll("\\@", "");
        currentPath = currentPath.replaceAll("\\*", "");

        StringTokenizer tokenizer = new StringTokenizer(currentPath, "/");
        if (tokenizer.countTokens() > 0) {
            if (logger.isDebugEnabled())
                logger.debug(" --- Tokenizer for " + path + " with " + tokenizer.countTokens() + " elements");
            while (tokenizer.hasMoreElements()) {
                String token = tokenizer.nextToken();
                if (!(token.trim().equals(""))) {
                    if (logger.isDebugEnabled())
                        logger.debug("\t +" + token + " added");
                    list.add(token);
                }
            }
        } else {
            if (!(currentPath.trim().equals(""))) {
                if (logger.isDebugEnabled())
                    logger.debug("\t +" + currentPath + " added");
                list.add(currentPath);
            }

        }

        if (logger.isDebugEnabled())
            logger.debug(" --- Size of list for " + path + " is = " + list.size());
        return list;
    }

    private void addUniqueConstraint(String key, List<PathExpression> pathExpressions) {
        KeyConstraint keyConstraint = new KeyConstraint(pathExpressions);
        this.mapOfUnique.put(key, keyConstraint);
    }

    private void addKeyConstraint(String key, List<PathExpression> pathExpressions) {
        KeyConstraint keyConstraint = new KeyConstraint(pathExpressions, true);
        this.mapOfKeys.put(key, keyConstraint);
    }

    private KeyConstraint getUniqueConstraint(String key) {
        return this.mapOfUnique.get(key);
    }

    private KeyConstraint getKeyConstraint(String key) {
        return this.mapOfKeys.get(key);
    }

    private void addForeignKeyConstraint(String foreignKeyName, List<PathExpression> pathExpressions,
            String primaryKeyName) {
        KeyConstraint keyConstraint = this.getKeyConstraint(primaryKeyName);
        ForeignKeyConstraint foreignKeyConstraint = new ForeignKeyConstraint(keyConstraint, pathExpressions);
        this.mapOfForeignKeys.put(foreignKeyName, foreignKeyConstraint);
    }
}