Package: ViewAndControllerLayoutBuilder
ViewAndControllerLayoutBuilder
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
createComponent(Layout) |
|
|
|
|
|
||||||||||||||||||||
createErrorView(Layout, Throwable) |
|
|
|
|
|
||||||||||||||||||||
getValue() |
|
|
|
|
|
||||||||||||||||||||
getViewAndControllerFor(Layout) |
|
|
|
|
|
||||||||||||||||||||
static {...} |
|
|
|
|
|
||||||||||||||||||||
visit(Layout) |
|
|
|
|
|
Coverage
1: /*
2: * *************************************************************************************************************************************************************
3: *
4: * NorthernWind - lightweight CMS
5: * http://tidalwave.it/projects/northernwind
6: *
7: * Copyright (C) 2011 - 2025 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/northernwind-src
22: * git clone https://github.com/tidalwave-it/northernwind-src
23: *
24: * *************************************************************************************************************************************************************
25: */
26: package it.tidalwave.northernwind.frontend.ui.spi;
27:
28: import javax.annotation.Nonnull;
29: import javax.annotation.concurrent.NotThreadSafe;
30: import java.util.IdentityHashMap;
31: import java.util.Map;
32: import java.util.Optional;
33: import java.util.function.BiFunction;
34: import it.tidalwave.util.NotFoundException;
35: import it.tidalwave.role.Composite;
36: import it.tidalwave.northernwind.core.model.SiteNode;
37: import it.tidalwave.northernwind.frontend.ui.Layout;
38: import it.tidalwave.northernwind.frontend.ui.RenderContext;
39: import it.tidalwave.northernwind.frontend.ui.ViewController;
40: import it.tidalwave.northernwind.frontend.ui.ViewFactory.ViewAndController;
41: import lombok.Getter;
42: import lombok.RequiredArgsConstructor;
43:
44: /***************************************************************************************************************************************************************
45: *
46: * A {@link Layout} visitor that instantiate views and controllers for a given {@code Layout}. The whole {@code Layout}
47: * tree is visited and for each child an instance of {@link ViewAndController} is created, the controller being called
48: * with the {@link ViewController#prepareRendering(it.tidalwave.northernwind.frontend.ui.ViewController.RenderContext)}
49: * method. No rendering is performed, but instances of {@code ViewAndController} are stored for later retrieval by means
50: * of the method {@link #getViewAndControllerFor(it.tidalwave.northernwind.frontend.ui.Layout)}.
51: *
52: * @stereotype Visitor
53: * @author Fabrizio Giudici
54: *
55: **************************************************************************************************************************************************************/
56: @NotThreadSafe @RequiredArgsConstructor
57: public class ViewAndControllerLayoutBuilder implements Composite.Visitor<Layout, ViewAndControllerLayoutBuilder>
58: {
59: private static final ViewController VOID_CONTROLLER = new ViewController() {};
60:
61: @Nonnull
62: private final SiteNode siteNode;
63:
64: @Nonnull
65: private final RenderContext renderContext;
66:
67: @Getter @Nonnull
68: private final BiFunction<Layout, Throwable, Object> errorViewSupplier;
69:
70: private final Map<Layout, ViewAndController> viewAndControllerMapByLayout = new IdentityHashMap<>();
71:
72: /***********************************************************************************************************************************************************
73: *
74: **********************************************************************************************************************************************************/
75: @Override
76: public void visit (@Nonnull final Layout layout)
77: {
78: try
79: {
80: final var vac = createComponent(layout);
81: vac.getController().prepareRendering(renderContext);
82: viewAndControllerMapByLayout.put(layout, vac);
83: }
84: catch (Exception e)
85: {
86: viewAndControllerMapByLayout.put(layout, createErrorView(layout, e));
87: }
88: }
89:
90: /***********************************************************************************************************************************************************
91: *
92: **********************************************************************************************************************************************************/
93: @Override @Nonnull
94: public Optional<ViewAndControllerLayoutBuilder> getValue()
95: {
96: return Optional.of(this);
97: }
98:
99: /***********************************************************************************************************************************************************
100: *
101: **********************************************************************************************************************************************************/
102: @Nonnull
103: public Optional<ViewAndController> getViewAndControllerFor (@Nonnull final Layout layout)
104: {
105: return Optional.ofNullable(viewAndControllerMapByLayout.get(layout));
106: }
107:
108: /***********************************************************************************************************************************************************
109: *
110: **********************************************************************************************************************************************************/
111: @Nonnull
112: private ViewAndController createComponent (@Nonnull final Layout layout)
113: {
114: try
115: {
116: return layout.createViewAndController(siteNode);
117: }
118: catch (NotFoundException e)
119: {
120: return createErrorView(layout, new NotFoundException("Missing component for: " + layout.getTypeUri()));
121: }
122: catch (Throwable e)
123: {
124: return createErrorView(layout, e);
125: }
126: }
127:
128: /***********************************************************************************************************************************************************
129: *
130: **********************************************************************************************************************************************************/
131: @Nonnull
132: private ViewAndController createErrorView (@Nonnull final Layout layout, @Nonnull final Throwable e)
133: {
134: return new ViewAndController(errorViewSupplier.apply(layout, e), VOID_CONTROLLER);
135: }
136: }