View Javadoc
1   /*
2    * *************************************************************************************************************************************************************
3    *
4    * SteelBlue: DCI User Interfaces
5    * http://tidalwave.it/projects/steelblue
6    *
7    * Copyright (C) 2015 - 2025 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.ui.core.role;
27  
28  import jakarta.annotation.Nonnull;
29  import java.util.Collection;
30  import java.util.Collections;
31  import it.tidalwave.util.As;
32  import it.tidalwave.util.NamedCallback;
33  import it.tidalwave.util.Parameters;
34  import it.tidalwave.role.SimpleComposite;
35  import it.tidalwave.ui.core.Mutable;
36  import it.tidalwave.ui.core.role.impl.DefaultPresentationModel;
37  import org.apiguardian.api.API;
38  import static it.tidalwave.util.Parameters.r;
39  import static it.tidalwave.ui.core.role.Presentable._Presentable_;
40  import static org.apiguardian.api.API.Status.EXPERIMENTAL;
41  
42  /***************************************************************************************************************************************************************
43   *
44   * TODO: As the NetBeans Node, it should allow children, have event listeners for children added/removed/changed.
45   * This class so becomes the true M in MVC.
46   *
47   * @stereotype  Role
48   * @since       2.0-ALPHA-1
49   * @author      Fabrizio Giudici
50   *
51   **************************************************************************************************************************************************************/
52  public interface PresentationModel extends As, Mutable
53    {
54      /** Shortcut for {@link it.tidalwave.util.As}. */
55      public static final Class<PresentationModel> _PresentationModel_ = PresentationModel.class;
56  
57      /** Shortcut for {@link it.tidalwave.util.As}. */
58      public static final As.Type<SimpleComposite<PresentationModel>> _SimpleCompositeOfPresentationModel_ = As.type(SimpleComposite.class);
59  
60      public static final String PROPERTY_CHILDREN = "children";
61  
62      /** This is an undocumented feature. If you add a {@link NamedCallback} with this name as a role in this object, it will be called back when
63          {@link #dispose()} is called. */
64      public static final String CALLBACK_DISPOSE = "dispose";
65  
66      public static final String P_VERBOSE_TOSTRING = PresentationModel.class.getCanonicalName() + ".verboseToString";
67  
68      public static final String PARAM_OWNER = "owner";
69      public static final String PARAM_ROLE = "role";
70  
71      /***********************************************************************************************************************************************************
72       * Disposes this object.
73       **********************************************************************************************************************************************************/
74      public void dispose();
75  
76      /***********************************************************************************************************************************************************
77       * {@return a new instance given an owner and no roles}.
78       * @param   owner   the owner
79       * @since           3.2-ALPHA-3
80       **********************************************************************************************************************************************************/
81      @Nonnull
82      public static PresentationModel of (@Nonnull final Object owner)
83        {
84          Parameters.mustNotBeArrayOrCollection(owner, PARAM_OWNER);
85          return of(owner, Collections.emptyList());
86        }
87  
88      /***********************************************************************************************************************************************************
89       * {@return a new instance given an owner and a single role}.
90       * @param   owner   the owner
91       * @param   role    the role (or a {@link it.tidalwave.util.RoleFactory})
92       * @since           3.2-ALPHA-3
93       **********************************************************************************************************************************************************/
94      @Nonnull
95      public static PresentationModel of (@Nonnull final Object owner, @Nonnull final Object role)
96        {
97          Parameters.mustNotBeArrayOrCollection(owner, PARAM_OWNER);
98          Parameters.mustNotBeArrayOrCollection(role, PARAM_ROLE);
99          return of(owner, r(role));
100       }
101 
102     /***********************************************************************************************************************************************************
103      * {@return a new instance given an owner and multiple roles}.
104      * @param   owner   the owner
105      * @param   roles   roles or {@link it.tidalwave.util.RoleFactory} instances
106      * @since           3.2-ALPHA-1
107      * @since           3.2-ALPHA-3 (refactored)
108      **********************************************************************************************************************************************************/
109     @Nonnull
110     public static PresentationModel of (@Nonnull final Object owner, @Nonnull final Collection<Object> roles)
111       {
112         Parameters.mustNotBeArrayOrCollection(owner, PARAM_OWNER);
113         return new DefaultPresentationModel(owner, roles);
114       }
115 
116     /***********************************************************************************************************************************************************
117      * {@return an empty instance (no roles, with the exception of a dummy {@link Displayable})}.
118      * @since           3.2-ALPHA-3
119      **********************************************************************************************************************************************************/
120     @Nonnull
121     public static PresentationModel empty()
122       {
123         // TODO: cache a singleton, but don't do eager initialization (e.g. a final static), as it would deadlock
124         return of("", Displayable.of("<empty presentation model>"));
125       }
126 
127     /***********************************************************************************************************************************************************
128      * {@return a new instance from an owner which might have the {@link Presentable} role}. If it is present, it is called to create the
129      * {@code PresentationModel}; otherwise a default one is created. Additional roles are added.
130      * @param   owner   the owner
131      * @param   roles   roles or {@link it.tidalwave.util.RoleFactory} instances
132      * @since           3.2-ALPHA-8
133      **********************************************************************************************************************************************************/
134     @API(status = EXPERIMENTAL) // TODO: perhaps it could be merged to of().
135     @Nonnull
136     public static PresentationModel ofMaybePresentable (@Nonnull final As owner, @Nonnull final Collection<Object> roles)
137       {
138         Parameters.mustNotBeArrayOrCollection(owner, PARAM_OWNER);
139         return owner.maybeAs(_Presentable_)
140                     .map(p -> p.createPresentationModel(roles))
141                     .orElseGet(() -> of(owner, roles));
142       }
143 
144     /***********************************************************************************************************************************************************
145      * {@return a new instance from an owner which might have the {@link Presentable} role}. If it is present, it is called to create the
146      * {@code PresentationModel}; otherwise a default one is created.
147      * @param   owner   the owner
148      * @since           3.2-ALPHA-8
149      **********************************************************************************************************************************************************/
150     @API(status = EXPERIMENTAL) // TODO: perhaps it could be merged to of().
151     @Nonnull
152     public static PresentationModel ofMaybePresentable (@Nonnull final As owner)
153       {
154         return ofMaybePresentable(owner, Collections.emptyList());
155       }
156 
157     /***********************************************************************************************************************************************************
158      * Sets the verbose mode for {@link java.lang.Object#toString} implementations of {@code PresentationModel}. Looking at the implementation of
159      * {@link javafx.scene.control.cell.DefaultTreeCell}, the code always calls {@code toString()} during an update, even though the text value is later
160      * overridden; hence, this method should be as fast as possible. By default, the shortened class name and system id of the owner object is returned;
161      * set verbosity to have the owner object {@code toString()} called instead.
162      * It is also possible to set system the property {@code it.tidalwave.ui.core.role.PresentationModel.verboseToString}.
163      * @param           verbose   the verbosity
164      * @since           2.0-ALPHA-4
165      * @see             #isVerboseToString()
166      **********************************************************************************************************************************************************/
167     public static void setVerboseToString (final boolean verbose)
168       {
169         DefaultPresentationModel.setVerboseToString(verbose);
170       }
171 
172     /***********************************************************************************************************************************************************
173      * {@return the verbose mode for {@link java.lang.Object#toString} implementations of {@code PresentationModel}}.
174      * @since           2.0-ALPHA-4
175      * @see             #setVerboseToString(boolean)
176      **********************************************************************************************************************************************************/
177     public static boolean isVerboseToString()
178       {
179         return DefaultPresentationModel.isVerboseToString();
180       }
181   }