Skip to content

Commit 07aff6d

Browse files
authored
Merge pull request #31 from JohT/feature/artifact-reports
Add artifact reports
2 parents e8babfa + 4702dbb commit 07aff6d

File tree

86 files changed

+4756
-648
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+4756
-648
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Artifacts with dependencies to other artifacts
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(packageInArtifact:Package)
4+
MATCH (packageInArtifact)-[:CONTAINS]->(typeInPackage:Type)
5+
MATCH (typeInPackage)-[:DEPENDS_ON]->(dependencyType:Type)
6+
MATCH (dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
7+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage)
8+
WHERE artifact.fileName <> dependencyArtifact.fileName
9+
WITH replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
10+
,artifact.numberOfPackages AS packagesInArtifactCount
11+
,artifact.numberOfTypes AS typesInArtifactCount
12+
,collect(DISTINCT packageInArtifact.fqn) AS packages
13+
,count(DISTINCT packageInArtifact.fqn) AS packagesCount
14+
,round(100.0 / artifact.numberOfPackages
15+
* count(DISTINCT packageInArtifact.fqn)
16+
, 2) AS packageSpread
17+
,collect(DISTINCT typeInPackage.name) AS types
18+
,count(DISTINCT typeInPackage.fqn) AS typesCount
19+
,round(100.0 / artifact.numberOfTypes
20+
* count(DISTINCT typeInPackage.fqn)
21+
, 2) AS typesSpread
22+
,replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
23+
// additionally group by if the dependency is an interface or not
24+
,dependencyType:Interface AS dependencyTypeIsInterface
25+
,collect(DISTINCT dependencyPackage.fqn) AS dependencyPackages
26+
,count(DISTINCT dependencyPackage.fqn) AS dependencyPackagesCount
27+
,collect(DISTINCT dependencyType.name) AS dependencyTypes
28+
,count(DISTINCT dependencyType.fqn) AS dependencyTypesCount
29+
// Filter out empty dependency sets
30+
WHERE dependencyPackagesCount > 0
31+
AND packagesCount > 1
32+
RETURN artifactName
33+
,packagesInArtifactCount
34+
,packagesCount
35+
,packageSpread
36+
,typesInArtifactCount
37+
,typesCount
38+
,typesSpread
39+
,dependencyArtifactName
40+
,dependencyTypeIsInterface
41+
,dependencyPackagesCount
42+
,dependencyTypesCount
43+
,dependencyPackages[0..2] AS someDependencyPackages
44+
,dependencyTypes[0..4] AS someDependencyTypes
45+
,packages[0..2] AS someCallingPackages
46+
,types[0..4] AS someCallingTypes
47+
ORDER BY packagesCount DESC
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Incoming Artifact Dependencies
2+
3+
MATCH (a:Artifact:Archive)
4+
OPTIONAL MATCH (a)<-[r:DEPENDS_ON]-(ea:Artifact:Archive)
5+
WHERE a.fileName <> ea.fileName
6+
WITH a
7+
,COUNT(ea) AS incomingDependencies
8+
,SUM(r.weight) AS incomingDependenciesWeight
9+
SET a.incomingDependencies = incomingDependencies
10+
,a.incomingDependenciesWeight = incomingDependenciesWeight
11+
RETURN a.fileName
12+
,incomingDependencies
13+
,incomingDependenciesWeight
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Most used internal dependencies across artifacts
2+
3+
MATCH (type:Type)-[:DEPENDS_ON]->(dependencyType:Type)
4+
MATCH (artifact:Artifact)-[:CONTAINS]->(package:Package)-[:CONTAINS]->(type:Type)
5+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
6+
WHERE artifact.fileName <> dependencyArtifact.fileName
7+
WITH replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
8+
,COLLECT(DISTINCT dependencyPackage.fqn) AS dependencyPackageNames
9+
,COLLECT(DISTINCT dependencyType.name) AS dependencyTypeNames
10+
,COLLECT(DISTINCT replace(last(split(artifact.fileName, '/')), '.jar', '')) AS artifactNames
11+
,COUNT(DISTINCT package.fqn) AS numberOfPackages
12+
,COUNT(DISTINCT type.fqn) AS numberOfTypes
13+
,COUNT(DISTINCT dependencyType) AS numberOfDependencyTypes
14+
,REDUCE(interfaces=0, depType IN COLLECT(DISTINCT dependencyType) |
15+
CASE WHEN depType:Interface THEN interfaces + 1 ELSE interfaces END ) AS numberOfDependencyInterfaces
16+
ORDER BY numberOfPackages DESC
17+
RETURN dependencyArtifactName AS dependency
18+
,numberOfPackages AS usedByPackages
19+
,numberOfTypes AS usedByTypes
20+
,SIZE(dependencyPackageNames) AS providesPackages
21+
,SIZE(dependencyTypeNames) AS providesTypes
22+
,ROUND(100.0 / numberOfDependencyTypes * numberOfDependencyInterfaces, 2) AS interfaceRate
23+
,dependencyPackageNames[0..5] AS someProvidedPackages
24+
,dependencyTypeNames[0..5] AS someProvidedTypes
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Outgoing Artifact Dependencies
2+
3+
MATCH (a:Artifact:Archive)
4+
OPTIONAL MATCH (a)-[r:DEPENDS_ON]->(ea:Artifact:Archive)
5+
WHERE a.fileName <> ea.fileName
6+
WITH a
7+
,COUNT(ea) AS outgoingDependencies
8+
,SUM(r.weight) AS outgoingDependenciesWeight
9+
SET a.outgoingDependencies = outgoingDependencies
10+
,a.outgoingDependenciesWeight = outgoingDependenciesWeight
11+
RETURN a.fileName
12+
,outgoingDependencies
13+
,outgoingDependenciesWeight
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Set number of packages and types on artifacts
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(package:Package)
4+
MATCH (package)-[:CONTAINS]->(type:Type)
5+
WITH artifact
6+
,COUNT(DISTINCT package.fqn) AS numberOfPackages
7+
,COUNT(DISTINCT type.fqn) AS numberOfTypes
8+
SET artifact.numberOfPackages = numberOfPackages
9+
,artifact.numberOfTypes = numberOfTypes
10+
RETURN artifact.fileName
11+
,numberOfPackages
12+
,numberOfTypes
13+
ORDER BY artifact.fileName
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Usage and spread of internal artifact dependencies
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(packageInArtifact:Package)
4+
MATCH (packageInArtifact)-[:CONTAINS]->(typeInPackage:Type)
5+
MATCH (typeInPackage)-[:DEPENDS_ON]->(dependencyType:Type)
6+
MATCH (dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
7+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage)
8+
WHERE artifact.fileName <> dependencyArtifact.fileName
9+
WITH replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
10+
,artifact.numberOfPackages AS packagesInArtifactCount
11+
,artifact.numberOfTypes AS typesInArtifactCount
12+
,collect(DISTINCT packageInArtifact.fqn) AS packages
13+
,count(DISTINCT packageInArtifact.fqn) AS packagesCount
14+
,(100.0
15+
/ artifact.numberOfPackages
16+
* count(DISTINCT packageInArtifact.fqn)) AS packageSpread
17+
,collect(DISTINCT typeInPackage.name) AS types
18+
,count(DISTINCT typeInPackage.fqn) AS typesCount
19+
,(100.0
20+
/ artifact.numberOfTypes
21+
* count(DISTINCT typeInPackage.fqn)) AS typesSpread
22+
,replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
23+
// additionally group by if the dependency is an interface or not
24+
,dependencyType:Interface AS dependencyTypeIsInterface
25+
,collect(DISTINCT dependencyPackage.fqn) AS dependencyPackages
26+
,count(DISTINCT dependencyPackage.fqn) AS dependencyPackagesCount
27+
,collect(DISTINCT dependencyType.name) AS dependencyTypes
28+
,count(DISTINCT dependencyType.fqn) AS dependencyTypesCount
29+
// Filter out empty dependency sets
30+
WHERE dependencyPackagesCount > 0
31+
AND packagesCount > 1
32+
RETURN dependencyArtifactName
33+
,dependencyTypeIsInterface
34+
,COUNT(DISTINCT artifactName) AS usedInArtifacts
35+
,SUM(packagesCount) AS usedInPackages
36+
37+
,MIN(packageSpread) AS minPackageSpread
38+
,MAX(packageSpread) AS maxPackageSpread
39+
,AVG(packageSpread) AS avgPackageSpread
40+
,stDev(packageSpread) AS stdPackageSpread
41+
,percentileDisc(packageSpread, 0.5) AS per5PackageSpread
42+
43+
,MIN(packagesCount) AS minPackageCount
44+
,MAX(packagesCount) AS maxPackageCount
45+
,AVG(packagesCount) AS avgPackageCount
46+
,stDev(packagesCount) AS stdPackageCount
47+
,percentileDisc(packagesCount, 0.5) AS per5PackageCount
48+
49+
,MIN(typesSpread) AS minTypeSpread
50+
,MAX(typesSpread) AS maxTypeSpread
51+
,AVG(typesSpread) AS avgTypeSpread
52+
,stDev(typesSpread) AS stdTypeSpread
53+
,percentileDisc(typesSpread, 0.5) AS per5TypeSpread
54+
ORDER BY toLower(dependencyArtifactName) ASC
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Usage and spread of internal artifact dependents
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(packageInArtifact:Package)
4+
MATCH (packageInArtifact)-[:CONTAINS]->(typeInPackage:Type)
5+
MATCH (typeInPackage)-[:DEPENDS_ON]->(dependencyType:Type)
6+
MATCH (dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
7+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage)
8+
WHERE artifact.fileName <> dependencyArtifact.fileName
9+
WITH replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
10+
,artifact.numberOfPackages AS packagesInArtifactCount
11+
,artifact.numberOfTypes AS typesInArtifactCount
12+
,collect(DISTINCT packageInArtifact.fqn) AS packages
13+
,count(DISTINCT packageInArtifact.fqn) AS packagesCount
14+
,(100.0
15+
/ artifact.numberOfPackages
16+
* count(DISTINCT packageInArtifact.fqn)) AS packageSpread
17+
,collect(DISTINCT typeInPackage.name) AS types
18+
,count(DISTINCT typeInPackage.fqn) AS typesCount
19+
,(100.0
20+
/ artifact.numberOfTypes
21+
* count(DISTINCT typeInPackage.fqn)) AS typesSpread
22+
,replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
23+
// additionally group by if the dependency is an interface or not
24+
,dependencyType:Interface AS dependencyTypeIsInterface
25+
,collect(DISTINCT dependencyPackage.fqn) AS dependencyPackages
26+
,count(DISTINCT dependencyPackage.fqn) AS dependencyPackagesCount
27+
,collect(DISTINCT dependencyType.name) AS dependencyTypes
28+
,count(DISTINCT dependencyType.fqn) AS dependencyTypesCount
29+
// Filter out empty dependency sets
30+
WHERE dependencyPackagesCount > 0
31+
AND packagesCount > 1
32+
RETURN artifactName
33+
,dependencyTypeIsInterface
34+
,COUNT(DISTINCT dependencyArtifactName) AS artifactDependencies
35+
,SUM(dependencyPackagesCount) AS artifactDependencyPackages
36+
,100.0 / SUM(packagesInArtifactCount) * SUM(packagesCount) AS dependentPackagesRate
37+
38+
,MIN(packageSpread) AS minPackageSpread
39+
,MAX(packageSpread) AS maxPackageSpread
40+
,AVG(packageSpread) AS avgPackageSpread
41+
,stDev(packageSpread) AS stdPackageSpread
42+
,percentileDisc(packageSpread, 0.5) AS per5PackageSpread
43+
44+
,MIN(packagesCount) AS minPackageCount
45+
,MAX(packagesCount) AS maxPackageCount
46+
,AVG(packagesCount) AS avgPackageCount
47+
,stDev(packagesCount) AS stdPackageCount
48+
,percentileDisc(packagesCount, 0.5) AS per5PackageCount
49+
50+
,MIN(typesSpread) AS minTypeSpread
51+
,MAX(typesSpread) AS maxTypeSpread
52+
,AVG(typesSpread) AS avgTypeSpread
53+
,stDev(typesSpread) AS stdTypeSpread
54+
,percentileDisc(typesSpread, 0.5) AS per5TypeSpread
55+
ORDER BY toLower(artifactName) ASC

cypher/Candidates_for_Interface_Segregation.cypher

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
MATCH (type:Type)-[:DECLARES]->(method:Method)-[:INVOKES]->(dependentMethod:Method)
44
MATCH (dependentMethod)<-[:DECLARES]-(dependentType:Type)
5-
MATCH (dependentType)-[:IMPLEMENTS*]->(superType:Type)-[:DECLARES]->(inheritedMethod:Method)
5+
MATCH (dependentType)-[:IMPLEMENTS*1..9]->(superType:Type)-[:DECLARES]->(inheritedMethod:Method)
66
WHERE type.fqn <> dependentType.fqn
77
AND dependentMethod.name IS NOT NULL
88
AND inheritedMethod.name IS NOT NULL
@@ -15,6 +15,8 @@ WHERE type.fqn <> dependentType.fqn
1515
// Count the different signatures without the return type
1616
// of all declared methods including the inherited ones
1717
,count(DISTINCT split(method.signature, ' ')[1]) + count(DISTINCT split(inheritedMethod.signature, ' ')[1]) AS declaredMethods
18+
// Filter out types that declare only a few more methods than those that are actually used.
19+
// A good interface segregation candidate declares a lot of methods where only a few of them are used widely.
1820
WHERE declaredMethods > calledMethods + 2
1921
WITH fullDependentTypeName
2022
,declaredMethods
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//Community Detection 0 Delete Projection
22

3-
CALL gds.graph.drop('package-dependencies'
3+
CALL gds.graph.drop('package-dependencies', false)
44
YIELD graphName, nodeCount, relationshipCount, creationTime, modificationTime
55
RETURN graphName, nodeCount, relationshipCount, creationTime, modificationTime
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//Community Detection 0 Delete Projection
2+
3+
CALL gds.graph.drop('artifact-dependencies', false)
4+
YIELD graphName, nodeCount, relationshipCount, creationTime, modificationTime
5+
RETURN graphName, nodeCount, relationshipCount, creationTime, modificationTime

0 commit comments

Comments
 (0)