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 * Returns the children of this object.
64 *
65 * @return the children
66 **********************************************************************************************************************************************************/
67 @Nonnull
68 public F findChildren();
69
70 /***********************************************************************************************************************************************************
71 * Returns a stream of children.
72 *
73 * @return the stream
74 * @since 3.2-ALPHA-23
75 **********************************************************************************************************************************************************/
76 @Nonnull
77 public default Stream<? extends T> stream()
78 {
79 return findChildren().stream();
80 }
81
82 /***********************************************************************************************************************************************************
83 * Iterates through children.
84 *
85 * @param consumer the consumer
86 * @since 3.2-ALPHA-23
87 **********************************************************************************************************************************************************/
88 public default void forEach (@Nonnull final Consumer<? super T> consumer)
89 {
90 stream().forEach(consumer);
91 }
92
93 /***********************************************************************************************************************************************************
94 **********************************************************************************************************************************************************/
95 @SuppressWarnings("EmptyMethod")
96 public static interface Visitor<T, R>
97 {
98 /***************************************************************************************************************
99 *
100 * Visits an object. This method is called before visiting children (pre-order).
101 *
102 * @param object the visited object
103 *
104 **************************************************************************************************************/
105 public default void preVisit (@Nonnull final T object)
106 {
107 }
108
109 /***************************************************************************************************************
110 *
111 * Visits an object. This method is actually called just after {@link #preVisit(Object)}, it makes sense to
112 * implement it when you don't need to distinguish between pre-order and post-order traversal.
113 *
114 * @param object the visited object
115 *
116 **************************************************************************************************************/
117 public default void visit (@Nonnull final T object)
118 {
119 }
120
121 /***************************************************************************************************************
122 *
123 * Visits an object. This method is called after visiting children (post-order).
124 *
125 * @param object the visited object
126 *
127 **************************************************************************************************************/
128 public default void postVisit (@Nonnull final T object)
129 {
130 }
131
132 /***************************************************************************************************************
133 *
134 * Returns the value of this visitor.
135 *
136 * @return the value
137 *
138 **************************************************************************************************************/
139 @Nonnull
140 public default Optional<R> getValue()
141 {
142 return Optional.empty();
143 }
144 }
145 }