com.hangum.tadpole.rdb.erd.core.relation.RelationUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.hangum.tadpole.rdb.erd.core.relation.RelationUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2013 hangum.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     hangum - initial API and implementation
 ******************************************************************************/
package com.hangum.tadpole.rdb.erd.core.relation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.hangum.tadpole.commons.libs.core.define.PublicTadpoleDefine;
import com.hangum.tadpole.engine.define.DBDefine;
import com.hangum.tadpole.engine.manager.TadpoleSQLManager;
import com.hangum.tadpole.engine.query.dao.mysql.ReferencedTableDAO;
import com.hangum.tadpole.engine.query.dao.sqlite.SQLiteRefTableDAO;
import com.hangum.tadpole.engine.query.dao.system.UserDBDAO;
import com.hangum.tadpole.rdb.model.Column;
import com.hangum.tadpole.rdb.model.DB;
import com.hangum.tadpole.rdb.model.RdbFactory;
import com.hangum.tadpole.rdb.model.Relation;
import com.hangum.tadpole.rdb.model.RelationKind;
import com.hangum.tadpole.rdb.model.Table;
import com.ibatis.sqlmap.client.SqlMapClient;

/**
 * ERD  Table relation  
 * 
 * <pre>      
  
   constraint_name      :    ?? ?
   table_name            :     ? ?
   column_name         :     ? 
       
   referenced_table_name   :    ? ?
   referenced_column_name   :     ? 
 * </pre>
 * 
 * @author hangum
 *
 */
public class RelationUtil {
    private static final Logger logger = Logger.getLogger(RelationUtil.class);

    /**
     *  ?  .
     * 
     * @param userDB
     * @param mapDBTables
     * @param db
     * @param refTableNames
     * @throws Exception
     */
    public static void calRelation(UserDBDAO userDB, Map<String, Table> mapDBTables, DB db, String refTableNames) {
        try {

            //  sqlite  ?  .
            if (DBDefine.SQLite_DEFAULT == userDB.getDBDefine()) {
                calRelation(userDB, mapDBTables, db, makeSQLiteRelation(userDB));

            } else if (DBDefine.CUBRID_DEFAULT == userDB.getDBDefine()) {
                calRelation(userDB, mapDBTables, db, CubridTableRelation.makeCubridRelation(userDB, refTableNames));

            } else if (DBDefine.HIVE_DEFAULT == userDB.getDBDefine()
                    | DBDefine.HIVE2_DEFAULT == userDB.getDBDefine()) {
                // ignore relation code
            } else if (DBDefine.TAJO_DEFAULT == userDB.getDBDefine()) {
                // ignore relation code
            } else {
                calRelation(userDB, mapDBTables, db, getReferenceTable(userDB, refTableNames));
            }
        } catch (Exception e) {
            logger.error("create relation ", e);
        }
    }

    /**
     *  ?? .
     * 
     * @param userDB
     * @param mapDBTables
     * @param db
     * @throws Exception
     */
    public static void calRelation(UserDBDAO userDB, Map<String, Table> mapDBTables, DB db) {

        try {
            //  sqlite  ?  .
            if (DBDefine.SQLite_DEFAULT == userDB.getDBDefine()) {
                calRelation(userDB, mapDBTables, db, makeSQLiteRelation(userDB));
            } else if (DBDefine.CUBRID_DEFAULT == userDB.getDBDefine()) {
                calRelation(userDB, mapDBTables, db, CubridTableRelation.makeCubridRelation(userDB));
            } else if (DBDefine.HIVE_DEFAULT == userDB.getDBDefine()
                    | DBDefine.HIVE2_DEFAULT == userDB.getDBDefine()) {
                // ignore relation code
            } else if (DBDefine.TAJO_DEFAULT == userDB.getDBDefine()) {
                // ignore relation code
            } else {
                calRelation(userDB, mapDBTables, db, getReferenceTable(userDB));
            }
        } catch (Exception e) {
            logger.error("create relation ", e);
        }
    }

    /**
     * sqlite? relation? .
     * 
     * @param userDB
     * @return
     */
    private static List<ReferencedTableDAO> makeSQLiteRelation(UserDBDAO userDB) {
        List<ReferencedTableDAO> listRealRefTableDAO = new ArrayList<ReferencedTableDAO>();

        try {
            //  ? ?.
            for (SQLiteRefTableDAO sqliteRefTableDAO : getSQLiteRefTbl(userDB)) {

                String strFullTextSQL = sqliteRefTableDAO.getSql();
                if (logger.isDebugEnabled())
                    logger.debug("\t full text:" + strFullTextSQL);

                int indexKey = StringUtils.indexOf(strFullTextSQL, "FOREIGN KEY");
                if (indexKey == -1) {
                    indexKey = StringUtils.indexOf(strFullTextSQL, "foreign key");

                    if (indexKey == -1) {
                        if (logger.isDebugEnabled())
                            logger.debug("Not found foreign keys.");
                        continue;
                    }
                }

                String forKey = sqliteRefTableDAO.getSql().substring(indexKey);
                if (logger.isDebugEnabled())
                    logger.debug("\t=================>[forKeys]\n" + forKey);
                String[] foreignInfo = forKey.split("FOREIGN KEY");
                if (foreignInfo.length == 1)
                    foreignInfo = forKey.split("foreign key");

                for (int i = 1; i < foreignInfo.length; i++) {
                    try {
                        String strForeign = foreignInfo[i];
                        if (logger.isDebugEnabled())
                            logger.debug("\t ==========================> sub[\n" + strForeign + "]");
                        ReferencedTableDAO ref = new ReferencedTableDAO();

                        // ? 
                        ref.setTable_name(sqliteRefTableDAO.getTbl_name());

                        // ,  (   ) ??...
                        String colName = StringUtils.substringBetween(strForeign, "(", ")");

                        //  ?,  REFERENCES    ?  (
                        String refTbName = StringUtils.substringBetween(strForeign, "REFERENCES", "(");
                        if ("".equals(refTbName) || null == refTbName)
                            refTbName = StringUtils.substringBetween(strForeign, "references", "(");

                        //  ,  refTbName? ??  ) ...
                        String refCol = StringUtils.substringBetween(strForeign, refTbName + "(", ")");

                        ref.setColumn_name(moveSpec(colName));
                        ref.setReferenced_table_name(moveSpec(refTbName));
                        ref.setReferenced_column_name(moveSpec(refCol));

                        // sqlite ?? ? .... ?.
                        ref.setConstraint_name(ref.toString());

                        listRealRefTableDAO.add(ref);

                    } catch (Exception e) {
                        logger.error("SQLLite Relation making", e);
                    }
                } // inner if

            } // last for
        } catch (Exception e) {
            logger.error("SQLite Relation check 2", e);
        }

        return listRealRefTableDAO;
    }

    private static String moveSpec(String val) {
        return StringUtils.trimToEmpty(val.replaceAll("\\[", "").replaceAll("\\]", ""));
    }

    /**
     * ?  .
     * 
     * @param userDB
     * @param mapDBTables
     * @param db
     * @throws Exception
     */
    public static void calRelation(UserDBDAO userDB, Map<String, Table> mapDBTables, DB db,
            List<ReferencedTableDAO> referenceTableList) throws Exception {

        RdbFactory tadpoleFactory = RdbFactory.eINSTANCE;

        // ?    .
        for (ReferencedTableDAO refTabDAO : referenceTableList) {
            try {
                Table soTabMod = mapDBTables.get(refTabDAO.getTable_name());
                Table tarTabMod = mapDBTables.get(refTabDAO.getReferenced_table_name());

                // ?? ?? ,  ??  . 
                if (soTabMod != null && tarTabMod != null) {

                    // ? ? relation? .
                    boolean isAlrealyAppend = false;
                    for (Relation relation : soTabMod.getOutgoingLinks()) {

                        if (relation.getConstraint_name() != null && refTabDAO.getConstraint_name() != null) {
                            if (relation.getConstraint_name().equalsIgnoreCase(refTabDAO.getConstraint_name())) {
                                isAlrealyAppend = true;
                                break;
                            }
                        }
                    }
                    for (Relation relation : soTabMod.getIncomingLinks()) {

                        if (relation.getConstraint_name() != null && refTabDAO.getConstraint_name() != null) {
                            if (relation.getConstraint_name().equalsIgnoreCase(refTabDAO.getConstraint_name())) {
                                isAlrealyAppend = true;
                                break;
                            }
                        }
                    }

                    // TODO  ?? ??  ?  ? ? ? ?  . 
                    // java.lang.RuntimeException: Cycle detected in graph
                    if (refTabDAO.getTable_name().equalsIgnoreCase(refTabDAO.getReferenced_table_name()))
                        continue;

                    // ?  ? ?
                    if (isAlrealyAppend)
                        continue;

                    //  ?  ?.
                    Relation relation = tadpoleFactory.createRelation();
                    /*   ?  ?  
                     *   ? ? 
                     *  
                     * org.eclipse.emf.ecore.resource.Resource$IOWrappedException: 
                     * The object 'com.hangum.tadpole.model.impl.RelationImpl@5e44efa0 (source_kind: ONLY_ONE, target_kind: ONE_MANY, column_name: country_id, referenced_column_name: country_id, bendpoint: [], constraint_name: null)' 
                     * is not contained in a resource.
                     */
                    relation.setDb(db);

                    relation.setConstraint_name(refTabDAO.getConstraint_name());

                    relation.setColumn_name(refTabDAO.getColumn_name());
                    relation.setReferenced_column_name(refTabDAO.getReferenced_column_name());

                    /*
                     * ? ?  ? ?? ?.
                     */
                    Map<String, Column> sourceColumnsMap = new HashMap<String, Column>();
                    Map<String, Column> targetColumnMap = new HashMap<String, Column>();
                    for (Column column : soTabMod.getColumns())
                        sourceColumnsMap.put(column.getField(), column);
                    for (Column column : tarTabMod.getColumns())
                        targetColumnMap.put(column.getField(), column);

                    // source  
                    Column col = sourceColumnsMap.get(refTabDAO.getColumn_name().replaceAll(",", ""));

                    // target  
                    Column colR = targetColumnMap.get(refTabDAO.getReferenced_column_name().replaceAll(",", ""));
                    if (logger.isDebugEnabled()) {
                        if (col == null || colR == null) {
                            logger.debug(
                                    "###[table index]###############################################################################");
                            logger.debug(db.getUrl() + ":" + refTabDAO.toString());
                            logger.debug(
                                    "###[table index]###############################################################################");
                        }
                    }
                    if (col == null || colR == null)
                        continue;

                    //            logger.debug("\t [source ]" + col.getField() + " [key]" + col.getKey());
                    //            logger.debug("\t [target ]" + colR.getField() + " [key]" + colR.getKey());
                    relation.setSource_kind(calcRelationCol(col, colR));
                    relation.setTarget_kind(calcRelationCol(colR, col));

                    // 
                    soTabMod.getIncomingLinks().add(relation);
                    tarTabMod.getOutgoingLinks().add(relation);

                    relation.setSource(soTabMod);
                    relation.setTarget(tarTabMod);

                } // if(souceModel != null && targetModel != null
            } catch (Exception e) {
                logger.error("create relation", e);
            }

        } // for
    }

    /**
     *  ?? ? relational type? ?.
     * 
     * ? ? NULL?  ?? ?? ?.
     * 
     * @param soCol source table
     * @rapap taCol target table
     * @return
     */
    public static RelationKind calcRelationCol(Column soCol, Column taCol) {
        if ("YES".equals(taCol.getNull()) || "YES".equals(soCol.getNull())) {

            if (PublicTadpoleDefine.isPK(soCol.getKey()))
                return RelationKind.ZERO_OR_ONE;
            else
                return RelationKind.ZERO_OR_MANY;

        } else {

            if (PublicTadpoleDefine.isPK(soCol.getKey()))
                return RelationKind.ONLY_ONE;
            else
                return RelationKind.ONE_OR_MANY;

        }
    }

    /**
     * sqlite  ?
     * @param userDB
     * @return
     * @throws Exception
     */
    public static List<SQLiteRefTableDAO> getSQLiteRefTbl(UserDBDAO userDB) throws Exception {
        SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
        return sqlClient.queryForList("referencedTableListALL");
    }

    /**
     * sqlite  ?
     * @param userDB
     * @return
     * @throws Exception
     */
    public static List<SQLiteRefTableDAO> getSQLiteRefTbl(UserDBDAO userDB, String tableName) throws Exception {
        SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
        return sqlClient.queryForList("referencedTableList", tableName);
    }

    /**
     * ??  ?  .
     * 
     * @return
     * @throws Exception
     */
    public static List<ReferencedTableDAO> getReferenceTable(UserDBDAO userDB, String tableName) throws Exception {
        SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
        return sqlClient.queryForList("referencedTableList", tableName);
    }

    /**
     * ??  ?  .
     * 
     * @return
     * @throws Exception
     */
    public static List<ReferencedTableDAO> getReferenceTable(UserDBDAO userDB) throws Exception {
        SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
        return sqlClient.queryForList("referencedTableListALL");
    }

}