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.ioc;
35
36 import info.magnolia.objectfactory.CandidateParameterResolver;
37 import info.magnolia.objectfactory.ComponentProvider;
38 import info.magnolia.objectfactory.ParameterResolver;
39 import info.magnolia.objectfactory.guice.GuiceComponentProvider;
40
41 import java.io.Serializable;
42 import java.util.function.Supplier;
43
44 import com.google.inject.Key;
45 import com.vaadin.server.VaadinServlet;
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class UiContextBoundComponentProvider implements ComponentProvider, Serializable {
60
61 private final transient GuiceComponentProvider parentComponentProvider;
62
63 private final CurrentUiContextReference currentUiContextReference;
64
65 private final UiContextReference uiContextReference;
66
67 public UiContextBoundComponentProvider(UiContextReference uiContextReference) {
68 this(uiContextReference, (GuiceComponentProvider) VaadinServlet.getCurrent().getServletContext().getAttribute("componentProvider"), CurrentUiContextReference.get());
69 }
70
71 public UiContextBoundComponentProvider(UiContextReference uiContextReference, GuiceComponentProvider parentComponentProvider, CurrentUiContextReference currentUiContextReference) {
72 this.uiContextReference = uiContextReference;
73 this.parentComponentProvider = parentComponentProvider;
74 this.currentUiContextReference = currentUiContextReference;
75 }
76
77 public UiContextReference getUiContextReference() {
78 return this.uiContextReference;
79 }
80
81 @Override
82 public <T> Class<? extends T> getImplementation(Class<T> type) {
83 return getParent().getImplementation(getClosestMappedType(type));
84 }
85
86 private <T> Key<T> getClosestMappedType(Class<T> type) {
87 return this.currentUiContextReference.getAvailableContextReferences().stream()
88 .map(key -> Key.get(type, key.getAnnotation()))
89
90 .filter(key -> getParent().getTypeMappings().containsKey(key))
91 .findFirst()
92
93 .orElseGet(() -> Key.get(type));
94 }
95
96 @Override
97 public <T> T getSingleton(Class<T> type) {
98 return getParent().getSingleton(type);
99 }
100
101 @Override
102 public <T> T getComponent(Class<T> type) {
103 return provideInCurrentScope(() -> getParent().getComponent(type));
104 }
105
106 @Override
107 public <T> T newInstance(Class<T> type, Object... parameters) {
108 return newInstanceWithParameterResolvers(type, new CandidateParameterResolver(parameters));
109 }
110
111 @Override
112 public <T> T newInstanceWithParameterResolvers(Class<T> type, ParameterResolver... parameters) {
113 return provideInCurrentScope(() -> getParent().newInstanceWithParameterResolvers(getClosestMappedType(type), parameters));
114 }
115
116 @Override
117 public GuiceComponentProvider getParent() {
118 return this.parentComponentProvider;
119 }
120
121 private <T> T provideInCurrentScope(Supplier<T> provider) {
122 final UiContextReference previousUiContextReference = currentUiContextReference.getUiContextReference();
123 currentUiContextReference.setUiContextReference(this.uiContextReference);
124 try {
125 return provider.get();
126 } finally {
127 currentUiContextReference.setUiContextReference(previousUiContextReference);
128 }
129 }
130 }