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