All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.jhipster.lite.module.domain.landscape.JHipsterLandscape Maven / Gradle / Ivy

There is a newer version: 1.22.0
Show newest version
package tech.jhipster.lite.module.domain.landscape;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import tech.jhipster.lite.module.domain.JHipsterFeatureSlug;
import tech.jhipster.lite.module.domain.JHipsterModuleSlug;
import tech.jhipster.lite.module.domain.JHipsterSlug;
import tech.jhipster.lite.module.domain.resource.JHipsterModulesResources;

public final class JHipsterLandscape {

  private final JHipsterLandscapeLevels levels;

  private JHipsterLandscape(JHipsterLandscapeLevels levels) {
    this.levels = levels;
  }

  public static JHipsterLandscape from(JHipsterModulesResources resources) {
    assertNoDuplicatedSlug(resources);

    return new JHipsterLandscape(JHipsterLandscapeLevels.builder().resources(resources).build()).withoutNestedDependencies().sorted();
  }

  private static void assertNoDuplicatedSlug(JHipsterModulesResources resources) {
    duplicatedSlug(resources).ifPresent(throwForDuplicatedSlug());
  }

  private static Optional duplicatedSlug(JHipsterModulesResources resources) {
    List featureSlugs = allFeatureSlugs(resources);

    return resources.stream().map(resource -> resource.slug().get()).filter(featureSlugs::contains).findFirst();
  }

  private static List allFeatureSlugs(JHipsterModulesResources resources) {
    return resources.stream().flatMap(resource -> resource.organization().feature().stream()).map(JHipsterFeatureSlug::get).toList();
  }

  private static Consumer throwForDuplicatedSlug() {
    return slug -> {
      throw InvalidLandscapeException.duplicatedSlug(slug);
    };
  }

  private JHipsterLandscape withoutNestedDependencies() {
    return new JHipsterLandscape(new JHipsterLandscapeLevels(nestedDependenciesFreeLevels()));
  }

  private List nestedDependenciesFreeLevels() {
    return levels.stream().map(toLevelsWithoutNestedDependencies()).toList();
  }

  private Function toLevelsWithoutNestedDependencies() {
    return level -> new JHipsterLandscapeLevel(level.elements().stream().map(this::toElementWithoutNestedDependencies).toList());
  }

  private JHipsterLandscapeElement toElementWithoutNestedDependencies(JHipsterLandscapeElement element) {
    return switch (element) {
      case JHipsterLandscapeModule module -> moduleWithoutNestedDependencies(module);
      case JHipsterLandscapeFeature feature -> feature;
    };
  }

  private JHipsterLandscapeModule moduleWithoutNestedDependencies(JHipsterLandscapeModule module) {
    List knownDependencies = knownDependencies(module);

    return JHipsterLandscapeModule.builder()
      .module(module.slug())
      .operation(module.operation())
      .propertiesDefinition(module.propertiesDefinition())
      .dependencies(dependenciesWithoutNested(module, knownDependencies));
  }

  private List knownDependencies(JHipsterLandscapeModule module) {
    return module.dependencies().map(toKnownDependencies()).orElse(List.of());
  }

  private Function> toKnownDependencies() {
    return dependencies -> dependencies.stream().flatMap(dependency -> allDependenciesOf(dependency.slug())).toList();
  }

  private List dependenciesWithoutNested(
    JHipsterLandscapeModule module,
    List knownDependencies
  ) {
    return module.dependencies().map(toDependenciesWithoutNested(knownDependencies)).orElse(null);
  }

  private Function> toDependenciesWithoutNested(
    List knownDependencies
  ) {
    return dependencies -> dependencies.stream().filter(dependency -> !knownDependencies.contains(dependency)).toList();
  }

  private Stream allDependenciesOf(JHipsterSlug slug) {
    return levels
      .stream()
      .flatMap(level -> level.elements().stream())
      .filter(element -> element.slug().equals(slug))
      .flatMap(element -> element.dependencies().map(JHipsterLandscapeDependencies::stream).orElse(Stream.of()));
  }

  public Collection sort(Collection modules) {
    return levels.stream().flatMap(toLevelModules(modules)).toList();
  }

  private Function> toLevelModules(Collection modules) {
    return level -> modules.stream().filter(inLevel(level)).sorted();
  }

  private Predicate inLevel(JHipsterLandscapeLevel level) {
    return module ->
      level
        .elements()
        .stream()
        .flatMap(JHipsterLandscapeElement::allModules)
        .map(JHipsterLandscapeElement::slug)
        .anyMatch(levelElement -> levelElement.equals(module));
  }

  private JHipsterLandscape sorted() {
    return new JHipsterLandscape(new JHipsterLandscapeLevels(levels.stream().map(toSortedLevel()).toList()));
  }

  private Function toSortedLevel() {
    Comparator levelComparator = Comparator.comparing(this::linksCount).thenComparing(element ->
      element.slug().get()
    );

    return level -> new JHipsterLandscapeLevel(level.elements().stream().sorted(levelComparator).toList());
  }

  private long linksCount(JHipsterLandscapeElement element) {
    return switch (element) {
      case JHipsterLandscapeFeature feature -> featureLinksCount(feature);
      case JHipsterLandscapeModule module -> moduleLinksCount(module);
    };
  }

  private long featureLinksCount(JHipsterLandscapeFeature feature) {
    return elementDependantModulesCount(feature) + dependantModulesCount(feature);
  }

  private long dependantModulesCount(JHipsterLandscapeFeature feature) {
    return feature.modules().stream().mapToLong(this::moduleLinksCount).sum();
  }

  private long moduleLinksCount(JHipsterLandscapeModule module) {
    return elementDependantModulesCount(module) + dependenciesCount(module);
  }

  private long elementDependantModulesCount(JHipsterLandscapeElement element) {
    return levels
      .stream()
      .flatMap(level -> level.elements().stream())
      .filter(JHipsterLandscapeModule.class::isInstance)
      .map(JHipsterLandscapeModule.class::cast)
      .flatMap(toDependencies())
      .filter(dependency -> dependency.slug().equals(element.slug()))
      .count();
  }

  private Function> toDependencies() {
    return landscapeModule -> landscapeModule.dependencies().map(JHipsterLandscapeDependencies::stream).orElse(Stream.of());
  }

  private long dependenciesCount(JHipsterLandscapeModule module) {
    return module.dependencies().map(JHipsterLandscapeDependencies::count).orElse(0L);
  }

  public JHipsterLandscapeLevels levels() {
    return levels;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy