示例#1
0
  /**
   * Process the 'digital' reaction in a way to obtain an ordered list of components, taking account
   * of their dependencies.
   *
   * @return Ordered list of comoponent's Ids.
   */
  public List<String> proceed() {
    // -----
    // 1.On vérifie si tous les composants définis par leurs ids existent
    final StringBuilder missing = new StringBuilder();
    for (final DIComponentInfo componentInfo : diComponentInfos) {
      for (final DIDependency dependency : componentInfo.getDependencies()) {
        // Si une référence est requise
        // et qu'elle est absente, c'est qu'elle est manquante !
        if (dependency.isRequired() && !allComponentInfos.contains(dependency.getName())) {
          missing
              .append(dependency)
              .append(" (referenced by " + componentInfo.getId() + ")")
              .append(", ");
        }
      }
    }
    if (missing.length() > 0) {
      throw new DIException(
          "Components not found :"
              + missing.toString()
              + "\n\tLoaded components : "
              + diComponentInfos);
    }
    // -----
    // 2.On résout les dépendances
    final List<DIComponentInfo> unsorted = new ArrayList<>(diComponentInfos);
    // Niveaux de dépendances des composants
    //		final List<List<String>> levels = new ArrayList<>();
    final List<String> sorted = new ArrayList<>();

    // . Par défaut on considére comme triés tous les parents
    // On va trier les nouveaux composants.
    while (!unsorted.isEmpty()) {
      final int countSorted = sorted.size();
      for (final Iterator<DIComponentInfo> iterator = unsorted.iterator(); iterator.hasNext(); ) {
        final DIComponentInfo componentInfo = iterator.next();
        final boolean solved =
            isSolved(componentInfo, parentComponentInfos, allComponentInfos, sorted);
        if (solved) {
          // Le composant est résolu
          // - On l'ajoute sa clé à la liste des clés de composants résolus
          // - On le supprime de la liste des composants à résoudre
          sorted.add(componentInfo.getId());
          iterator.remove();
        }
      }
      // Si lors d'une itération on ne fait rien c'est qu'il y a une dépendance cyclique
      if (countSorted == sorted.size()) {
        // On a une dépendance cyclique !
        throw new DIException("Liste des composants non résolus :" + unsorted);
      }
    }
    // -----
    // 3 On expose un liste de ids et non les composantInfos
    return Collections.unmodifiableList(sorted);
  }
示例#2
0
  private static boolean isSolved(
      final DIDependency dependency,
      final Set<String> parentComponentInfos,
      final Set<String> allComponentInfos,
      final List<String> sorted) {
    // Une dépendace est résolue si tous les ids concernés sont résolus.
    // Si la dépendance est déjà résolue et bien c'est bon on pass à la dépendances suivante

    if (dependency.isRequired()) {
      return parentComponentInfos.contains(dependency.getName())
          || sorted.contains(dependency.getName());
    } else if (dependency.isOption()) {
      // Si l'objet fait partie de la liste alors il doit être résolu.
      if (allComponentInfos.contains(dependency.getName())) {
        return sorted.contains(dependency.getName());
      }
      // Sinon comme il est optionnel c'est ok.
      return true;
    } else if (dependency.isList()) {
      // Si l'objet fait partie de la liste alors il doit être résolu.
      for (final String id : allComponentInfos) {
        final boolean match =
            id.equals(dependency.getName()) || id.startsWith(dependency.getName() + '#');
        if (match && !sorted.contains(id)) {
          // L'objet id fait partie de la liste
          return sorted.contains(id);
        }
      }
      return true;
    }
    throw new IllegalStateException();
  }