1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.framework;
35
36 import info.magnolia.ui.framework.ioc.ViewComponentProvider;
37 import info.magnolia.ui.framework.ioc.ViewContextKeyRegistry;
38 import info.magnolia.objectfactory.ComponentProvider;
39 import info.magnolia.ui.api.ioc.UiContextScoped;
40 import info.magnolia.ui.framework.ioc.BeanStore;
41 import info.magnolia.ui.framework.ioc.SessionStore;
42 import info.magnolia.ui.framework.ioc.UiContextBoundComponentProvider;
43 import info.magnolia.ui.framework.ioc.UiContextReference;
44 import info.magnolia.util.Util;
45
46 import java.util.Objects;
47 import java.util.stream.Stream;
48
49 import javax.inject.Inject;
50
51
52
53
54 @UiContextScoped
55 public class ViewProviderImpl implements ViewProvider {
56
57 private final UiContextReference currentUiContextReference;
58
59 @Inject
60 ViewProviderImpl(UiContextReference currentUiContextReference) {
61 this.currentUiContextReference = currentUiContextReference;
62 }
63
64 @Override
65 public <V extends UiFrameworkView, D extends ViewDefinition<V>> V create(D definition, Object... args) {
66 final Class<? extends V> viewImpl = definition.getImplementationClass();
67 final ViewContextKeyRegistry viewContextRegistry = ViewContextKeyRegistry.access();
68
69 final UiContextBoundComponentProvider componentProvider = createComponentProvider(definition, args);
70 final UiContextReference viewContextReference = componentProvider.getUiContextReference();
71 final BeanStore beanStore = SessionStore.access().getBeanStore(viewContextReference);
72 Stream.of(args).filter(Objects::nonNull).forEach(arg -> beanStore.put(arg.getClass(), arg));
73
74 final V view = componentProvider.newInstance(viewImpl, args);
75 viewContextRegistry.register(view, viewContextReference);
76 beanStore.put(viewImpl, view);
77
78 return view;
79 }
80
81 private <D extends ViewDefinition> UiContextBoundComponentProvider createComponentProvider(D definition, Object... args) {
82 final UiContextReference viewContextReference = generateUniqueViewContextReference(definition, ViewContextKeyRegistry.access());
83
84 final BeanStore beanStore = SessionStore.access().createBeanStore(viewContextReference);
85
86 Stream.of(args).forEach(arg -> beanStore.put(arg.getClass(), arg));
87
88 final ViewComponentProvider viewComponentProvider = new ViewComponentProvider(viewContextReference);
89 beanStore.put(ComponentProvider.class, viewComponentProvider);
90 beanStore.put(ViewComponentProvider.class, viewComponentProvider);
91 beanStore.put(ViewProvider.class, new ViewProviderImpl(viewContextReference));
92 beanStore.put(definition.getClass(), definition);
93
94 return viewComponentProvider;
95 }
96
97 private <V extends UiFrameworkView, D extends ViewDefinition<V>> UiContextReference generateUniqueViewContextReference(D definition, ViewContextKeyRegistry registry) {
98 String name = definition.getName();
99 UiContextReference viewContextReference;
100 do {
101 viewContextReference = UiContextReference.ofView(name, currentUiContextReference);
102 name = Util.createUniqueName(name);
103 } while (registry.isRegistered(viewContextReference));
104
105 return viewContextReference;
106 }
107 }