PanelGroupControlSupport.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * SteelBlue: DCI User Interfaces
  5.  * http://tidalwave.it/projects/steelblue
  6.  *
  7.  * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/steelblue-src
  22.  * git clone https://github.com/tidalwave-it/steelblue-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.ui.core.spi;

  27. import jakarta.annotation.Nonnull;
  28. import java.util.ArrayList;
  29. import java.util.Collection;
  30. import java.util.HashMap;
  31. import java.util.List;
  32. import java.util.Map;
  33. import java.util.function.Function;
  34. import it.tidalwave.ui.core.PanelGroupControl;
  35. import it.tidalwave.ui.core.PanelGroupProvider;
  36. import org.apiguardian.api.API;
  37. import it.tidalwave.util.As;
  38. import it.tidalwave.util.ShortNames;
  39. import lombok.RequiredArgsConstructor;
  40. import lombok.experimental.Delegate;
  41. import lombok.extern.slf4j.Slf4j;
  42. import static org.apiguardian.api.API.Status.EXPERIMENTAL;
  43. import static java.util.stream.Collectors.*;

  44. /***************************************************************************************************************************************************************
  45.  *
  46.  * A support implementation of {@link PanelGroupControl}.
  47.  *
  48.  * @param   <T> the type of the top container
  49.  * @param   <S>
  50.  * @since       2.0-ALPHA-3
  51.  * @author      Fabrizio Giudici
  52.  *
  53.  **************************************************************************************************************************************************************/
  54. @API(status = EXPERIMENTAL)
  55. @RequiredArgsConstructor @Slf4j
  56. public abstract class PanelGroupControlSupport<T, S> implements As, PanelGroupControl<T>
  57.   {
  58.     @Delegate @Nonnull
  59.     private final As delegate = As.forObject(this);

  60.     @Nonnull
  61.     private final Function<As, Collection<? extends PanelGroupProvider<S>>> pgpProvider;

  62.     /***********************************************************************************************************************************************************
  63.      *
  64.      **********************************************************************************************************************************************************/
  65.     protected PanelGroupControlSupport()
  66.       {
  67.         this(PanelGroupControlSupport::defaultPanelGroupProviders);
  68.       }

  69.     /***********************************************************************************************************************************************************
  70.      * {@inheritDoc}
  71.      **********************************************************************************************************************************************************/
  72.     @Override
  73.     public void setup (@Nonnull final Configuration<T> configuration)
  74.       {
  75.         final var topContainersByGroup = configuration.getTopContainersByGroup();
  76.         final var providersByGroup = new HashMap<Group, List<PanelGroupProvider<S>>>();
  77.         pgpProvider.apply(this).forEach(p -> providersByGroup.computeIfAbsent(p.getGroup(), ignored -> new ArrayList<>()).add(p));
  78.         log.debug("Providers by placement:");
  79.         providersByGroup.forEach((placement, provider) -> log.debug(">>>> {}: {}", placement, ShortNames.shortIds(provider)));
  80.         final var unboundPlacements = providersByGroup.keySet().stream().filter(p -> !topContainersByGroup.containsKey(p)).collect(toList());

  81.         if (!unboundPlacements.isEmpty())
  82.           {
  83.             throw new RuntimeException("No top container(s) provider for " + unboundPlacements);
  84.           }

  85.         providersByGroup.forEach((group, providers) ->
  86.             assemble(group, providers, topContainersByGroup.get(group), configuration.getGroupOptions(), configuration.getOptions()));
  87.       }

  88.     /***********************************************************************************************************************************************************
  89.      * Assemble a set of panes for the given group.
  90.      * @param   group               the {@code Group}
  91.      * @param   panelProviders      the {@code PanelGroupProvider}s associated to the given {@code Group}
  92.      * @param   topContainer        the top container
  93.      * @param   groupOptions        options for each group
  94.      * @param   options             options for doing the job
  95.      **********************************************************************************************************************************************************/
  96.     protected abstract void assemble (@Nonnull final Group group,
  97.                                       @Nonnull final List<? extends PanelGroupProvider<S>> panelProviders,
  98.                                       @Nonnull final T topContainer,
  99.                                       @Nonnull final Map<Group, List<Options>> groupOptions,
  100.                                       @Nonnull final List<Options> options);

  101.     /***********************************************************************************************************************************************************
  102.      *
  103.      **********************************************************************************************************************************************************/
  104.     @Nonnull
  105.     private static <S> Collection<PanelGroupProvider<S>> defaultPanelGroupProviders (@Nonnull final As as)
  106.       {
  107.         return as.asMany(As.<PanelGroupProvider<S>>type(PanelGroupProvider.class));
  108.       }
  109.   }