diff --git a/src/main/java/org/owasp/dependencytrack/persistence/QueryManager.java b/src/main/java/org/owasp/dependencytrack/persistence/QueryManager.java index f29c03828f..0374442032 100644 --- a/src/main/java/org/owasp/dependencytrack/persistence/QueryManager.java +++ b/src/main/java/org/owasp/dependencytrack/persistence/QueryManager.java @@ -917,6 +917,45 @@ public void removeDependencyIfExist(Project project, Component component) { } } + /** + * Intelligently adds dependencies for components that are not already a dependency + * of the specified project and removes the dependency relationship for components + * that are not in the list of specified components. + * @param project the project to bind components to + * @param components the complete list of components that should be dependencies of the project + */ + public void reconcileDependencies(Project project, List components) { + // Holds a list of all Components that are existing dependencies of the specified project + final List existingProjectDependencies = new ArrayList<>(); + getAllDependencies(project).forEach(item -> existingProjectDependencies.add(item.getComponent())); + reconcileDependencies(project, existingProjectDependencies, components); + } + + /** + * Intelligently adds dependencies for components that are not already a dependency + * of the specified project and removes the dependency relationship for components + * that are not in the list of specified components. + * @param project the project to bind components to + * @param existingProjectDependencies the complete list of existing dependent components + * @param components the complete list of components that should be dependencies of the project + */ + public void reconcileDependencies(Project project, List existingProjectDependencies, List components) { + // Removes components as dependencies to the project for all + // components not included in the list provided + for (Component existingDependency: existingProjectDependencies) { + boolean keep = false; + for (Component component: components) { + if (component.getId() == existingDependency.getId()) { + keep = true; + } + } + if (!keep) { + removeDependencyIfExist(project, existingDependency); + } + } + components.forEach(component -> createDependencyIfNotExist(project, component, null, null)); + } + /** * Returns a List of all Dependency for the specified Project. * This method if designed NOT to provide paginated results. diff --git a/src/main/java/org/owasp/dependencytrack/tasks/BomUploadProcessingTask.java b/src/main/java/org/owasp/dependencytrack/tasks/BomUploadProcessingTask.java index 9628cfaf9d..10aea4926d 100644 --- a/src/main/java/org/owasp/dependencytrack/tasks/BomUploadProcessingTask.java +++ b/src/main/java/org/owasp/dependencytrack/tasks/BomUploadProcessingTask.java @@ -54,8 +54,14 @@ public void inform(Event e) { final byte[] bomBytes = event.getBom(); QueryManager qm = new QueryManager(); try { + final Project project = qm.getObjectByUuid(Project.class, event.getProjectUuid()); final List components; final List flattenedComponents = new ArrayList<>(); + + // Holds a list of all Components that are existing dependencies of the specified project + final List existingProjectDependencies = new ArrayList<>(); + qm.getAllDependencies(project).forEach(item -> existingProjectDependencies.add(item.getComponent())); + final String bomString = new String(bomBytes); if (bomString.startsWith("