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.api.app.registry;
35
36 import info.magnolia.config.registry.AbstractRegistry;
37 import info.magnolia.config.registry.DefinitionMetadata;
38 import info.magnolia.config.registry.DefinitionMetadataBuilder;
39 import info.magnolia.config.registry.DefinitionProvider;
40 import info.magnolia.config.registry.DefinitionType;
41 import info.magnolia.event.EventBus;
42 import info.magnolia.event.SystemEventBus;
43 import info.magnolia.ui.api.app.AppDescriptor;
44
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.Collections;
48 import java.util.List;
49 import java.util.Set;
50
51 import javax.inject.Inject;
52 import javax.inject.Named;
53 import javax.inject.Singleton;
54
55 import org.apache.commons.collections.CollectionUtils;
56
57
58
59
60
61
62
63 @Singleton
64 public class AppDescriptorRegistry extends AbstractRegistry<AppDescriptor> {
65
66 private EventBus systemEventBus;
67
68 @Inject
69 public AppDescriptorRegistry(@Named(SystemEventBus.NAME) EventBus systemEventBus) {
70 this.systemEventBus = systemEventBus;
71 }
72
73 @Override
74 public void register(DefinitionProvider<AppDescriptor> provider) {
75 super.register(provider);
76 sendEvent(AppRegistryEventType.REGISTERED, Collections.singleton(provider.getMetadata()));
77 }
78
79
80 public void unregister(String name) {
81 DefinitionProvider<AppDescriptor> toRemove = getProvider(name);
82 getRegistryMap().remove(toRemove.getMetadata());
83 sendEvent(AppRegistryEventType.UNREGISTERED, Collections.singleton(toRemove.getMetadata()));
84 }
85
86
87
88
89 @Deprecated
90 public AppDescriptor getAppDescriptor(String name) {
91 return getProvider(name).get();
92 }
93
94
95
96
97 @Deprecated
98 public boolean isAppDescriptorRegistered(String name) {
99 try {
100 getProvider(name);
101 } catch (NoSuchDefinitionException | IllegalStateException e) {
102 return false;
103 }
104 return true;
105 }
106
107 @SuppressWarnings("unchecked")
108 @Override
109 public Set<DefinitionMetadata> unregisterAndRegister(Collection<DefinitionMetadata> metaDataToUnregister, Collection<DefinitionProvider<AppDescriptor>> providersToRegister) {
110
111 Collection<DefinitionMetadata> metadataBefore = getRegistryMap().keySet();
112 Collection<DefinitionProvider<AppDescriptor>> providersBefore = getRegistryMap().values();
113
114 Set<DefinitionMetadata> registeredMetaData = super.unregisterAndRegister(metaDataToUnregister, providersToRegister);
115
116 Collection<DefinitionMetadata> metadataAfter = getRegistryMap().keySet();
117
118 Collection<DefinitionMetadata> added = CollectionUtils.subtract(metadataAfter, metadataBefore);
119 Collection<DefinitionMetadata> removed = CollectionUtils.subtract(metadataBefore, metadataAfter);
120 Collection<DefinitionMetadata> kept = CollectionUtils.subtract(metadataBefore, removed);
121 Collection<DefinitionMetadata> changed = getAppsThatHaveChanged(kept, providersBefore, providersToRegister);
122
123 sendEvent(AppRegistryEventType.REGISTERED, added);
124 sendEvent(AppRegistryEventType.UNREGISTERED, removed);
125 sendEvent(AppRegistryEventType.REREGISTERED, changed);
126
127 return registeredMetaData;
128 }
129
130 @Override
131 public DefinitionType type() {
132 return DefinitionTypes.APP;
133 }
134
135 @Override
136 public DefinitionMetadataBuilder newMetadataBuilder() {
137 return DefinitionMetadataBuilder.usingNameAsId();
138 }
139
140 private Collection<DefinitionMetadata> getAppsThatHaveChanged(Collection<DefinitionMetadata> kept, Collection<DefinitionProvider<AppDescriptor>> providersBefore, Collection<DefinitionProvider<AppDescriptor>> providersToRegister) {
141 final List<DefinitionMetadata> changed = new ArrayList<>();
142 for (DefinitionMetadata metadata : kept) {
143 if (!getAppDescriptor(metadata, providersBefore).equals(getAppDescriptor(metadata, providersToRegister))) {
144 changed.add(metadata);
145 }
146 }
147 return changed;
148 }
149
150 private AppDescriptor getAppDescriptor(DefinitionMetadata metadata, Collection<DefinitionProvider<AppDescriptor>> providers) {
151 for (DefinitionProvider<AppDescriptor> provider : providers) {
152 if (provider.getMetadata().equals(metadata)) {
153 return provider.get();
154 }
155 }
156 return null;
157 }
158
159
160
161
162 private void sendEvent(AppRegistryEventType eventType, Collection<DefinitionMetadata> appDescriptors) {
163 for (DefinitionMetadata appMetadata : appDescriptors) {
164 systemEventBus.fireEvent(new AppRegistryEvent(appMetadata, eventType));
165 }
166 }
167 }