1 /*
2 * *************************************************************************************************************************************************************
3 *
4 * TheseFoolishThings: Miscellaneous utilities
5 * http://tidalwave.it/projects/thesefoolishthings
6 *
7 * Copyright (C) 2009 - 2024 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.ui.spi;
27
28 import javax.annotation.Nonnull;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.function.Function;
34 import java.util.stream.Stream;
35 import java.util.stream.StreamSupport;
36 import it.tidalwave.util.As;
37 import it.tidalwave.util.spi.ArrayListCollectorSupport;
38 import it.tidalwave.role.Composite;
39 import it.tidalwave.role.SimpleComposite;
40 import it.tidalwave.role.ui.PresentationModel;
41 import static it.tidalwave.util.Parameters.r;
42 import static it.tidalwave.role.ui.Presentable._Presentable_;
43
44 /***************************************************************************************************************************************************************
45 *
46 * A {@link java.util.stream.Collector} which collects a {@link Stream} of {@link PresentationModel}s into a single
47 * {@code PresentationModel} with a {@code Composite<PresentationModel>} role containing them.
48 *
49 * @author Fabrizio Giudici
50 *
51 **************************************************************************************************************************************************************/
52 public class PresentationModelCollectors extends ArrayListCollectorSupport<PresentationModel, PresentationModel>
53 {
54 @Nonnull
55 private final Collection<Object> roles = new ArrayList<>();
56
57 /***********************************************************************************************************************************************************
58 * A {@link java.util.stream.Collector} which collects a {@link Stream} of {@link PresentationModel}s into a single
59 * {@code PresentationModel} with a {@link Composite} role containing them. In other words:
60 *
61 * <pre>
62 * List<PresentationModel> pms = ...
63 * PresentationModel compositePm = pms.stream().collect(toCompositePresentationModel());
64 * // same contents as childrenPms
65 * List<PresentationModel> childrenPms = compositePm.as(_Composite_).findChildren().results();
66 * </pre>
67 *
68 * @param roles some extra roles included in the resulting {@code PresentationModel}
69 * @return a {@code PresentationModel}
70 * @since 3.2-ALPHA-3 (refactored)
71 **********************************************************************************************************************************************************/
72 @Nonnull
73 public static PresentationModelCollectors toCompositePresentationModel (@Nonnull final Collection<Object> roles)
74 {
75 return new PresentationModelCollectors(roles);
76 }
77
78 @Nonnull
79 public static PresentationModelCollectors toCompositePresentationModel()
80 {
81 return toCompositePresentationModel((Collection<Object>)Collections.emptyList());
82 }
83
84 /***********************************************************************************************************************************************************
85 * A facility method that creates a composite {@link PresentationModel} out of an iterable (which means an array,
86 * a collection or a stream) of objects implementing {@link As}. For each object in the iterable, its {@code
87 * PresentationModel} is created by means of invoking its {@link it.tidalwave.role.ui.Presentable} role. Then all
88 * the {@code PresentationModel}s are aggregated into the composite.
89 *
90 * A function which creates specific roles for each {@code PresentationModel} can be specified. The function can
91 * return a single role or multiple roles in form of an array {@code Object[]}.
92 *
93 * @param <T> the type of the objects
94 * @param i the {@code Iterable}
95 * @param roleCreator the function to create roles
96 * @return the composite {@code PresentationModel}
97 *
98 ******************************************************************************************************************/
99 @Nonnull
100 public static <T extends As> PresentationModel toCompositePresentationModel (
101 @Nonnull final Iterable<? extends T> i,
102 @Nonnull final Function<? super T, Object> roleCreator)
103 {
104 return StreamSupport.stream(i.spliterator(), false)
105 .map(o -> o.as(_Presentable_).createPresentationModel(r(roleCreator.apply(o))))
106 .collect(toCompositePresentationModel());
107 }
108
109 /***********************************************************************************************************************************************************
110 * A facility simplified version of
111 * {@link #toCompositePresentationModel(java.lang.Iterable, java.util.function.Function)}.
112 *
113 * @param <T> the type of the objects
114 * @param i the {@code Iterable}
115 * @return the composite {@code PresentationModel}
116 *
117 ******************************************************************************************************************/
118 @Nonnull
119 public static <T extends As> PresentationModel toCompositePresentationModel (@Nonnull final Iterable<T> i)
120 {
121 return toCompositePresentationModel(i, o -> new Object[0]);
122 }
123
124 /***********************************************************************************************************************************************************
125 * {@inheritDoc}
126 *
127 ******************************************************************************************************************/
128 @Override @Nonnull
129 public Function<List<PresentationModel>, PresentationModel> finisher()
130 {
131 return childrenPms -> PresentationModel.of("", r(roles, SimpleComposite.ofCloned(childrenPms)));
132 }
133
134 /***********************************************************************************************************************************************************
135 *
136 ******************************************************************************************************************/
137 private PresentationModelCollectors (@Nonnull final Collection<Object> roles)
138 {
139 this.roles.addAll(roles);
140 }
141 }