RoleManager.java

  1. /*
  2.  * *********************************************************************************************************************
  3.  *
  4.  * TheseFoolishThings: Miscellaneous utilities
  5.  * http://tidalwave.it/projects/thesefoolishthings
  6.  *
  7.  * Copyright (C) 2009 - 2023 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
  12.  * the License. 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
  17.  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
  18.  * specific language governing permissions and limitations under the License.
  19.  *
  20.  * *********************************************************************************************************************
  21.  *
  22.  * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
  23.  * git clone https://github.com/tidalwave-it/thesefoolishthings-src
  24.  *
  25.  * *********************************************************************************************************************
  26.  */
  27. package it.tidalwave.role.spi;

  28. import javax.annotation.Nonnull;
  29. import java.util.Iterator;
  30. import java.util.List;
  31. import java.util.Objects;
  32. import java.util.ServiceLoader;
  33. import it.tidalwave.util.LazySupplier;
  34. import lombok.AccessLevel;
  35. import lombok.NoArgsConstructor;
  36. import lombok.extern.slf4j.Slf4j;

  37. /***********************************************************************************************************************
  38.  *
  39.  * A service which retrieves DCI Roles for a given object.
  40.  *
  41.  * @author  Fabrizio Giudici
  42.  *
  43.  **********************************************************************************************************************/
  44. public interface RoleManager
  45.   {
  46.     /*******************************************************************************************************************
  47.      *
  48.      * A locator for the {@link RoleManager} which uses the {@link ServiceLoader} facility to be independent of
  49.      * any DI framework.
  50.      *
  51.      ******************************************************************************************************************/
  52.     @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE)
  53.     public static final class Locator
  54.       {
  55.         private static final LazySupplier<RoleManager> ROLE_MANAGER_REF =
  56.                 LazySupplier.of(RoleManager.Locator::findRoleManager);

  57.         private static final LazySupplier<RoleManagerProvider> ROLE_MANAGER_PROVIDER_REF =
  58.                 LazySupplier.of(RoleManager.Locator::findRoleManagerProvider);

  59.         /***************************************************************************************************************
  60.          *
  61.          **************************************************************************************************************/
  62.         @Nonnull
  63.         public static RoleManager find()
  64.           {
  65.             return ROLE_MANAGER_REF.get();
  66.           }

  67.         /***************************************************************************************************************
  68.          *
  69.          **************************************************************************************************************/
  70.         @Nonnull
  71.         private static RoleManager findRoleManager()
  72.           {
  73.             return Objects.requireNonNull(ROLE_MANAGER_PROVIDER_REF.get().getRoleManager(),
  74.                                           "Cannot find RoleManager");
  75.           }

  76.         /***************************************************************************************************************
  77.          *
  78.          **************************************************************************************************************/
  79.         @Nonnull
  80.         private static RoleManagerProvider findRoleManagerProvider()
  81.           {
  82.             final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  83.             final Iterator<RoleManagerProvider> i =
  84.                     ServiceLoader.load(RoleManagerProvider.class, classLoader).iterator();

  85.             if (!i.hasNext())
  86.               {
  87.                 throw new RuntimeException("No ServiceProvider for RoleManagerProvider");
  88.               }

  89.             final RoleManagerProvider roleManagerProvider = Objects.requireNonNull(i.next(),
  90.                                                                                          "roleManagerProvider is null");
  91.             assert roleManagerProvider != null; // for SpotBugs
  92.             log.info("RoleManagerProvider instantiated from META-INF: {}", roleManagerProvider);
  93.             return roleManagerProvider;
  94.           }
  95.       }

  96.     /*******************************************************************************************************************
  97.      *
  98.      * Retrieves the roles of the given class for the given owner object.
  99.      *
  100.      * @param <T>           the static type of the roles
  101.      * @param   owner       the owner object
  102.      * @param   roleType    the dynamic type of the roles
  103.      * @return              a list of roles
  104.      *
  105.      ******************************************************************************************************************/
  106.     @Nonnull
  107.     public <T> List<? extends T> findRoles (@Nonnull Object owner, @Nonnull Class<T> roleType);
  108.   }