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