View Javadoc
1   /*
2    * *************************************************************************************************************************************************************
3    *
4    * SteelBlue: DCI User Interfaces
5    * http://tidalwave.it/projects/steelblue
6    *
7    * Copyright (C) 2015 - 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/steelblue-src
22   * git clone https://github.com/tidalwave-it/steelblue-src
23   *
24   * *************************************************************************************************************************************************************
25   */
26  package it.tidalwave.role.ui.javafx.impl.common;
27  
28  import javax.annotation.Nonnegative;
29  import javax.annotation.Nonnull;
30  import java.util.ArrayList;
31  import java.util.List;
32  import java.util.concurrent.Executor;
33  import java.util.concurrent.RejectedExecutionException;
34  import java.util.function.Consumer;
35  import java.util.function.Supplier;
36  import javafx.collections.ObservableList;
37  import javafx.application.Platform;
38  import it.tidalwave.util.annotation.VisibleForTesting;
39  import it.tidalwave.role.ui.PresentationModel;
40  import it.tidalwave.role.ui.javafx.impl.util.Logging;
41  import lombok.experimental.UtilityClass;
42  import lombok.extern.slf4j.Slf4j;
43  import static java.util.Collections.emptyList;
44  import static javafx.collections.FXCollections.*;
45  import static it.tidalwave.role.SimpleComposite._SimpleComposite_;
46  import static it.tidalwave.role.ui.javafx.impl.util.Logging.INDENT;
47  
48  /***************************************************************************************************************************************************************
49   *
50   * @author  Fabrizio Giudici
51   *
52   **************************************************************************************************************************************************************/
53  @UtilityClass @Slf4j
54  public class JavaFXWorker
55    {
56      public static <T> void run (@Nonnull final Executor executor,
57                                  @Nonnull Supplier<T> backgroundSupplier,
58                                  @Nonnull Consumer<T> javaFxFinalizer)
59        {
60          try
61            {
62              executor.execute(() ->
63                {
64                  final var value = backgroundSupplier.get();
65                  Platform.runLater(() -> javaFxFinalizer.accept(value));
66                });
67            }
68          catch (RejectedExecutionException e)
69            {
70              log.error("Background task failed: {}", e.getMessage());
71            }
72        }
73  
74      @Nonnull
75      public static ObservableList<PresentationModel> childrenPm (@Nonnull final PresentationModel pm)
76        {
77          return childrenPm(pm, 0);
78        }
79  
80      @Nonnull
81      public static ObservableList<PresentationModel> childrenPm (@Nonnull final PresentationModel pm,
82                                                                  @Nonnegative int depth)
83        {
84          final var indent = INDENT.substring(0, depth * 8);
85          final var composite = pm.maybeAs(_SimpleComposite_);
86          composite.ifPresent(c -> Logging.logObject(indent, composite));
87          final List<PresentationModel> items = composite.map(c -> c.findChildren().results()).orElse(emptyList());
88          final var badItems = extractBadItems(items);
89  
90          if (!badItems.isEmpty()) // defensive
91            {
92              log.error("Child object are not PresentationModel: (only 10 are shown)");
93              log.error("This happens when the PresentationModel doesn't have its own Composite role that decorates the" +
94                        " owner entity Composite - see SimpleCompositePresentable for instance.");
95              badItems.stream().limit(10).forEach(item -> log.error("    {}", item));
96              return emptyObservableList();
97            }
98  
99          Logging.logObjects(indent, items);
100         return observableArrayList(items);
101       }
102 
103     @Nonnull
104     @VisibleForTesting static List<Object> extractBadItems (@Nonnull final List<PresentationModel> items)
105       {
106         final List<Object> badItems = new ArrayList<>(items);
107         badItems.removeIf(item -> item instanceof PresentationModel);
108         return badItems;
109 //        return items.stream()
110 //                    .map(item -> (Object)item)
111 //                    .filter(item -> !(item instanceof PresentationModel))
112 //                    .peek(item -> log.error(">>>> {}", item))
113 //                    .collect(toList());
114       }
115   }
116