001package gudusoft.gsqlparser.dlineage.dataflow.metadata.grabit;
002
003import java.util.Collections;
004import java.util.Comparator;
005import java.util.LinkedHashMap;
006import java.util.List;
007import java.util.Map;
008
009import gudusoft.gsqlparser.EDbVendor;
010import gudusoft.gsqlparser.dlineage.dataflow.metadata.MetadataAnalyzer;
011import gudusoft.gsqlparser.dlineage.dataflow.model.ModelBindingManager;
012import gudusoft.gsqlparser.dlineage.dataflow.model.xml.column;
013import gudusoft.gsqlparser.dlineage.dataflow.model.xml.dataflow;
014import gudusoft.gsqlparser.dlineage.dataflow.model.xml.procedure;
015import gudusoft.gsqlparser.dlineage.dataflow.model.xml.table;
016import gudusoft.gsqlparser.dlineage.util.Pair3;
017import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
018import gudusoft.gsqlparser.sqlenv.TSQLEnv;
019import gudusoft.gsqlparser.util.SQLUtil;
020import gudusoft.gsqlparser.util.json.JSON;
021
022public class GrabitMetadataAnalyzer implements MetadataAnalyzer<String> {
023
024        private Map<String, procedure> procedureMap = new LinkedHashMap<String, procedure>();
025        private Map<String, table> tableMap = new LinkedHashMap<String, table>();
026        private Map<String, column> columnMap = new LinkedHashMap<String, column>();
027        private EDbVendor vendor;
028
029        @Override
030        public synchronized dataflow analyzeMetadata(EDbVendor vendor, String metadata) {
031                init(vendor);
032                dataflow dataflow = new dataflow();
033                Map json = (Map) JSON.parseObject(metadata.trim());
034        if (json.containsKey("createdBy")) {
035            String createdBy = (String) json.get("createdBy");
036            if (createdBy.toLowerCase().indexOf("grabit") != -1) {
037                List databases = (List) json.get("databases");
038                        if (databases != null) {
039                        
040                                for (int i = 0; i < databases.size(); i++) {
041                                        Map jsonDatabase = (Map) databases.get(i);
042                                        String databaseName = (String) jsonDatabase.get("name");
043                                        List tables = (List) jsonDatabase.get("tables");
044                                        for (int j = 0; j < tables.size(); j++) {
045                                                Map jsonTable = (Map) tables.get(j);
046                                                        databaseName = (String) jsonTable.get("database");
047                                                        if(databaseName.indexOf(".")!=-1) {
048                                                                databaseName = SQLUtil.quoteDottedName(vendor, ESQLDataObjectType.dotCatalog, databaseName);
049                                                        }
050                                                String schemeName = (String) jsonTable.get("schema");
051                                                if(schemeName.indexOf(".")!=-1) {
052                                                        schemeName = SQLUtil.quoteDottedName(vendor, ESQLDataObjectType.dotSchema, schemeName);
053                                                }
054                                                String tableName = (String) jsonTable.get("name");
055                                                if(tableName.indexOf(".")!=-1) {
056                                                        tableName = SQLUtil.quoteDottedName(vendor, ESQLDataObjectType.dotTable, tableName);
057                                                }
058                                                boolean isView = false;
059                                                if (jsonTable.containsKey("isView")) {
060                                                        isView = Boolean.parseBoolean((String) jsonTable.get("isView"));
061                                                }
062                                                List columns = (List) jsonTable.get("columns");
063                                                for (int k = 0; k < columns.size(); k++) {
064                                                        Map jsonColumn = (Map) columns.get(k);
065                                                        String columnName = (String) jsonColumn.get("name");
066                                                        appendTable(dataflow, databaseName, schemeName, tableName, isView, columnName);
067                                                }
068                                        }
069                                }
070                        }
071            }
072        }
073                sortTableColumns(dataflow);
074                return dataflow;
075        }
076
077        private void init(EDbVendor vendor) {
078                this.vendor = vendor;
079                procedureMap.clear();
080                tableMap.clear();
081                columnMap.clear();
082                if (ModelBindingManager.get() == null) {
083                        ModelBindingManager.set(new ModelBindingManager());
084                }
085        }
086
087        private void sortTableColumns(dataflow dataflow) {
088                if (dataflow.getTables() != null) {
089                        for (table table : dataflow.getTables()) {
090                                Collections.sort(table.getColumns(), new Comparator<column>() {
091                                        public int compare(column t1, column t2) {
092                                                if (t1.getName().equalsIgnoreCase("RelationRows"))
093                                                        return 1;
094                                                if (t2.getName().equalsIgnoreCase("RelationRows"))
095                                                        return -1;
096                                                return 0;
097                                        }
098                                });
099                        }
100                }
101
102                if (dataflow.getResultsets() != null) {
103                        for (table table : dataflow.getResultsets()) {
104                                Collections.sort(table.getColumns(), new Comparator<column>() {
105                                        public int compare(column t1, column t2) {
106                                                if (t1.getName().equalsIgnoreCase("RelationRows"))
107                                                        return 1;
108                                                if (t2.getName().equalsIgnoreCase("RelationRows"))
109                                                        return -1;
110                                                return 0;
111                                        }
112                                });
113                        }
114                }
115        }
116
117        private void appendTable(dataflow dataflow, String databaseName, String schemaName, String tableName,
118                        boolean isView, String columnName) {
119                String tableKey = getFullName(databaseName, schemaName, tableName);
120                if (!tableMap.containsKey(tableKey)) {
121                        table table = new table();
122                        table.setDatabase(databaseName);
123                        table.setSchema(schemaName);
124                        table.setName(tableName);
125                        if (!SQLUtil.isEmpty(table.getSchema()) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(table.getSchema())) {
126                                table.setName(table.getSchema() + "." + table.getName());
127                        }
128                        if (!SQLUtil.isEmpty(table.getDatabase()) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(table.getDatabase())) {
129                                table.setName(table.getDatabase() + "." + table.getName());
130                        }
131                        table.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
132                        table.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
133                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
134                                        + new Pair3<Long, Long, Integer>(-1L, -1L,
135                                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
136                        if (isView) {
137                                table.setType("view");
138                                dataflow.getViews().add(table);
139                        } else {
140                                table.setType("table");
141                                dataflow.getTables().add(table);
142                        }
143                        tableMap.put(tableKey, table);
144                }
145
146                table table = tableMap.get(tableKey);
147                String sourceColumnKey = getFullName(databaseName, schemaName, tableName, columnName);
148                if (!columnMap.containsKey(sourceColumnKey)) {
149                        column column = new column();
150                        column.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
151                        column.setName(columnName);
152                        if ("RelationRows".equalsIgnoreCase(columnName)) {
153                                column.setSource("system");
154                        }
155                        column.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
156                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
157                                        + new Pair3<Long, Long, Integer>(-1L, -1L,
158                                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
159                        table.getColumns().add(column);
160                        columnMap.put(sourceColumnKey, column);
161                }
162        }
163
164        private String getFullName(String... segments) {
165                StringBuilder builder = new StringBuilder();
166                for (int i = 0; i < segments.length; i++) {
167                        builder.append(segments[i]);
168                        if (i < segments.length - 1) {
169                                builder.append(".");
170                        }
171                }
172                return builder.toString().replace("null.", "");
173        }
174}