@@ -83,6 +83,9 @@ public void execute(Java2GraphConfig config, GraphContext context) throws Except
8383 exportMethodDefinitionsCsv (config .getOutCsvDir (), context );
8484 exportFieldsCsv (config .getOutCsvDir (), context );
8585 exportDependsOnCsv (config .getOutCsvDir (), context );
86+ exportParametersCsv (config .getOutCsvDir (), context );
87+ exportVariablesCsv (config .getOutCsvDir (), context );
88+ exportDataFlowCsv (config .getOutCsvDir (), context );
8689 }
8790
8891 if (resolvedDbPath != null ) {
@@ -195,6 +198,39 @@ private void exportDependsOnCsv(Path dir, GraphContext context) throws IOExcepti
195198 }
196199 }
197200
201+ private void exportParametersCsv (Path dir , GraphContext context ) throws IOException {
202+ try (FileWriter out = new FileWriter (dir .resolve ("parameters.csv" ).toFile ());
203+ CSVPrinter printer = new CSVPrinter (out , CSVFormat .Builder .create ().setHeader ("id" , "methodFqn" , "name" , "typeFqn" , "index" ).build ())) {
204+ for (ParameterNode node : context .parameters .values ()) {
205+ if (node .getId () != null && !node .getId ().isBlank ()) {
206+ printer .printRecord (node .getId (), node .getMethodFqn (), node .getName (), node .getTypeFqn (), node .getIndex ());
207+ }
208+ }
209+ }
210+ }
211+
212+ private void exportVariablesCsv (Path dir , GraphContext context ) throws IOException {
213+ try (FileWriter out = new FileWriter (dir .resolve ("variables.csv" ).toFile ());
214+ CSVPrinter printer = new CSVPrinter (out , CSVFormat .Builder .create ().setHeader ("id" , "methodFqn" , "name" , "typeFqn" ).build ())) {
215+ for (VariableNode node : context .variables .values ()) {
216+ if (node .getId () != null && !node .getId ().isBlank ()) {
217+ printer .printRecord (node .getId (), node .getMethodFqn (), node .getName (), node .getTypeFqn ());
218+ }
219+ }
220+ }
221+ }
222+
223+ private void exportDataFlowCsv (Path dir , GraphContext context ) throws IOException {
224+ try (FileWriter out = new FileWriter (dir .resolve ("data_flow.csv" ).toFile ());
225+ CSVPrinter printer = new CSVPrinter (out , CSVFormat .Builder .create ().setHeader ("sourceId" , "targetId" , "flowType" ).build ())) {
226+ for (DataFlowEdge edge : context .dataFlowEdges ) {
227+ if (edge .getSourceId () != null && edge .getTargetId () != null ) {
228+ printer .printRecord (edge .getSourceId (), edge .getTargetId (), edge .getFlowType ());
229+ }
230+ }
231+ }
232+ }
233+
198234 private void exportLadybug (Java2GraphConfig config , GraphContext context ) {
199235 Set <String > affectedPaths = new HashSet <>();
200236 if (isIncremental ) {
@@ -263,6 +299,9 @@ private void exportLadybug(Java2GraphConfig config, GraphContext context) {
263299 executeOrThrow (conn , "CREATE NODE TABLE Field(id STRING, fqn STRING, name STRING, typeFqn STRING, containingClassFqn STRING, annotations STRING, filePath STRING, PRIMARY KEY (id))" );
264300 executeOrThrow (conn , "CREATE REL TABLE DependsOn(FROM Class TO Class, injectionType STRING)" );
265301 executeOrThrow (conn , "CREATE REL TABLE HasField(FROM Class TO Field)" );
302+ executeOrThrow (conn , "CREATE NODE TABLE Parameter(id STRING, methodFqn STRING, name STRING, typeFqn STRING, index INT64, PRIMARY KEY (id))" );
303+ executeOrThrow (conn , "CREATE NODE TABLE Variable(id STRING, methodFqn STRING, name STRING, typeFqn STRING, PRIMARY KEY (id))" );
304+ executeOrThrow (conn , "CREATE REL TABLE DataFlow(FROM Variable TO Parameter, FROM Parameter TO Parameter, FROM Field TO Parameter, FROM Variable TO Field, FROM Parameter TO Field, FROM Field TO Field, flowType STRING)" );
266305
267306 Path tempDir = Files .createTempDirectory ("ladybug_import" );
268307
@@ -381,6 +420,60 @@ private void exportLadybug(Java2GraphConfig config, GraphContext context) {
381420 }
382421 }
383422 }
423+
424+ Set <String > paramIds = new HashSet <>();
425+ Set <String > varIds = new HashSet <>();
426+
427+ Path paramsCsv = tempDir .resolve ("parameters.csv" );
428+ try (FileWriter out = new FileWriter (paramsCsv .toFile ());
429+ CSVPrinter printer = new CSVPrinter (out , CSVFormat .DEFAULT )) {
430+ for (ParameterNode node : context .parameters .values ()) {
431+ if (node .getId () != null && !node .getId ().isBlank ()) {
432+ printer .printRecord (node .getId (), node .getMethodFqn (), node .getName (), node .getTypeFqn (), node .getIndex ());
433+ paramIds .add (node .getId ());
434+ }
435+ }
436+ }
437+
438+ Path varsCsv = tempDir .resolve ("variables.csv" );
439+ try (FileWriter out = new FileWriter (varsCsv .toFile ());
440+ CSVPrinter printer = new CSVPrinter (out , CSVFormat .DEFAULT )) {
441+ for (VariableNode node : context .variables .values ()) {
442+ if (node .getId () != null && !node .getId ().isBlank ()) {
443+ printer .printRecord (node .getId (), node .getMethodFqn (), node .getName (), node .getTypeFqn ());
444+ varIds .add (node .getId ());
445+ }
446+ }
447+ }
448+
449+ Path dfVP = tempDir .resolve ("df_vp.csv" );
450+ Path dfPP = tempDir .resolve ("df_pp.csv" );
451+ Path dfFP = tempDir .resolve ("df_fp.csv" );
452+ Path dfVF = tempDir .resolve ("df_vf.csv" );
453+ Path dfPF = tempDir .resolve ("df_pf.csv" );
454+ Path dfFF = tempDir .resolve ("df_ff.csv" );
455+
456+ try (
457+ FileWriter fwVP = new FileWriter (dfVP .toFile ()); CSVPrinter pVP = new CSVPrinter (fwVP , CSVFormat .DEFAULT );
458+ FileWriter fwPP = new FileWriter (dfPP .toFile ()); CSVPrinter pPP = new CSVPrinter (fwPP , CSVFormat .DEFAULT );
459+ FileWriter fwFP = new FileWriter (dfFP .toFile ()); CSVPrinter pFP = new CSVPrinter (fwFP , CSVFormat .DEFAULT );
460+ FileWriter fwVF = new FileWriter (dfVF .toFile ()); CSVPrinter pVF = new CSVPrinter (fwVF , CSVFormat .DEFAULT );
461+ FileWriter fwPF = new FileWriter (dfPF .toFile ()); CSVPrinter pPF = new CSVPrinter (fwPF , CSVFormat .DEFAULT );
462+ FileWriter fwFF = new FileWriter (dfFF .toFile ()); CSVPrinter pFF = new CSVPrinter (fwFF , CSVFormat .DEFAULT )
463+ ) {
464+ for (DataFlowEdge edge : context .dataFlowEdges ) {
465+ String src = edge .getSourceId ();
466+ String tgt = edge .getTargetId ();
467+ if (src != null && tgt != null ) {
468+ if (varIds .contains (src ) && paramIds .contains (tgt )) pVP .printRecord (src , tgt , edge .getFlowType ());
469+ else if (paramIds .contains (src ) && paramIds .contains (tgt )) pPP .printRecord (src , tgt , edge .getFlowType ());
470+ else if (fieldIds .contains (src ) && paramIds .contains (tgt )) pFP .printRecord (src , tgt , edge .getFlowType ());
471+ else if (varIds .contains (src ) && fieldIds .contains (tgt )) pVF .printRecord (src , tgt , edge .getFlowType ());
472+ else if (paramIds .contains (src ) && fieldIds .contains (tgt )) pPF .printRecord (src , tgt , edge .getFlowType ());
473+ else if (fieldIds .contains (src ) && fieldIds .contains (tgt )) pFF .printRecord (src , tgt , edge .getFlowType ());
474+ }
475+ }
476+ }
384477
385478 logger .info ("Executing bulk COPY commands..." );
386479 executeOrThrow (conn ,
@@ -397,6 +490,14 @@ private void exportLadybug(Java2GraphConfig config, GraphContext context) {
397490 executeOrThrow (conn , "COPY Field FROM '" + fieldsCsv .toAbsolutePath ().toString () + "' (PARALLEL=FALSE)" );
398491 executeOrThrow (conn , "COPY DependsOn FROM '" + dependsOnCsv .toAbsolutePath ().toString () + "' (PARALLEL=FALSE)" );
399492 executeOrThrow (conn , "COPY HasField FROM '" + hasFieldCsv .toAbsolutePath ().toString () + "' (PARALLEL=FALSE)" );
493+ executeOrThrow (conn , "COPY Parameter FROM '" + paramsCsv .toAbsolutePath ().toString () + "' (PARALLEL=FALSE)" );
494+ executeOrThrow (conn , "COPY Variable FROM '" + varsCsv .toAbsolutePath ().toString () + "' (PARALLEL=FALSE)" );
495+ executeOrThrow (conn , "COPY DataFlow FROM '" + dfVP .toAbsolutePath ().toString () + "' (FROM='Variable', TO='Parameter', PARALLEL=FALSE)" );
496+ executeOrThrow (conn , "COPY DataFlow FROM '" + dfPP .toAbsolutePath ().toString () + "' (FROM='Parameter', TO='Parameter', PARALLEL=FALSE)" );
497+ executeOrThrow (conn , "COPY DataFlow FROM '" + dfFP .toAbsolutePath ().toString () + "' (FROM='Field', TO='Parameter', PARALLEL=FALSE)" );
498+ executeOrThrow (conn , "COPY DataFlow FROM '" + dfVF .toAbsolutePath ().toString () + "' (FROM='Variable', TO='Field', PARALLEL=FALSE)" );
499+ executeOrThrow (conn , "COPY DataFlow FROM '" + dfPF .toAbsolutePath ().toString () + "' (FROM='Parameter', TO='Field', PARALLEL=FALSE)" );
500+ executeOrThrow (conn , "COPY DataFlow FROM '" + dfFF .toAbsolutePath ().toString () + "' (FROM='Field', TO='Field', PARALLEL=FALSE)" );
400501 } else {
401502 logger .info ("Performing high-performance incremental updates (Purge-then-Create)..." );
402503
0 commit comments