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

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

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import tech.jhipster.lite.module.domain.JHipsterFeatureSlug;
import tech.jhipster.lite.module.domain.JHipsterSlug;
import tech.jhipster.lite.module.domain.resource.JHipsterModuleResource;
import tech.jhipster.lite.module.domain.resource.JHipsterModulesResources;
import tech.jhipster.lite.shared.error.domain.Assert;

public record JHipsterLandscapeLevels(Collection levels) {
  public JHipsterLandscapeLevels(Collection levels) {
    Assert.notEmpty("levels", levels);

    this.levels = Collections.unmodifiableCollection(levels);
  }

  static JHipsterLandscapeLevelsBuilder builder() {
    return new JHipsterLandscapeLevelsBuilder();
  }

  public Collection get() {
    return levels();
  }

  public Stream stream() {
    return levels().stream();
  }

  static class JHipsterLandscapeLevelsBuilder {

    private final Map> features = new ConcurrentHashMap<>();
    private final Collection modules = new ArrayList<>();

    JHipsterLandscapeLevelsBuilder resources(JHipsterModulesResources resources) {
      Assert.notNull("resources", resources);

      resources.stream().forEach(this::append);

      return this;
    }

    private JHipsterLandscapeLevelsBuilder append(JHipsterModuleResource resource) {
      Assert.notNull("resource", resource);

      resource.organization().feature().ifPresentOrElse(addFeature(resource), addModule(resource));

      return this;
    }

    private Consumer addFeature(JHipsterModuleResource resource) {
      return feature -> features.computeIfAbsent(feature, newArrayList()).add(landscapeModule(resource));
    }

    private Function> newArrayList() {
      return key -> new ArrayList<>();
    }

    private Runnable addModule(JHipsterModuleResource resource) {
      return () -> modules.add(landscapeModule(resource));
    }

    private static JHipsterLandscapeModule landscapeModule(JHipsterModuleResource resource) {
      return JHipsterLandscapeModule.builder()
        .module(resource.slug())
        .operation(resource.apiDoc().operation())
        .propertiesDefinition(resource.propertiesDefinition())
        .dependencies(resource.organization().dependencies());
    }

    public JHipsterLandscapeLevels build() {
      List elements = Stream.concat(features.entrySet().stream().map(toFeature()), modules.stream()).toList();
      JHipsterLandscapeLevelsDispatcher dispatcher = new JHipsterLandscapeLevelsDispatcher(elements);

      dispatcher.buildRoot();

      while (dispatcher.hasRemainingElements()) {
        dispatcher.dispatchNextLevel();
      }

      return new JHipsterLandscapeLevels(dispatcher.levels());
    }

    private Function>, JHipsterLandscapeFeature> toFeature() {
      return entry -> new JHipsterLandscapeFeature(entry.getKey(), entry.getValue());
    }
  }

  private static class JHipsterLandscapeLevelsDispatcher {

    private final List levels = new ArrayList<>();
    private List elementsToDispatch;

    public JHipsterLandscapeLevelsDispatcher(List elements) {
      elementsToDispatch = elements;
    }

    public void buildRoot() {
      List rootElements = levelElements(withoutDependencies());

      if (rootElements.isEmpty()) {
        throw InvalidLandscapeException.missingRootElement();
      }

      appendLevel(rootElements);
    }

    private Predicate withoutDependencies() {
      return element -> element.dependencies().isEmpty();
    }

    public boolean hasRemainingElements() {
      return !elementsToDispatch.isEmpty();
    }

    public void dispatchNextLevel() {
      Set knownSlugs = knownSlugs();
      List levelElements = levelElements(withAllKnownDependencies(knownSlugs));

      if (levelElements.isEmpty()) {
        throw InvalidLandscapeException.unknownDependency(
          knownSlugs,
          elementsToDispatch.stream().map(JHipsterLandscapeElement::slug).toList()
        );
      }

      appendLevel(levelElements);
    }

    private List levelElements(Predicate condition) {
      return elementsToDispatch.stream().filter(condition).toList();
    }

    private Predicate withAllKnownDependencies(Set knownSlugs) {
      return element ->
        knownSlugs.containsAll(
          element.dependencies().stream().flatMap(JHipsterLandscapeDependencies::stream).map(JHipsterLandscapeDependency::slug).toList()
        );
    }

    private Set knownSlugs() {
      return levels.stream().flatMap(JHipsterLandscapeLevel::slugs).collect(Collectors.toSet());
    }

    private void appendLevel(List elements) {
      updateElementsToDispatch(elements);

      levels.add(new JHipsterLandscapeLevel(elements));
    }

    private void updateElementsToDispatch(List elements) {
      elementsToDispatch = elementsToDispatch.stream().filter(element -> !elements.contains(element)).toList();
    }

    public Collection levels() {
      return levels;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy