Skip to content

Commit e98feeb

Browse files
Master branch: Added logic to check for, and eliminate, duplicate dependency relationships. #134
1 parent 0873702 commit e98feeb

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

src/main/java/org/owasp/dependencytrack/persistence/QueryManager.java

+43-2
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,31 @@ public PaginatedResult getCwes() {
891891
* @return a Dependency object
892892
*/
893893
public Dependency createDependencyIfNotExist(Project project, Component component, String addedBy, String notes) {
894+
List<Dependency> dependencies = getDependencies(project, component);
895+
896+
// Holder for possible duplicate dependencies
897+
List<Dependency> duplicates = new ArrayList<>();
898+
899+
// Holder for an existing Dependency (if present)
900+
Dependency existingDependency = null;
901+
902+
if (dependencies.size() > 0) {
903+
// Ensure that only one dependency object exists
904+
if (dependencies.size() > 1) {
905+
// Iterate through the duplicates and add them to the list of dependencies to be deleted
906+
for (int i = 1; i < dependencies.size(); i++) {
907+
duplicates.add(dependencies.get(i));
908+
}
909+
}
910+
// Return the first dependency found - all others will be deleted
911+
existingDependency = dependencies.get(0);
912+
}
913+
delete(duplicates);
914+
915+
if (existingDependency != null) {
916+
return existingDependency;
917+
}
918+
894919
Dependency dependency = getDependency(project, component);
895920
if (dependency != null) {
896921
return dependency;
@@ -1067,10 +1092,26 @@ public long getDependencyCount(Component component) {
10671092
*/
10681093
@SuppressWarnings("unchecked")
10691094
public Dependency getDependency(Project project, Component component) {
1095+
final List<Dependency> result = getDependencies(project, component);
1096+
return result.size() == 0 ? null : result.get(0);
1097+
}
1098+
1099+
/**
1100+
* Returns a List of Dependencies for the specified Project and Component.
1101+
*
1102+
* There should NEVER be duplicate dependencies. But this method is intended
1103+
* to check for them and return the list. This is a private method and should
1104+
* never be accessed outside the QueryManager.
1105+
*
1106+
* @param project the Project the component is part of
1107+
* @param component the Component
1108+
* @return a List of Dependency objects, or null if not found
1109+
*/
1110+
@SuppressWarnings("unchecked")
1111+
private List<Dependency> getDependencies(Project project, Component component) {
10701112
final Query query = pm.newQuery(Dependency.class, "project == :project && component == :component");
10711113
query.getFetchPlan().addGroup(Dependency.FetchGroup.ALL.name());
1072-
final List<Dependency> result = (List<Dependency>) query.execute(project, component);
1073-
return result.size() == 0 ? null : result.get(0);
1114+
return (List<Dependency>) query.execute(project, component);
10741115
}
10751116

10761117
/**

0 commit comments

Comments
 (0)