RoleCollector.java
- /*
- * *************************************************************************************************************************************************************
- *
- * SteelBlue: DCI User Interfaces
- * http://tidalwave.it/projects/steelblue
- *
- * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
- *
- * *************************************************************************************************************************************************************
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- *
- * *************************************************************************************************************************************************************
- *
- * git clone https://bitbucket.org/tidalwave/steelblue-src
- * git clone https://github.com/tidalwave-it/steelblue-src
- *
- * *************************************************************************************************************************************************************
- */
- package it.tidalwave.ui.javafx.impl.common;
- import jakarta.annotation.Nonnull;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import java.util.concurrent.CopyOnWriteArrayList;
- import javafx.application.Platform;
- import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
- import it.tidalwave.ui.core.role.UserAction;
- import it.tidalwave.util.As;
- import lombok.Getter;
- import lombok.extern.slf4j.Slf4j;
- import static it.tidalwave.ui.core.role.UserActionProvider._UserActionProvider_;
- import static java.util.stream.Collectors.*;
- import static it.tidalwave.util.ShortNames.*;
- /***************************************************************************************************************************************************************
- *
- * This class collects a bag of roles from a source. It is used to preload roles in a generic thread before using them in a JavaFX thread.
- *
- * @author Fabrizio Giudici
- *
- **************************************************************************************************************************************************************/
- @Slf4j
- public class RoleCollector
- {
- private final Map<Class<?>, List<Object>> roleMapByTipe = new HashMap<>();
- /** The default user action, which is the first action of the first {@link it.tidalwave.ui.core.role.UserActionProvider}. */
- @Getter @Nonnull
- private final Optional<UserAction> defaultUserAction;
- /***********************************************************************************************************************************************************
- *
- **********************************************************************************************************************************************************/
- public RoleCollector()
- {
- defaultUserAction = Optional.empty();
- }
- /***********************************************************************************************************************************************************
- * Creates a new instances for the given source and role types.
- * @param source the source
- * @param roleTypes the types of roles to collect
- **********************************************************************************************************************************************************/
- @SuppressFBWarnings("CT_CONSTRUCTOR_THROW")
- public RoleCollector (@Nonnull final As source, @Nonnull final Iterable<Class<?>> roleTypes)
- {
- if (Platform.isFxApplicationThread())
- {
- throw new IllegalStateException("RoleCollector must not be instantiated in the JavaFX thread");
- }
- if (log.isTraceEnabled())
- {
- log.trace("ctor({}, {})", source, shortNames(roleTypes));
- }
- roleTypes.forEach(roleType -> copyRoles(source, roleType));
- // TODO: perhaps it could be associated to a dummy key, instead of being returned by a getter?
- defaultUserAction = getMany(_UserActionProvider_).stream().flatMap(a -> a.getOptionalDefaultAction().stream()).findFirst();
- }
- /***********************************************************************************************************************************************************
- * Adds a role. This method is useful for tests.
- * @param roleType the type of the role
- * @param role the role
- **********************************************************************************************************************************************************/
- public <R> void put (@Nonnull final Class<R> roleType, @Nonnull final R role)
- {
- putMany(roleType, List.of(role));
- }
- /***********************************************************************************************************************************************************
- * Adds roles. This method is useful for tests.
- * @param roleType the type of the role
- * @param roles the roles
- **********************************************************************************************************************************************************/
- private <R> void putMany (@Nonnull final Class<R> roleType, @Nonnull final Collection<? extends R> roles)
- {
- roleMapByTipe.put(roleType, new ArrayList<>(roles));
- }
- /***********************************************************************************************************************************************************
- * {@return a role of thw given type, if present}. If multiple roles for the same type are present, the first is returned.
- * @param roleType the type of the role
- **********************************************************************************************************************************************************/
- @Nonnull
- public <R> Optional<R> get (@Nonnull final Class<R> roleType)
- {
- return getMany(roleType).stream().findFirst();
- }
- /***********************************************************************************************************************************************************
- * {@return multiple roles of thw given type}.
- * @param roleType the type of the role
- **********************************************************************************************************************************************************/
- @Nonnull @SuppressWarnings("unchecked")
- public <R> List<R> getMany (@Nonnull final Class<R> roleType)
- {
- return new CopyOnWriteArrayList<>((Collection<? extends R>)roleMapByTipe.getOrDefault(roleType, List.of()));
- }
- /***********************************************************************************************************************************************************
- * {@inheritDoc}
- **********************************************************************************************************************************************************/
- @Nonnull
- public String toString()
- {
- return roleMapByTipe.entrySet().stream().map(this::toString).collect(joining(", ", "RoleCollector(", ")"));
- }
- /***********************************************************************************************************************************************************
- *
- **********************************************************************************************************************************************************/
- @Nonnull
- private String toString (@Nonnull final Map.Entry<Class<?>, List<Object>> entry)
- {
- return shortName(entry.getKey()) + ": " + shortIds(entry.getValue());
- }
- /***********************************************************************************************************************************************************
- * Copy roles of the given type.
- * @param source the source
- * @param roleType the type of roles to collect
- **********************************************************************************************************************************************************/
- private <R> void copyRoles (@Nonnull final As source, @Nonnull final Class<R> roleType)
- {
- putMany(roleType, source.asMany(roleType));
- }
- }