static void mergeArtifacts()

in src/main/java/org/apache/sling/feature/builder/BuilderUtil.java [122:200]


    static void mergeArtifacts(final Artifacts target,
        final Artifacts source,
        final Feature sourceFeature,
        final List<ArtifactId> artifactOverrides,
        final String originKey) {

        for (final Artifact artifactFromSource : source) {

            // set of artifacts in target, matching the artifact from source
            // the artifacts are kept in the order of the target - hence the linked hash set.
            final Set<Artifact> allExistingInTarget = new LinkedHashSet<>();
            for (final ArtifactId id : artifactFromSource.getAliases(true)) {
                for (Artifact targetArtifact : target) {
                    // Find aliased bundles in target
                    if (id.isSame(targetArtifact.getId())) {
                        allExistingInTarget.add(targetArtifact);
                    }
                }

                findAliasedArtifacts(id, target, allExistingInTarget);
            }

            final List<Artifact> selectedArtifacts = new ArrayList<>();
            if (allExistingInTarget.isEmpty()) {
                selectedArtifacts.add(artifactFromSource);
            }

            int insertPos = target.size();
            int count = 0;
            for (final Artifact existing : allExistingInTarget) {
                if (sourceFeature.getId().toMvnId().equals(existing.getMetadata().get(originKey))) {
                    // If the source artifact came from the same feature, keep them side-by-side
                    // but make sure we add the target ones first - hence, the count
                    selectedArtifacts.add(count++, existing);
                    selectedArtifacts.add(artifactFromSource);
                } else {
                    List<Artifact> artifacts = selectArtifactOverride(sourceFeature, existing, artifactFromSource, artifactOverrides, sourceFeature.getId());
                    // if we have an all policy we might have more then one artifact - we put the target one first
                    if (artifacts.size() > 1) {
                        selectedArtifacts.add(count++, artifacts.remove(0));
                    }
                    selectedArtifacts.addAll(artifacts);
                    Artifact same = null;
                    while ((same = target.getSame(existing.getId())) != null) {
                        // Keep executing removeSame() which ignores the version until last one was
                        // removed
                        final int p = target.indexOf(same);
                        if (p < insertPos) {
                            insertPos = p;
                        }
                        target.remove(p);
                    }
                }
            }

            for (final Artifact sa : new LinkedHashSet<>(selectedArtifacts)) {
                // create a copy to detach artifact from source
                final Artifact cp = addFeatureOrigin(sa.copy(sa.getId()), sourceFeature, sa);
                cp.getMetadata().put(BuilderUtil.class.getName() + "added", "true");
                // Record the original feature of the bundle, if needed
                if (originKey != null) {
                    if (sourceFeature != null && source.contains(sa) && sa.getMetadata().get(originKey) == null) {
                        cp.getMetadata().put(originKey, sourceFeature.getId().toMvnId());
                    }
                }
                if (insertPos == target.size()) {
                    target.add(cp);
                    insertPos = target.size();
                } else {
                    target.add(insertPos, cp);
                    insertPos++;
                }
            }
        }

        for (Artifact artifact : target) {
            artifact.getMetadata().remove(BuilderUtil.class.getName() + "added");
        }
    }