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.config.registry.DefinitionMetadata;
37 import info.magnolia.config.registry.DefinitionProvider;
38 import info.magnolia.config.registry.DefinitionRawView;
39 import info.magnolia.config.registry.Registry;
40 import info.magnolia.config.registry.decoration.DefinitionDecorator;
41 import info.magnolia.config.source.ConfigurationSourceTypes;
42 import info.magnolia.config.source.raw.DefinitionRawViewMapWrapper;
43 import info.magnolia.config.source.stub.ConfigurationSourceTypeStub;
44 import info.magnolia.event.EventBus;
45 import info.magnolia.event.SystemEventBus;
46 import info.magnolia.jcr.util.NodeTypes;
47 import info.magnolia.periscope.search.SearchResultSupplierDefinition;
48 import info.magnolia.periscope.search.SearchResultSupplierDefinitionRegistry;
49 import info.magnolia.periscope.search.jcr.JcrSearchResultSupplierDefinition;
50 import info.magnolia.ui.api.app.AppDescriptor;
51 import info.magnolia.ui.api.app.SubAppDescriptor;
52 import info.magnolia.ui.api.app.registry.AppDescriptorRegistry;
53 import info.magnolia.ui.api.app.registry.AppRegistryEvent;
54 import info.magnolia.ui.api.app.registry.AppRegistryEventHandler;
55 import info.magnolia.ui.contentapp.configuration.ContentAppDescriptor;
56 import info.magnolia.ui.contentapp.configuration.ContentSubAppDescriptor;
57 import info.magnolia.ui.datasource.DatasourceDefinition;
58 import info.magnolia.ui.datasource.jcr.JcrDatasourceDefinition;
59
60 import java.util.ArrayList;
61 import java.util.Arrays;
62 import java.util.Calendar;
63 import java.util.HashMap;
64 import java.util.List;
65 import java.util.Objects;
66 import java.util.Optional;
67 import java.util.Set;
68 import java.util.stream.Collectors;
69
70 import javax.inject.Inject;
71 import javax.inject.Named;
72 import javax.inject.Singleton;
73
74 import com.google.common.collect.Sets;
75
76
77
78
79 @Singleton
80 public class JcrSearchSuppliersGenerator implements AppRegistryEventHandler {
81
82 private final AppDescriptorRegistry appDescriptorRegistry;
83 private final SearchResultSupplierDefinitionRegistry searchResultSupplierDefinitionRegistry;
84
85 @Inject
86 public JcrSearchSuppliersGenerator(AppDescriptorRegistry appDescriptorRegistry, SearchResultSupplierDefinitionRegistry searchResultSupplierDefinitionRegistry, @Named(SystemEventBus.NAME) EventBus systemEventBus) {
87 this.appDescriptorRegistry = appDescriptorRegistry;
88 this.searchResultSupplierDefinitionRegistry = searchResultSupplierDefinitionRegistry;
89 systemEventBus.addHandler(AppRegistryEvent.class, this);
90 }
91
92 @Override
93 public void onAppRegistered(AppRegistryEvent event) {
94 Optional.of(appDescriptorRegistry.getProvider(event.getAppDescriptorMetadata()))
95 .filter(DefinitionProvider::isValid)
96 .filter(appDescriptorDefinitionProvider -> searchResultSupplierDefinitionRegistry.getAllMetadata().stream()
97 .filter(metadata -> metadata.getConfigurationSourceType() != ConfigurationSourceTypes.code)
98 .filter(metadata -> metadata.getConfigurationSourceType() != ConfigurationSourceTypeStub.stub)
99 .noneMatch(metadata -> metadata.getModule().equals(appDescriptorDefinitionProvider.getMetadata().getModule()))
100 )
101 .map(this::autoGenerateSupplier)
102 .ifPresent(searchResultSupplierDefinitionRegistry::register);
103 }
104
105 @Override
106 public void onAppReregistered(AppRegistryEvent event) {
107 onAppRegistered(event);
108 }
109
110 @Override
111 public void onAppUnregistered(AppRegistryEvent event) {
112 searchResultSupplierDefinitionRegistry.unregisterAndRegister(searchResultSupplierDefinitionRegistry.getAllProviders().stream()
113 .filter(DefinitionProvider::isValid)
114 .filter(definitionProvider -> definitionProvider.getMetadata().getConfigurationSourceType().equals(ConfigurationSourceTypes.code))
115 .filter(definitionProvider -> definitionProvider.getMetadata().getName().equals(event.getAppDescriptorMetadata().getName()))
116 .map(DefinitionProvider::getMetadata)
117 .collect(Collectors.toList()),
118 Arrays.asList()
119 );
120 }
121
122
123 AutogeneratedDefinitionProvider autoGenerateSupplier(DefinitionProvider<AppDescriptor> appDescriptorDefinitionProvider) {
124 JcrDatasourceDefinition jcrDatasourceDefinition = null;
125 String subAppName = null;
126 AppDescriptor appDescriptor = appDescriptorDefinitionProvider.get();
127 if (appDescriptor instanceof ContentAppDescriptor) {
128 final DatasourceDefinition datasource = ((ContentAppDescriptor<?>) appDescriptor).getDatasource();
129 if (datasource instanceof JcrDatasourceDefinition) {
130 jcrDatasourceDefinition = (JcrDatasourceDefinition) datasource;
131 subAppName = appDescriptor.getSubApps().values().stream().findFirst().map(SubAppDescriptor::getName).orElse(null);
132 }
133 }
134 if (jcrDatasourceDefinition == null) {
135 for (SubAppDescriptor subAppDescriptor : appDescriptor.getSubApps().values()) {
136 if (subAppDescriptor instanceof ContentSubAppDescriptor) {
137 final DatasourceDefinition datasource = ((ContentSubAppDescriptor<?>) subAppDescriptor).getDatasource();
138 if (datasource instanceof JcrDatasourceDefinition) {
139 jcrDatasourceDefinition = (JcrDatasourceDefinition) datasource;
140 subAppName = subAppDescriptor.getName();
141 break;
142 }
143 }
144 }
145 }
146 return jcrDatasourceDefinition == null ? null : new AutogeneratedDefinitionProvider(appDescriptorDefinitionProvider, subAppName,
147 jcrDatasourceDefinition.getWorkspace(),
148 jcrDatasourceDefinition.getRootPath(),
149 jcrDatasourceDefinition.getAllowedNodeTypes()
150 );
151 }
152
153
154
155
156
157 class AutogeneratedDefinitionProvider implements DefinitionProvider<SearchResultSupplierDefinition> {
158
159 private final DefinitionMetadata definitionMetadata;
160 private final JcrSearchResultSupplierDefinition supplierDefinition;
161 private final DefinitionRawView rawView;
162 private long time;
163
164 AutogeneratedDefinitionProvider(DefinitionProvider<AppDescriptor> appDescriptorDefinitionProvider,
165 String subAppName, String workspace, String rootPath, Set<String> allowedNodeTypes
166 ) {
167 final DefinitionMetadata appDescriptorDefinitionProviderMetadata = appDescriptorDefinitionProvider.getMetadata();
168 supplierDefinition = new JcrSearchResultSupplierDefinition();
169 supplierDefinition.setAppName(appDescriptorDefinitionProviderMetadata.getReferenceId());
170 supplierDefinition.setSubAppName(subAppName);
171 supplierDefinition.setWorkspace(workspace);
172 supplierDefinition.setRootPath(rootPath);
173 supplierDefinition.setNodeTypes(allowedNodeTypes.isEmpty() ? Sets.newHashSet(NodeTypes.Content.NAME) : allowedNodeTypes);
174 final AppDescriptor appDescriptor = appDescriptorDefinitionProvider.get();
175 supplierDefinition.setIcon(appDescriptor.getIcon());
176 supplierDefinition.setEnabled(appDescriptor.isEnabled());
177
178 time = Calendar.getInstance().getTime().getTime();
179 rawView = new DefinitionRawViewMapWrapper(new HashMap<String, Object>() {
180 {
181 put("class", supplierDefinition.getClass().getName());
182 put("workspace", supplierDefinition.getWorkspace());
183 put("rootPath", supplierDefinition.getRootPath());
184 put("nodeTypes", supplierDefinition.getNodeTypes());
185 put("appName", supplierDefinition.getAppName());
186 put("subAppName", supplierDefinition.getSubAppName());
187 put("icon", supplierDefinition.getIcon());
188 values().removeIf(Objects::isNull);
189 }
190 });
191
192 definitionMetadata = searchResultSupplierDefinitionRegistry.newMetadataBuilder()
193 .name(appDescriptorDefinitionProviderMetadata.getName())
194 .module(appDescriptorDefinitionProviderMetadata.getModule())
195 .configurationSourceType(ConfigurationSourceTypes.code)
196 .type(SearchResultSupplierDefinitionRegistry.TYPE)
197 .relativeLocation(appDescriptorDefinitionProviderMetadata.getName())
198 .build();
199 }
200
201 @Override
202 public List<DefinitionDecorator<SearchResultSupplierDefinition>> getDecorators() {
203 return new ArrayList<>();
204 }
205
206 @Override
207 public DefinitionMetadata getMetadata() {
208 return definitionMetadata;
209 }
210
211 @Override
212 public SearchResultSupplierDefinition get() throws Registry.InvalidDefinitionException {
213 return supplierDefinition;
214 }
215
216 @Override
217 public DefinitionRawView getRaw() {
218 return rawView;
219 }
220
221 @Override
222 public boolean isValid() {
223 return true;
224 }
225
226 @Override
227 public long getLastModified() {
228 return time;
229 }
230 }
231 }