1 /*
2 * *************************************************************************************************************************************************************
3 *
4 * TheseFoolishThings: Miscellaneous utilities
5 * http://tidalwave.it/projects/thesefoolishthings
6 *
7 * Copyright (C) 2009 - 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/thesefoolishthings-src
22 * git clone https://github.com/tidalwave-it/thesefoolishthings-src
23 *
24 * *************************************************************************************************************************************************************
25 */
26 package it.tidalwave.role.impl;
27
28 import jakarta.annotation.Nonnull;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.List;
32 import it.tidalwave.util.As;
33 import it.tidalwave.util.RoleFactory;
34 import it.tidalwave.util.Task;
35 import it.tidalwave.role.spi.OwnerRoleFactory;
36 import it.tidalwave.role.spi.SystemRoleFactory;
37 import lombok.extern.slf4j.Slf4j;
38 import static it.tidalwave.util.ShortNames.*;
39
40 /***************************************************************************************************************************************************************
41 *
42 * An implementation for {@link As} based on Spring.
43 *
44 * @author Fabrizio Giudici
45 *
46 **************************************************************************************************************************************************************/
47 @Slf4j
48 class DefaultOwnerRoleFactory implements OwnerRoleFactory
49 {
50 @Nonnull
51 private final Object owner;
52
53 private final ContextSnapshot contextSnapshot;
54
55 /***********************************************************************************************************************************************************
56 * Constructor for use with composition.
57 *
58 * @param owner the owner object
59 **********************************************************************************************************************************************************/
60 public DefaultOwnerRoleFactory (@Nonnull final Object owner)
61 {
62 this.owner = owner;
63 contextSnapshot = new ContextSnapshot(owner);
64 }
65
66 /***********************************************************************************************************************************************************
67 * {@inheritDoc}
68 **********************************************************************************************************************************************************/
69 @Override @Nonnull @SuppressWarnings("unchecked")
70 public <T> Collection<T> findRoles (@Nonnull final Class<? extends T> roleType)
71 {
72 log.trace("as({}) for {}", shortName(roleType), shortId(owner));
73 log.trace(">>>> contexts: {}", contextSnapshot);
74 final var systemRoleFactory = SystemRoleFactory.getInstance();
75
76 final List<T> roles = new ArrayList<>(contextSnapshot.runWithContexts(new Task<List<? extends T>, RuntimeException>()
77 {
78 @Override @Nonnull
79 public List<? extends T> run ()
80 {
81 final List<T> systemRoles = systemRoleFactory.findRoles(owner, roleType);
82
83 for (final var roleFactory : systemRoleFactory.findRoles(owner, RoleFactory.class))
84 {
85 if (roleType.isAssignableFrom(roleFactory.getRoleType()))
86 {
87 ((RoleFactory<Object, T>)roleFactory).createRoleFor(owner).ifPresent(systemRoles::add);
88 }
89 }
90
91 return systemRoles;
92 }
93 }));
94
95 if (roleType.isAssignableFrom(owner.getClass()))
96 {
97 roles.add(roleType.cast(owner));
98 }
99
100 log.trace(">>>> as() returning {}", shortIds(roles));
101
102 return roles;
103 }
104 }