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.launcherlayout;
35
36 import info.magnolia.cms.security.User;
37 import info.magnolia.cms.security.operations.AccessDefinition;
38 import info.magnolia.config.registry.DefinitionProvider;
39 import info.magnolia.config.registry.Registry;
40 import info.magnolia.context.MgnlContext;
41 import info.magnolia.event.EventBus;
42 import info.magnolia.event.SystemEventBus;
43 import info.magnolia.i18nsystem.I18nizer;
44 import info.magnolia.ui.api.app.AppDescriptor;
45 import info.magnolia.ui.api.app.registry.AppDescriptorRegistry;
46 import info.magnolia.ui.api.app.registry.AppRegistryEvent;
47 import info.magnolia.ui.api.app.registry.AppRegistryEventHandler;
48
49 import java.util.ArrayList;
50 import java.util.List;
51 import java.util.concurrent.atomic.AtomicReference;
52
53 import javax.inject.Inject;
54 import javax.inject.Named;
55 import javax.inject.Provider;
56 import javax.inject.Singleton;
57
58 import org.apache.commons.lang3.StringUtils;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62
63
64
65 @Singleton
66 public class AppLauncherLayoutManagerImpl implements AppLauncherLayoutManager {
67
68 private final Logger log = LoggerFactory.getLogger(AppLauncherLayoutManagerImpl.class);
69
70 private final AppDescriptorRegistry appDescriptorRegistry;
71
72 private final EventBus systemEventBus;
73
74 private final AtomicReference<AppLauncherLayoutDefinition> layoutDefinitionReference = new AtomicReference<AppLauncherLayoutDefinition>();
75
76 private final Provider<I18nizer> i18nizerProvider;
77
78 @Inject
79 public AppLauncherLayoutManagerImpl(AppDescriptorRegistry appDescriptorRegistry, @Named(SystemEventBus.NAME) EventBus systemEventBus, Provider<I18nizer> i18nizerProvider) {
80 this.appDescriptorRegistry = appDescriptorRegistry;
81 this.systemEventBus = systemEventBus;
82 this.i18nizerProvider = i18nizerProvider;
83
84
85
86
87
88 systemEventBus.addHandler(AppRegistryEvent.class, new AppRegistryEventHandler() {
89
90 @Override
91 public void onAppRegistered(AppRegistryEvent event) {
92 String name = event.getAppDescriptorMetadata().getName();
93 log.debug("Got AppRegistryEvent." + event.getEventType() + " for app: " + name);
94 sendChangedEvent();
95 }
96
97 @Override
98 public void onAppReregistered(AppRegistryEvent event) {
99 String name = event.getAppDescriptorMetadata().getName();
100 log.debug("Got AppRegistryEvent." + event.getEventType() + " for app: " + name);
101 sendChangedEvent();
102 }
103
104 @Override
105 public void onAppUnregistered(AppRegistryEvent event) {
106 String name = event.getAppDescriptorMetadata().getName();
107 log.debug("Got AppRegistryEvent." + event.getEventType() + " for app: " + name);
108 sendChangedEvent();
109 }
110 });
111 }
112
113 @Deprecated
114 @Override
115 public AppLauncherLayout getLayoutForCurrentUser() {
116 return getLayoutForUser(MgnlContext.getUser());
117 }
118
119 @Override
120 public AppLauncherLayout getLayoutForUser(User user) {
121 AppLauncherLayoutDefinition layoutDefinition = layoutDefinitionReference.get();
122 if (layoutDefinition == null) {
123 return new AppLauncherLayout();
124 }
125
126 AppLauncherLayout layout = new AppLauncherLayout();
127 for (AppLauncherGroupDefinition groupDefinition : layoutDefinition.getGroups()) {
128
129 if (!isGroupVisibleForUser(groupDefinition, user)) {
130 continue;
131 }
132
133 List<AppLauncherGroupEntry> entries = new ArrayList<AppLauncherGroupEntry>();
134 for (AppLauncherGroupEntryDefinition entryDefinition : groupDefinition.getApps()) {
135 AppDescriptor appDescriptor;
136 try {
137 final DefinitionProvider<AppDescriptor> definitionProvider = appDescriptorRegistry.getProvider(entryDefinition.getName());
138 if (!definitionProvider.isValid()) {
139
140 continue;
141 }
142 appDescriptor = i18nizerProvider.get().decorate(definitionProvider.get());
143 } catch (Registry.NoSuchDefinitionException | IllegalStateException e) {
144 log.warn(e.getMessage());
145 continue;
146 }
147
148 if (StringUtils.isBlank(appDescriptor.getLabel()) || StringUtils.isBlank(appDescriptor.getIcon())) {
149 log.warn("Label and/or icon for app [{}] are blank. App won't be displayed in the app launcher. Please either define them in the configuration tree or in the app's i18n properties file.", entryDefinition.getName());
150 continue;
151 }
152
153 if (isAppVisibleForUser(entryDefinition, appDescriptor, user)) {
154 AppLauncherGroupEntry entry = new AppLauncherGroupEntry();
155 entry.setName(entryDefinition.getName());
156 entry.setEnabled(entryDefinition.isEnabled());
157 entry.setAppDescriptor(appDescriptor);
158 entries.add(entry);
159 }
160 }
161
162 if (!entries.isEmpty()) {
163 AppLauncherGroup group = new AppLauncherGroup();
164 group.setName(groupDefinition.getName());
165 group.setLabel(groupDefinition.getLabel());
166 group.setColor(groupDefinition.getColor());
167 group.setPermanent(groupDefinition.isPermanent());
168 group.setClientGroup(groupDefinition.isClientGroup());
169 group.setApps(entries);
170 layout.addGroup(group);
171 }
172 }
173 return layout;
174 }
175
176 @Override
177 public void setLayout(AppLauncherLayoutDefinition layout) {
178 this.layoutDefinitionReference.set(i18nizerProvider.get().decorate(layout));
179 sendChangedEvent();
180 }
181
182 private boolean isAppVisibleForUser(AppLauncherGroupEntryDefinition entry, AppDescriptor appDescriptor, User user) {
183 AccessDefinition permissions = appDescriptor.getPermissions();
184 return entry.isEnabled() && appDescriptor.isEnabled() && (permissions == null || permissions.hasAccess(user));
185 }
186
187 private boolean isGroupVisibleForUser(AppLauncherGroupDefinition group, User user) {
188 AccessDefinition permissions = group.getPermissions();
189 return (permissions == null || permissions.hasAccess(user));
190 }
191
192
193
194
195 private void sendChangedEvent() {
196 log.debug("Sending AppLauncherLayoutChangedEvent on the system bus");
197 systemEventBus.fireEvent(new AppLauncherLayoutChangedEvent());
198 }
199 }