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;
27
28 import javax.annotation.Nonnull;
29 import java.util.Optional;
30 import java.util.function.Consumer;
31 import java.util.stream.Stream;
32 import it.tidalwave.util.Finder;
33
34 /***************************************************************************************************************************************************************
35 *
36 * The role of a composite object, that is an object which contains children. They are exposed by means of a
37 * {@link Finder}.
38 *
39 * @stereotype Role
40 *
41 * @author Fabrizio Giudici
42 * @it.tidalwave.javadoc.stable
43 *
44 **************************************************************************************************************************************************************/
45 @FunctionalInterface
46 public interface Composite<T, F extends Finder<? extends T>>
47 {
48 public static final Class<Composite> _Composite_ = Composite.class;
49
50 /***********************************************************************************************************************************************************
51 * A default <code>Composite</code> with no children.
52 **********************************************************************************************************************************************************/
53 public static final Composite<Object, Finder<Object>> DEFAULT = new Composite<>()
54 {
55 @Override @Nonnull
56 public Finder<Object> findChildren()
57 {
58 return Finder.empty();
59 }
60 };
61
62 /***********************************************************************************************************************************************************
63 * {@return the children of this object}.
64 **********************************************************************************************************************************************************/
65 @Nonnull
66 public F findChildren();
67
68 /***********************************************************************************************************************************************************
69 * {@return a stream of children}.
70 * @since 3.2-ALPHA-23
71 **********************************************************************************************************************************************************/
72 @Nonnull
73 public default Stream<? extends T> stream()
74 {
75 return findChildren().stream();
76 }
77
78 /***********************************************************************************************************************************************************
79 * Iterates through children.
80 * @param consumer the consumer
81 * @since 3.2-ALPHA-23
82 **********************************************************************************************************************************************************/
83 public default void forEach (@Nonnull final Consumer<? super T> consumer)
84 {
85 stream().forEach(consumer);
86 }
87
88 /***********************************************************************************************************************************************************
89 * A visitor that can travel through the {@code Composite} items.
90 * @param <T> the type of the composite
91 * @param <R> the type of the result
92 **********************************************************************************************************************************************************/
93 @SuppressWarnings("EmptyMethod")
94 public static interface Visitor<T, R>
95 {
96 /*******************************************************************************************************************************************************
97 * Visits an object. This method is called before visiting children (pre-order).
98 * @param object the visited object
99 ******************************************************************************************************************************************************/
100 public default void preVisit (@Nonnull final T object)
101 {
102 }
103
104 /*******************************************************************************************************************************************************
105 * Visits an object. This method is actually called just after {@link #preVisit(Object)}, it makes sense to implement it when you don't need to
106 * distinguish between pre-order and post-order traversal.
107 * @param object the visited object
108 ******************************************************************************************************************************************************/
109 public default void visit (@Nonnull final T object)
110 {
111 }
112
113 /*******************************************************************************************************************************************************
114 * Visits an object. This method is called after visiting children (post-order).
115 * @param object the visited object
116 ******************************************************************************************************************************************************/
117 public default void postVisit (@Nonnull final T object)
118 {
119 }
120
121 /*******************************************************************************************************************************************************
122 * {@return the value of this visitor}.
123 ******************************************************************************************************************************************************/
124 @Nonnull
125 public default Optional<R> getValue()
126 {
127 return Optional.empty();
128 }
129 }
130 }