001package gudusoft.gsqlparser.dlineage.dataflow.metadata.sqlflow;
002
003import gudusoft.gsqlparser.EDbVendor;
004import gudusoft.gsqlparser.dlineage.dataflow.metadata.MetadataAnalyzer;
005import gudusoft.gsqlparser.dlineage.dataflow.model.EffectType;
006import gudusoft.gsqlparser.dlineage.dataflow.model.ModelBindingManager;
007import gudusoft.gsqlparser.dlineage.dataflow.model.RelationshipType;
008import gudusoft.gsqlparser.dlineage.dataflow.model.SubType;
009import gudusoft.gsqlparser.dlineage.dataflow.model.TableColumnRelationshipElement;
010import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*;
011import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
012import gudusoft.gsqlparser.dlineage.util.Pair3;
013import gudusoft.gsqlparser.dlineage.util.XML2Model;
014import gudusoft.gsqlparser.sqlenv.TSQLEnv;
015import gudusoft.gsqlparser.util.SQLUtil;
016import gudusoft.gsqlparser.util.json.JSON;
017
018import java.io.File;
019import java.util.*;
020
021public class SqlflowMetadataAnalyzer implements MetadataAnalyzer<String> {
022
023    private Map<String, procedure> procedureMap = new LinkedHashMap<String, procedure>();
024    private Map<String, table> tableMap = new LinkedHashMap<String, table>();
025    private Map<String, oraclePackage> oraclePackageMap = new LinkedHashMap<String, oraclePackage>();
026    private Map<String, column> columnMap = new LinkedHashMap<String, column>();
027    private EDbVendor vendor;
028    private TSQLEnv sqlenv;
029
030    public SqlflowMetadataAnalyzer() {
031    }
032
033    public SqlflowMetadataAnalyzer(TSQLEnv sqlenv) {
034        this.sqlenv = sqlenv;
035    }
036
037    @Override
038    public synchronized dataflow analyzeMetadata(EDbVendor metadataVendor, String metadata) {
039        init(vendor);
040        dataflow dataflow = new dataflow();
041        Map json = (Map) JSON.parseObject(metadata.trim());
042        if (json.containsKey("createdBy")) {
043            String createdBy = (String) json.get("createdBy");
044            if (createdBy.toLowerCase().indexOf("sqlflow") != -1) {
045                List servers = (List) json.get("servers");
046                for (int x = 0; x < servers.size(); x++) {
047                    Map server = (Map) servers.get(x);
048                    String serverName = (String) server.get("name");
049                    String dbVendor = (String) server.get("dbVendor");
050
051                    EDbVendor vendor = metadataVendor;
052                    if (dbVendor != null) {
053                        vendor = EDbVendor.valueOf(dbVendor);
054                    }
055
056                    boolean supportsCatalogs = TSQLEnv.supportCatalog(vendor);
057                    boolean supportsSchemas = TSQLEnv.supportSchema(vendor);
058
059                    if (supportsCatalogs && supportsSchemas) {
060                        List databases = (List) server.get("databases");
061                        if (databases == null) {
062                            continue;
063                        }
064                        for (int i = 0; i < databases.size(); i++) {
065                            Map jsonDatabase = (Map) databases.get(i);
066                            String databaseName = (String) jsonDatabase.get("name");
067                                                        if (SQLUtil.parseNames(databaseName).size() > 1) {
068                                                                databaseName = "\"" + databaseName + "\"";
069                                                        }
070                            List schemas = (List) jsonDatabase.get("schemas");
071                            if (schemas == null) {
072                                continue;
073                            }
074                            for (int j = 0; j < schemas.size(); j++) {
075                                Map jsonSchema = (Map) schemas.get(j);
076                                String schemaName = (String) jsonSchema.get("name");
077                                if (SQLUtil.parseNames(schemaName).size() > 1) {
078                                        schemaName = "\"" + schemaName + "\"";
079                                                        }
080                                List tables = (List) jsonSchema.get("tables");
081                                List views = (List) jsonSchema.get("views");
082                              
083                                List dbObjs = new ArrayList();
084                                if (tables != null) {
085                                    dbObjs.addAll(tables);
086                                }
087                                if (views != null) {
088                                    dbObjs.addAll(views);
089                                }
090                                for (int k = 0; k < dbObjs.size(); k++) {
091                                    Map jsonTable = (Map) dbObjs.get(k);
092                                    String tableName = (String) jsonTable.get("name");
093                                    String type = (String) jsonTable.get("type");
094                                    String fromDDL = (String) jsonTable.get("fromDDL");
095                                    boolean isView = false;
096                                    if (type != null && type.toLowerCase().indexOf("view") != -1) {
097                                        isView = true;
098                                    }
099                                    List columns = (List) jsonTable.get("columns");
100                                    for (int l = 0; l < columns.size(); l++) {
101                                        Map jsonColumn = (Map) columns.get(l);
102                                        String columnName = (String) jsonColumn.get("name");
103                                        String dataType = null;
104                                        if (jsonColumn.containsKey("dataType")){
105                                            dataType = (String) jsonColumn.get("dataType");
106                                        }
107                                        Boolean primaryKey = null;
108                                        if (jsonColumn.containsKey("primaryKey")){
109                                            primaryKey = (Boolean) jsonColumn.get("primaryKey");
110                                        }
111                                        Boolean unqiueKey = null;
112                                        if (jsonColumn.containsKey("unqiueKey")){
113                                            unqiueKey = (Boolean) jsonColumn.get("unqiueKey");
114                                        }
115                                        Boolean indexKey = null;
116                                        if (jsonColumn.containsKey("indexKey")){
117                                            indexKey = (Boolean) jsonColumn.get("indexKey");
118                                        }
119                                        Boolean foreignKey = null;
120                                        if (jsonColumn.containsKey("foreignKey")){
121                                            foreignKey = (Boolean) jsonColumn.get("foreignKey");
122                                        }
123                                        appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName,
124                                                schemaName, tableName, isView, false, columnName, dataType, primaryKey, unqiueKey, indexKey, foreignKey, fromDDL);
125                                    }
126                                }
127                                
128                                List synonyms = (List) jsonSchema.get("synonyms");
129                                                                if (synonyms != null) {
130                                                                        for (int k = 0; k < synonyms.size(); k++) {
131                                                                                Map jsonTable = (Map) synonyms.get(k);
132                                                                                String synonymsName = (String) jsonTable.get("name");
133                                                                                String synonymsDatabaseName = (String) jsonTable.get("database");
134                                                                                String synonymsSchemaName = (String) jsonTable.get("schema");
135
136                                                                                String synonymsSourceName = (String) jsonTable.get("sourceName");
137                                                                                String synonymsSourceDatabaseName = (String) jsonTable.get("sourceDbLinkName");
138                                                                                String synonymsSourceSchemaName = (String) jsonTable.get("sourceSchema");
139
140                                                                                if (SQLUtil.isEmpty(synonymsSourceDatabaseName)) {
141                                                                                        synonymsSourceDatabaseName = synonymsDatabaseName;
142                                                                                }
143                                                                                
144                                                                                if (SQLUtil.isEmpty(synonymsSourceSchemaName)) {
145                                                                                        synonymsSourceSchemaName = synonymsSchemaName;
146                                                                                }
147
148                                                                                String tableKey = getFullTableName(vendor, serverName, synonymsSourceDatabaseName,
149                                                                                                synonymsSourceSchemaName, synonymsSourceName);
150                                                                                table sourceTable = tableMap.get(tableKey);
151                                                                                if (sourceTable != null) {
152                                                                                        List columns = (List) sourceTable.getColumns();
153                                            String fromDDL = sourceTable.getFromDDL();
154                                                                                        dbObjs.add(jsonTable);
155                                                                                        for (int l = 0; l < columns.size(); l++) {
156                                                                                                column jsonColumn = (column) columns.get(l);
157                                                                                                String columnName = (String) jsonColumn.getName();
158                                                                                                String dataType = jsonColumn.getDataType();
159                                                                                                appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow,
160                                                                                                                serverName, databaseName, schemaName, synonymsName, false, true,
161                                                                                                                columnName, dataType, false, false, false, false, fromDDL);
162                                                                                        }
163                                                                                        
164                                                                                        String synonymsTableKey = getFullTableName(vendor, serverName,
165                                                                                                        synonymsDatabaseName, synonymsSchemaName, synonymsName);
166                                                                                        table synonymsTable = tableMap.get(synonymsTableKey);
167                                                                                        if (synonymsTable != null) {
168                                                                                                List synonymsColumns = (List) synonymsTable.getColumns();
169                                                                                                
170                                                                                                for (int l = 0; l < synonymsColumns.size(); l++) {
171                                                                                                        relationship relationElement = new relationship();
172                                                                                                        relationElement.setType(RelationshipType.fdd.name());
173                                                                                                        relationElement.setEffectType(EffectType.synonym.name());
174                                                                                                                
175                                                                                                        long id = ++ModelBindingManager.get().RELATION_ID;
176                                                                                                        relationElement.setId(String.valueOf(id));
177                                                                                                        
178                                                                                                        column targetColumn = (column)synonymsColumns.get(l);
179                                                                                                        targetColumn target = new targetColumn();
180                                                                                                        target.setId(String.valueOf(targetColumn.getId()));
181                                                                                                        target.setColumn(targetColumn.getName());
182                                                                                                        target.setParent_id(String.valueOf(synonymsTable.getId()));
183                                                                                                        target.setParent_name(synonymsTable.getName());
184                                                                                                        relationElement.setTarget(target);
185                                        
186                                                                                                        column sourceColumn = (column)columns.get(l);
187                                                                                                        sourceColumn source = new sourceColumn();
188                                                                                                        source.setId(String.valueOf(sourceColumn.getId()));
189                                                                                                        source.setColumn(sourceColumn.getName());
190                                                                                                        source.setParent_id(String.valueOf(sourceTable.getId()));
191                                                                                                        source.setParent_name(sourceTable.getName());
192                                                                                                        relationElement.addSource(source);
193                                                                                                        
194                                                                                                        dataflow.getRelationships().add(relationElement);
195                                                                                                }
196                                                                                        }
197                                                                                }
198                                                                        }
199                                                                }
200                                
201                                List<Map> procedures = (List<Map>) jsonSchema.get("procedures");
202                                if (procedures != null) {
203                                    for (Map procedure : procedures) {
204                                        appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, procedure, null);
205                                    }
206                                }
207                                List<Map> functions = (List<Map>) jsonSchema.get("functions");
208                                if (functions != null) {
209                                    for (Map function : functions) {
210                                        appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, function, null);
211                                    }
212                                }
213                                List<Map> triggers = (List<Map>) jsonSchema.get("triggers");
214                                if (triggers != null) {
215                                    for (Map trigger : triggers) {
216                                        appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, trigger, null);
217                                    }
218                                }
219                            }
220                        }
221                    } else if (supportsCatalogs) {
222                        List databases = (List) server.get("databases");
223                        if (databases == null) {
224                            continue;
225                        }
226                        for (int i = 0; i < databases.size(); i++) {
227                            Map jsonDatabase = (Map) databases.get(i);
228                            String databaseName = (String) jsonDatabase.get("name");
229                            if (SQLUtil.parseNames(databaseName).size() > 1) {
230                                                                databaseName = "\"" + databaseName + "\"";
231                                                        }
232                            List tables = (List) jsonDatabase.get("tables");
233                            List views = (List) jsonDatabase.get("views");
234                            List dbObjs = new ArrayList();
235                            if (tables != null) {
236                                dbObjs.addAll(tables);
237                            }
238                            if (views != null) {
239                                dbObjs.addAll(views);
240                            }
241                            for (int k = 0; k < dbObjs.size(); k++) {
242                                Map jsonTable = (Map) dbObjs.get(k);
243                                String tableName = (String) jsonTable.get("name");
244                                String type = (String) jsonTable.get("type");
245                                String fromDDL = (String) jsonTable.get("fromDDL");
246                                boolean isView = false;
247                                if (type != null && type.toLowerCase().indexOf("view") != -1) {
248                                    isView = true;
249                                }
250                                List columns = (List) jsonTable.get("columns");
251                                for (int l = 0; l < columns.size(); l++) {
252                                    Map jsonColumn = (Map) columns.get(l);
253                                    String columnName = (String) jsonColumn.get("name");
254                                    String dataType = null;
255                                    if (jsonColumn.containsKey("dataType")){
256                                        dataType = (String) jsonColumn.get("dataType");
257                                    }
258                                    Boolean primaryKey = null;
259                                    if (jsonColumn.containsKey("primaryKey")){
260                                        primaryKey = (Boolean) jsonColumn.get("primaryKey");
261                                    }
262                                    Boolean unqiueKey = null;
263                                    if (jsonColumn.containsKey("unqiueKey")){
264                                        unqiueKey = (Boolean) jsonColumn.get("unqiueKey");
265                                    }
266                                    Boolean indexKey = null;
267                                    if (jsonColumn.containsKey("indexKey")){
268                                        indexKey = (Boolean) jsonColumn.get("indexKey");
269                                    }
270                                    Boolean foreignKey = null;
271                                    if (jsonColumn.containsKey("foreignKey")){
272                                        foreignKey = (Boolean) jsonColumn.get("foreignKey");
273                                    }
274                                    appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName,
275                                            null, tableName, isView, false, columnName, dataType, primaryKey, unqiueKey, indexKey, foreignKey, fromDDL);
276                                }
277                            }
278                            
279                            List synonyms = (List) jsonDatabase.get("synonyms");
280                                                        if (synonyms != null) {
281                                                                for (int k = 0; k < synonyms.size(); k++) {
282                                                                        Map jsonTable = (Map) synonyms.get(k);
283                                                                        String synonymsName = (String) jsonTable.get("name");
284                                                                        String synonymsDatabaseName = (String) jsonTable.get("database");
285
286                                                                        String synonymsSourceName = (String) jsonTable.get("sourceName");
287                                                                        String synonymsSourceDatabaseName = (String) jsonTable.get("sourceDbLinkName");
288
289                                                                        if (SQLUtil.isEmpty(synonymsSourceDatabaseName)) {
290                                                                                synonymsSourceDatabaseName = synonymsDatabaseName;
291                                                                        }
292
293                                                                        String tableKey = getFullTableName(vendor, serverName, synonymsSourceDatabaseName,
294                                                                                        null, synonymsSourceName);
295                                                                        table sourceTable = tableMap.get(tableKey);
296                                                                        if (sourceTable != null) {
297                                                                                List columns = (List) sourceTable.getColumns();
298                                        String fromDDL = sourceTable.getFromDDL();
299                                                                                dbObjs.add(jsonTable);
300                                                                                for (int l = 0; l < columns.size(); l++) {
301                                                                                        column jsonColumn = (column) columns.get(l);
302                                                                                        String columnName = (String) jsonColumn.getName();
303                                                                                        String dataType = jsonColumn.getDataType();
304                                                                                        appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow,
305                                                                                                        serverName, databaseName, null, synonymsName, false, true,
306                                                                                                        columnName, dataType, false, false, false, false, fromDDL);
307                                                                                }
308                                                                                
309                                                                                String synonymsTableKey = getFullTableName(vendor, serverName,
310                                                                                                synonymsDatabaseName, null, synonymsName);
311                                                                                table synonymsTable = tableMap.get(synonymsTableKey);
312                                                                                if (synonymsTable != null) {
313                                                                                        List synonymsColumns = (List) synonymsTable.getColumns();
314                                                                                        
315                                                                                        for (int l = 0; l < synonymsColumns.size(); l++) {
316                                                                                                relationship relationElement = new relationship();
317                                                                                                relationElement.setType(RelationshipType.fdd.name());
318                                                                                                relationElement.setEffectType(EffectType.synonym.name());
319                                                                                                        
320                                                                                                long id = ++ModelBindingManager.get().RELATION_ID;
321                                                                                                relationElement.setId(String.valueOf(id));
322                                                                                                
323                                                                                                column targetColumn = (column)synonymsColumns.get(l);
324                                                                                                targetColumn target = new targetColumn();
325                                                                                                target.setId(String.valueOf(targetColumn.getId()));
326                                                                                                target.setColumn(targetColumn.getName());
327                                                                                                target.setParent_id(String.valueOf(synonymsTable.getId()));
328                                                                                                target.setParent_name(synonymsTable.getName());
329                                                                                                relationElement.setTarget(target);
330                                
331                                                                                                column sourceColumn = (column)columns.get(l);
332                                                                                                sourceColumn source = new sourceColumn();
333                                                                                                source.setId(String.valueOf(sourceColumn.getId()));
334                                                                                                source.setColumn(sourceColumn.getName());
335                                                                                                source.setParent_id(String.valueOf(sourceTable.getId()));
336                                                                                                source.setParent_name(sourceTable.getName());
337                                                                                                relationElement.addSource(source);
338                                                                                                
339                                                                                                dataflow.getRelationships().add(relationElement);
340                                                                                        }
341                                                                                }
342                                                                        }
343                                                                }
344                                                        }
345                                                        
346                            List<Map> procedures = (List<Map>) jsonDatabase.get("procedures");
347                            if (procedures != null) {
348                                for (Map procedure : procedures) {
349                                    appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, null, procedure, null);
350                                }
351                            }
352                            List<Map> functions = (List<Map>) jsonDatabase.get("functions");
353                            if (functions != null) {
354                                for (Map function : functions) {
355                                    appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, null, function, null);
356                                }
357                            }
358                            List<Map> triggers = (List<Map>) jsonDatabase.get("triggers");
359                            if (triggers != null) {
360                                for (Map trigger : triggers) {
361                                    appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, null, trigger, null);
362                                }
363                            }
364                        }
365                    } else if (supportsSchemas) {
366                        List schemas = (List) server.get("schemas");
367                        if (schemas == null) {
368                            continue;
369                        }
370                        for (int i = 0; i < schemas.size(); i++) {
371                            Map jsonSchema = (Map) schemas.get(i);
372                            String schemaName = (String) jsonSchema.get("name");
373                            if (SQLUtil.parseNames(schemaName).size() > 1) {
374                                schemaName = "\"" + schemaName + "\"";
375                                                        }
376                            List tables = (List) jsonSchema.get("tables");
377                            List views = (List) jsonSchema.get("views");
378                            List dbObjs = new ArrayList();
379                            if (tables != null) {
380                                dbObjs.addAll(tables);
381                            }
382                            if (views != null) {
383                                dbObjs.addAll(views);
384                            }
385                            for (int k = 0; k < dbObjs.size(); k++) {
386                                Map jsonTable = (Map) dbObjs.get(k);
387                                String tableName = (String) jsonTable.get("name");
388                                String type = (String) jsonTable.get("type");
389                                String fromDDL = (String) jsonTable.get("fromDDL");
390                                boolean isView = false;
391                                if (type != null && type.toLowerCase().indexOf("view") != -1) {
392                                    isView = true;
393                                }
394                                List columns = (List) jsonTable.get("columns");
395                                for (int l = 0; l < columns.size(); l++) {
396                                    Map jsonColumn = (Map) columns.get(l);
397                                    String columnName = (String) jsonColumn.get("name");
398                                    String dataType = null;
399                                    if (jsonColumn.containsKey("dataType")){
400                                        dataType = (String) jsonColumn.get("dataType");
401                                    }
402                                    Boolean primaryKey = null;
403                                    if (jsonColumn.containsKey("primaryKey")){
404                                        primaryKey = (Boolean) jsonColumn.get("primaryKey");
405                                    }
406                                    Boolean unqiueKey = null;
407                                    if (jsonColumn.containsKey("unqiueKey")){
408                                        unqiueKey = (Boolean) jsonColumn.get("unqiueKey");
409                                    }
410                                    Boolean indexKey = null;
411                                    if (jsonColumn.containsKey("indexKey")){
412                                        indexKey = (Boolean) jsonColumn.get("indexKey");
413                                    }
414                                    Boolean foreignKey = null;
415                                    if (jsonColumn.containsKey("foreignKey")){
416                                        foreignKey = (Boolean) jsonColumn.get("foreignKey");
417                                    }
418                                    appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null,
419                                            schemaName, tableName, isView, false, columnName, dataType, primaryKey, unqiueKey, indexKey, foreignKey, fromDDL);
420                                }
421                            }
422                            
423                            List synonyms = (List) jsonSchema.get("synonyms");
424                                                        if (synonyms != null) {
425                                                                for (int k = 0; k < synonyms.size(); k++) {
426                                                                        Map jsonTable = (Map) synonyms.get(k);
427                                                                        String synonymsName = (String) jsonTable.get("name");
428                                                                        String synonymsSchemaName = (String) jsonTable.get("schema");
429
430                                                                        String synonymsSourceName = (String) jsonTable.get("sourceName");
431                                                                        String synonymsSourceSchemaName = (String) jsonTable.get("sourceSchema");
432
433                                                                        if (SQLUtil.isEmpty(synonymsSourceSchemaName)) {
434                                                                                synonymsSourceSchemaName = synonymsSchemaName;
435                                                                        }
436
437                                                                        String tableKey = getFullTableName(vendor, serverName, null,
438                                                                                        synonymsSourceSchemaName, synonymsSourceName);
439                                                                        table sourceTable = tableMap.get(tableKey);
440                                                                        if (sourceTable != null) {
441                                        String fromDDL = sourceTable.getFromDDL();
442                                                                                List columns = (List) sourceTable.getColumns();
443                                                                                dbObjs.add(jsonTable);
444                                                                                for (int l = 0; l < columns.size(); l++) {
445                                                                                        column jsonColumn = (column) columns.get(l);
446                                                                                        String columnName = (String) jsonColumn.getName();
447                                                                                        String dataType = jsonColumn.getDataType();
448                                                                                        appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow,
449                                                                                                        serverName, null, schemaName, synonymsName, false, true,
450                                                                                                        columnName, dataType, false, false, false, false, fromDDL);
451                                                                                }
452                                                                                
453                                                                                String synonymsTableKey = getFullTableName(vendor, serverName,
454                                                                                                null, synonymsSchemaName, synonymsName);
455                                                                                table synonymsTable = tableMap.get(synonymsTableKey);
456                                                                                if (synonymsTable != null) {
457                                                                                        List synonymsColumns = (List) synonymsTable.getColumns();
458                                                                                        
459                                                                                        for (int l = 0; l < synonymsColumns.size(); l++) {
460                                                                                                relationship relationElement = new relationship();
461                                                                                                relationElement.setType(RelationshipType.fdd.name());
462                                                                                                relationElement.setEffectType(EffectType.synonym.name());
463                                                                                                        
464                                                                                                long id = ++ModelBindingManager.get().RELATION_ID;
465                                                                                                relationElement.setId(String.valueOf(id));
466                                                                                                
467                                                                                                column targetColumn = (column)synonymsColumns.get(l);
468                                                                                                targetColumn target = new targetColumn();
469                                                                                                target.setId(String.valueOf(targetColumn.getId()));
470                                                                                                target.setColumn(targetColumn.getName());
471                                                                                                target.setParent_id(String.valueOf(synonymsTable.getId()));
472                                                                                                target.setParent_name(synonymsTable.getName());
473                                                                                                relationElement.setTarget(target);
474                                
475                                                                                                column sourceColumn = (column)columns.get(l);
476                                                                                                sourceColumn source = new sourceColumn();
477                                                                                                source.setId(String.valueOf(sourceColumn.getId()));
478                                                                                                source.setColumn(sourceColumn.getName());
479                                                                                                source.setParent_id(String.valueOf(sourceTable.getId()));
480                                                                                                source.setParent_name(sourceTable.getName());
481                                                                                                relationElement.addSource(source);
482                                                                                                
483                                                                                                dataflow.getRelationships().add(relationElement);
484                                                                                        }
485                                                                                }
486                                                                        }
487                                                                }
488                                                        }
489                                                        
490                            List<Map> oraclePackages = (List<Map>) jsonSchema.get("packages");
491                            if (oraclePackages != null) {
492                                for (Map oraclePackageItem : oraclePackages) {
493                                    String oraclePackageName = (String) oraclePackageItem.get("name");
494                                    oraclePackage oraclePackage = appendOraclePackage(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, oraclePackageName);
495                                    List<Map> procedures = (List<Map>) oraclePackageItem.get("procedures");
496                                    if (procedures != null) {
497                                        for (Map procedure : procedures) {
498                                            appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, procedure, oraclePackage);
499                                        }
500                                    }
501                                    List<Map> functions = (List<Map>) oraclePackageItem.get("functions");
502                                    if (functions != null) {
503                                        for (Map function : functions) {
504                                            appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, function, oraclePackage);
505                                        }
506                                    }
507                                    List<Map> triggers = (List<Map>) oraclePackageItem.get("triggers");
508                                    if (triggers != null) {
509                                        for (Map trigger : triggers) {
510                                            appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, trigger, oraclePackage);
511                                        }
512                                    }
513                                }
514                            }
515                            List<Map> procedures = (List<Map>) jsonSchema.get("procedures");
516                            if (procedures != null) {
517                                for (Map procedure : procedures) {
518                                    appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, procedure, null);
519                                }
520                            }
521                            List<Map> functions = (List<Map>) jsonSchema.get("functions");
522                            if (functions != null) {
523                                for (Map function : functions) {
524                                    appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, function, null);
525                                }
526                            }
527                            List<Map> triggers = (List<Map>) jsonSchema.get("triggers");
528                            if (triggers != null) {
529                                for (Map trigger : triggers) {
530                                    appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, null, schemaName, trigger, null);
531                                }
532                            }
533                        }
534                    }
535                }
536            }
537        }
538        sortTableColumns(dataflow);
539        return dataflow;
540    }
541
542    private void init(EDbVendor vendor) {
543        this.vendor = vendor;
544        procedureMap.clear();
545        tableMap.clear();
546        columnMap.clear();
547        if (ModelBindingManager.get() == null) {
548            ModelBindingManager.set(new ModelBindingManager());
549        }
550    }
551
552    private void sortTableColumns(dataflow dataflow) {
553        if (dataflow.getTables() != null) {
554            for (table table : dataflow.getTables()) {
555                Collections.sort(table.getColumns(), new Comparator<column>() {
556                    public int compare(column t1, column t2) {
557                        if (t1.getName().equalsIgnoreCase("RelationRows"))
558                            return 1;
559                        if (t2.getName().equalsIgnoreCase("RelationRows"))
560                            return -1;
561                        return 0;
562                    }
563                });
564            }
565        }
566
567        if (dataflow.getResultsets() != null) {
568            for (table table : dataflow.getResultsets()) {
569                Collections.sort(table.getColumns(), new Comparator<column>() {
570                    public int compare(column t1, column t2) {
571                        if (t1.getName().equalsIgnoreCase("RelationRows"))
572                            return 1;
573                        if (t2.getName().equalsIgnoreCase("RelationRows"))
574                            return -1;
575                        return 0;
576                    }
577                });
578            }
579        }
580    }
581
582    private oraclePackage appendOraclePackage(EDbVendor vendor, boolean supportsCatalogs, boolean supportsSchemas, dataflow dataflow, String serverName, String databaseName, String schemaName, String oraclePackageName) {
583        String oraclePackageKey = getFullTableName(vendor, serverName, databaseName, schemaName, oraclePackageName);
584        if (!oraclePackageMap.containsKey(oraclePackageKey)) {
585            oraclePackage oraclePackage = new oraclePackage();
586            if (serverName != null) {
587                oraclePackage.setServer(serverName);
588            } else if (sqlenv != null && sqlenv.getDefaultServerName() != null
589                    && !TSQLEnv.DEFAULT_SERVER_NAME.equalsIgnoreCase(sqlenv.getDefaultServerName())) {
590                oraclePackage.setServer(sqlenv.getDefaultServerName());
591            }
592            if (supportsCatalogs && databaseName != null) {
593                oraclePackage.setDatabase(databaseName);
594            } else if (supportsCatalogs && sqlenv != null && sqlenv.getDefaultCatalogName() != null
595                    && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(sqlenv.getDefaultCatalogName())) {
596                oraclePackage.setDatabase(sqlenv.getDefaultCatalogName());
597            }
598
599            if (supportsSchemas && schemaName != null) {
600                oraclePackage.setSchema(schemaName);
601            } else if (supportsSchemas && sqlenv != null && sqlenv.getDefaultSchemaName() != null
602                    && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(sqlenv.getDefaultSchemaName())) {
603                oraclePackage.setSchema(sqlenv.getDefaultSchemaName());
604            }
605
606            oraclePackage.setName(oraclePackageName);
607            if (supportsSchemas && !SQLUtil.isEmpty(oraclePackage.getSchema())) {
608                oraclePackage.setName(oraclePackage.getSchema() + "." + oraclePackage.getName());
609            }
610            if (supportsCatalogs && !SQLUtil.isEmpty(oraclePackage.getDatabase())) {
611                oraclePackage.setName(oraclePackage.getDatabase() + "." + oraclePackage.getName());
612            }
613            oraclePackage.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
614            if (ModelBindingManager.getGlobalSqlInfo() != null) {
615                oraclePackage.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
616                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
617                        + new Pair3<Long, Long, Integer>(-1L, -1L,
618                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
619            }
620            dataflow.getPackages().add(oraclePackage);
621            oraclePackageMap.put(oraclePackageKey, oraclePackage);
622        }
623        return oraclePackageMap.get(oraclePackageKey);
624    }
625
626    private void appendProcedure(EDbVendor vendor, boolean supportsCatalogs, boolean supportsSchemas, dataflow dataflow, String serverName, String databaseName, String schemaName, Map procedureObj, oraclePackage oraclePackage) {
627        String groupName = (String) procedureObj.get("groupName");
628        if (DlineageUtil.isProcedureExcluded(groupName)) {
629            return;
630        }
631        String procedureName = (String) procedureObj.get("name");
632        String procedureKey = getFullTableName(vendor, serverName, databaseName, schemaName, procedureName);
633        if (!procedureMap.containsKey(procedureKey)) {
634            procedure procedure = new procedure();
635            if (serverName != null) {
636                procedure.setServer(serverName);
637            } else if (sqlenv != null && sqlenv.getDefaultServerName() != null
638                    && !TSQLEnv.DEFAULT_SERVER_NAME.equalsIgnoreCase(sqlenv.getDefaultServerName())) {
639                procedure.setServer(sqlenv.getDefaultServerName());
640            }
641            if (supportsCatalogs && databaseName != null) {
642                procedure.setDatabase(databaseName);
643            } else if (supportsCatalogs && sqlenv != null && sqlenv.getDefaultCatalogName() != null
644                    && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(sqlenv.getDefaultCatalogName())) {
645                procedure.setDatabase(sqlenv.getDefaultCatalogName());
646            }
647
648            if (supportsSchemas && schemaName != null) {
649                procedure.setSchema(schemaName);
650            } else if (supportsSchemas && sqlenv != null && sqlenv.getDefaultSchemaName() != null
651                    && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(sqlenv.getDefaultSchemaName())) {
652                procedure.setSchema(sqlenv.getDefaultSchemaName());
653            }
654
655            procedure.setName(procedureName);
656            if (supportsSchemas && !SQLUtil.isEmpty(procedure.getSchema())) {
657                procedure.setName(procedure.getSchema() + "." + procedure.getName());
658            }
659            if (supportsCatalogs && !SQLUtil.isEmpty(procedure.getDatabase())) {
660                procedure.setName(procedure.getDatabase() + "." + procedure.getName());
661            }
662            procedure.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
663            if (ModelBindingManager.getGlobalSqlInfo() != null) {
664                procedure.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
665                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
666                        + new Pair3<Long, Long, Integer>(-1L, -1L,
667                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
668            }
669            procedure.setType((String) procedureObj.get("type"));
670            if (oraclePackage != null) {
671                oraclePackage.getProcedures().add(procedure);
672            } else {
673                dataflow.getProcedures().add(procedure);
674            }
675            procedureMap.put(procedureKey, procedure);
676        }
677    }
678
679    private void appendTable(EDbVendor vendor, boolean supportsCatalogs, boolean supportsSchemas, dataflow dataflow, String serverName, String databaseName, String schemaName, String tableName,
680                             boolean isView, boolean isSynonym, String columnName, String dataType, Boolean primaryKey, Boolean unqiueKey,Boolean indexKey, Boolean foreignKey, String fromDDL) {
681        String tableKey = getFullTableName(vendor, serverName, databaseName, schemaName, tableName);
682        if (!tableMap.containsKey(tableKey)) {
683            table table = new table();
684            if (serverName != null) {
685                table.setServer(serverName);
686            } else if (sqlenv != null && sqlenv.getDefaultServerName() != null
687                    && !TSQLEnv.DEFAULT_SERVER_NAME.equalsIgnoreCase(sqlenv.getDefaultServerName())) {
688                table.setServer(sqlenv.getDefaultServerName());
689            }
690            if (supportsCatalogs && databaseName != null) {
691                table.setDatabase(databaseName);
692            } else if (supportsCatalogs && sqlenv != null && sqlenv.getDefaultCatalogName() != null
693                    && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(sqlenv.getDefaultCatalogName())) {
694                table.setDatabase(sqlenv.getDefaultCatalogName());
695            }
696
697            if (supportsSchemas && schemaName != null) {
698                table.setSchema(schemaName);
699            } else if (supportsSchemas && sqlenv != null && sqlenv.getDefaultSchemaName() != null
700                    && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(sqlenv.getDefaultSchemaName())) {
701                table.setSchema(sqlenv.getDefaultSchemaName());
702            }
703
704            table.setName(tableName);
705            if (supportsSchemas && !SQLUtil.isEmpty(table.getSchema())) {
706                table.setName(table.getSchema() + "." + table.getName());
707            }
708            if (supportsCatalogs && !SQLUtil.isEmpty(table.getDatabase())) {
709                table.setName(table.getDatabase() + "." + table.getName());
710            }
711            table.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
712            if (ModelBindingManager.getGlobalSqlInfo() != null) {
713                table.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
714                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
715                        + new Pair3<Long, Long, Integer>(-1L, -1L,
716                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
717            }
718
719            if(!SQLUtil.isEmpty(fromDDL)){
720                table.setFromDDL(fromDDL);
721            }
722
723            if (isView) {
724                table.setType("view");
725                dataflow.getViews().add(table);
726            } else {
727                table.setType("table");
728                dataflow.getTables().add(table);
729            }
730                        if (isSynonym) {
731                                table.setSubType(SubType.synonym.name());
732                        }
733
734            tableMap.put(tableKey, table);
735        }
736
737        table table = tableMap.get(tableKey);
738        String sourceColumnKey = getFullColumnName(vendor, serverName, databaseName, schemaName, tableName, columnName);
739        if (!columnMap.containsKey(sourceColumnKey)) {
740            column column = new column();
741            column.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
742            column.setName(columnName);
743            column.setDataType(dataType);
744            column.setPrimaryKey(primaryKey);
745            column.setForeignKey(foreignKey);
746            column.setIndexKey(indexKey);
747            column.setUnqiueKey(unqiueKey);
748            if ("RelationRows".equalsIgnoreCase(columnName)) {
749                column.setSource("system");
750            }
751            if (ModelBindingManager.getGlobalSqlInfo() != null) {
752                column.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
753                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
754                        + new Pair3<Long, Long, Integer>(-1L, -1L,
755                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
756            }
757            table.getColumns().add(column);
758            columnMap.put(sourceColumnKey, column);
759        }
760    }
761
762    private String getFullColumnName(EDbVendor vendor, String... segments) {
763        StringBuilder builder = new StringBuilder();
764        for (int i = 1; i < segments.length; i++) {
765                        if (segments[i] == null) {
766                                continue;
767                        }
768            builder.append(segments[i]);
769            if (i < segments.length - 1) {
770                builder.append(".");
771            }
772        }
773        
774                return segments[0] + "." + SQLUtil.getIdentifierNormalColumnName(vendor, builder.toString());
775    }
776    
777    private String getFullTableName(EDbVendor vendor, String... segments) {
778        StringBuilder builder = new StringBuilder();
779        for (int i = 1; i < segments.length; i++) {
780                        if (segments[i] == null) {
781                                continue;
782                        }
783            builder.append(segments[i]);
784            if (i < segments.length - 1) {
785                builder.append(".");
786            }
787        }
788        
789                return segments[0] + "." + SQLUtil.getIdentifierNormalTableName(vendor, builder.toString());
790    }
791
792    public static void main(String[] args) throws Exception {
793        dataflow dataflow = new SqlflowMetadataAnalyzer().analyzeMetadata(EDbVendor.dbvoracle, SQLUtil.getFileContent(new File("C:\\Users\\KK\\Downloads\\metadata (9).json")));
794        System.out.println(XML2Model.saveXML(dataflow));
795    }
796}