View Javadoc
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&lt;PresentationModel&gt; pms = ...
63       * PresentationModel compositePm = pms.stream().collect(toCompositePresentationModel());
64       * // same contents as childrenPms
65       * List&lt;PresentationModel&gt; 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   }