]> git.argeo.org Git - gpl/argeo-suite.git/blob - ui/SuiteApp.java
Prepare next development cycle
[gpl/argeo-suite.git] / ui / SuiteApp.java
1 package org.argeo.app.ui;
2
3 import static org.argeo.api.cms.ux.CmsView.CMS_VIEW_UID_PROPERTY;
4
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Locale;
10 import java.util.Map;
11 import java.util.Objects;
12 import java.util.Set;
13 import java.util.TreeMap;
14 import java.util.TreeSet;
15
16 import javax.jcr.Node;
17 import javax.jcr.RepositoryException;
18 import javax.jcr.nodetype.NodeType;
19 import javax.xml.namespace.QName;
20
21 import org.argeo.api.acr.Content;
22 import org.argeo.api.acr.ContentRepository;
23 import org.argeo.api.acr.spi.ProvidedSession;
24 import org.argeo.api.cms.CmsConstants;
25 import org.argeo.api.cms.CmsEventSubscriber;
26 import org.argeo.api.cms.CmsLog;
27 import org.argeo.api.cms.CmsSession;
28 import org.argeo.api.cms.ux.CmsTheme;
29 import org.argeo.api.cms.ux.CmsUi;
30 import org.argeo.api.cms.ux.CmsView;
31 import org.argeo.app.api.EntityConstants;
32 import org.argeo.app.api.EntityNames;
33 import org.argeo.app.api.EntityType;
34 import org.argeo.app.api.RankedObject;
35 import org.argeo.cms.AbstractCmsApp;
36 import org.argeo.cms.CmsUserManager;
37 import org.argeo.cms.LocaleUtils;
38 import org.argeo.cms.Localized;
39 import org.argeo.cms.acr.ContentUtils;
40 import org.argeo.cms.jcr.CmsJcrUtils;
41 import org.argeo.cms.jcr.acr.JcrContent;
42 import org.argeo.cms.swt.CmsSwtUtils;
43 import org.argeo.cms.swt.acr.SwtUiProvider;
44 import org.argeo.cms.swt.dialogs.CmsFeedback;
45 import org.argeo.cms.ux.CmsUxUtils;
46 import org.argeo.eclipse.ui.specific.UiContext;
47 import org.argeo.jcr.JcrException;
48 import org.argeo.util.LangUtils;
49 import org.eclipse.swt.SWT;
50 import org.eclipse.swt.widgets.Composite;
51 import org.osgi.framework.Constants;
52 import org.osgi.service.useradmin.User;
53
54 /** The Argeo Suite App. */
55 public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber {
56 private final static CmsLog log = CmsLog.getLog(SuiteApp.class);
57
58 public final static String PUBLIC_BASE_PATH_PROPERTY = "publicBasePath";
59 public final static String DEFAULT_UI_NAME_PROPERTY = "defaultUiName";
60 public final static String DEFAULT_THEME_ID_PROPERTY = "defaultThemeId";
61 public final static String DEFAULT_LAYER_PROPERTY = "defaultLayer";
62 private final static String LOGIN = "login";
63 private final static String HOME_STATE = "~";
64
65 private String publicBasePath = null;
66
67 private String pidPrefix;
68 private String headerPid;
69 private String footerPid;
70 private String leadPanePid;
71 private String adminLeadPanePid;
72 private String loginScreenPid;
73
74 private String defaultUiName = "app";
75 private String adminUiName = "admin";
76
77 // FIXME such default names make refactoring more dangerous
78 @Deprecated
79 private String defaultLayerPid = "argeo.suite.ui.dashboardLayer";
80 @Deprecated
81 private String defaultThemeId = "org.argeo.app.theme.default";
82
83 private Map<String, RankedObject<SwtUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
84 private Map<String, RankedObject<SwtUiProvider>> uiProvidersByType = Collections.synchronizedMap(new HashMap<>());
85 private Map<String, RankedObject<SuiteLayer>> layersByPid = Collections.synchronizedSortedMap(new TreeMap<>());
86 private Map<String, RankedObject<SuiteLayer>> layersByType = Collections.synchronizedSortedMap(new TreeMap<>());
87
88 private CmsUserManager cmsUserManager;
89
90 // TODO make more optimal or via CmsSession/CmsView
91 private Map<String, SuiteUi> managedUis = new HashMap<>();
92
93 // ACR
94 private ContentRepository contentRepository;
95 // private JcrContentProvider jcrContentProvider;
96
97 // JCR
98 // private Repository repository;
99
100 public void init(Map<String, Object> properties) {
101 for (SuiteEvent event : SuiteEvent.values()) {
102 getCmsContext().getCmsEventBus().addEventSubscriber(event.topic(), this);
103 }
104
105 if (log.isDebugEnabled())
106 log.info("Argeo Suite App started");
107
108 if (properties.containsKey(DEFAULT_UI_NAME_PROPERTY))
109 defaultUiName = LangUtils.get(properties, DEFAULT_UI_NAME_PROPERTY);
110 if (properties.containsKey(DEFAULT_THEME_ID_PROPERTY))
111 defaultThemeId = LangUtils.get(properties, DEFAULT_THEME_ID_PROPERTY);
112 if (properties.containsKey(DEFAULT_LAYER_PROPERTY))
113 defaultLayerPid = LangUtils.get(properties, DEFAULT_LAYER_PROPERTY);
114 publicBasePath = LangUtils.get(properties, PUBLIC_BASE_PATH_PROPERTY);
115
116 if (properties.containsKey(Constants.SERVICE_PID)) {
117 String servicePid = properties.get(Constants.SERVICE_PID).toString();
118 if (servicePid.endsWith(".app")) {
119 pidPrefix = servicePid.substring(0, servicePid.length() - "app".length());
120 }
121 }
122
123 if (pidPrefix == null)
124 throw new IllegalArgumentException("PID prefix must be set.");
125
126 headerPid = pidPrefix + "header";
127 footerPid = pidPrefix + "footer";
128 leadPanePid = pidPrefix + "leadPane";
129 adminLeadPanePid = pidPrefix + "adminLeadPane";
130 loginScreenPid = pidPrefix + "loginScreen";
131 }
132
133 public void destroy(Map<String, Object> properties) {
134 for (SuiteUi ui : managedUis.values())
135 if (!ui.isDisposed()) {
136 ui.getDisplay().syncExec(() -> ui.dispose());
137 }
138 if (log.isDebugEnabled())
139 log.info("Argeo Suite App stopped");
140
141 }
142
143 @Override
144 public Set<String> getUiNames() {
145 HashSet<String> uiNames = new HashSet<>();
146 uiNames.add(defaultUiName);
147 uiNames.add(adminUiName);
148 return uiNames;
149 }
150
151 @Override
152 public CmsUi initUi(Object parent) {
153 Composite uiParent = (Composite) parent;
154 String uiName = uiParent.getData(UI_NAME_PROPERTY) != null ? uiParent.getData(UI_NAME_PROPERTY).toString()
155 : null;
156 CmsView cmsView = CmsSwtUtils.getCmsView(uiParent);
157 if (cmsView == null)
158 throw new IllegalStateException("No CMS view is registered.");
159 CmsTheme theme = getTheme(uiName);
160 if (theme != null)
161 CmsSwtUtils.registerCmsTheme(uiParent.getShell(), theme);
162 SuiteUi argeoSuiteUi = new SuiteUi(uiParent, SWT.INHERIT_DEFAULT);
163 String uid = cmsView.getUid();
164 managedUis.put(uid, argeoSuiteUi);
165 argeoSuiteUi.addDisposeListener((e) -> {
166 managedUis.remove(uid);
167 if (log.isDebugEnabled())
168 log.debug("Suite UI " + uid + " has been disposed.");
169 });
170 return argeoSuiteUi;
171 }
172
173 @Override
174 public String getThemeId(String uiName) {
175 String themeId = System.getProperty("org.argeo.app.theme.default");
176 if (themeId != null)
177 return themeId;
178 return defaultThemeId;
179 }
180
181 @Override
182 public void refreshUi(CmsUi cmsUi, String state) {
183 try {
184 Content context = null;
185 SuiteUi ui = (SuiteUi) cmsUi;
186
187 String uiName = Objects.toString(ui.getParent().getData(UI_NAME_PROPERTY), null);
188 if (uiName == null)
189 throw new IllegalStateException("UI name should not be null");
190 CmsView cmsView = CmsSwtUtils.getCmsView(ui);
191
192 ProvidedSession contentSession = (ProvidedSession) CmsUxUtils.getContentSession(contentRepository, cmsView);
193
194 SwtUiProvider headerUiProvider = findUiProvider(headerPid);
195 SwtUiProvider footerUiProvider = findUiProvider(footerPid);
196 SwtUiProvider leadPaneUiProvider;
197 if (adminUiName.equals(uiName)) {
198 leadPaneUiProvider = findUiProvider(adminLeadPanePid);
199 } else {
200 leadPaneUiProvider = findUiProvider(leadPanePid);
201 }
202
203 Localized appTitle = null;
204 if (headerUiProvider instanceof DefaultHeader) {
205 appTitle = ((DefaultHeader) headerUiProvider).getTitle();
206 }
207 ui.setTitle(appTitle);
208
209 if (cmsView.isAnonymous() && publicBasePath == null) {// internal app, must login
210 ui.logout();
211 if (headerUiProvider != null)
212 refreshPart(headerUiProvider, ui.getHeader(), context);
213 ui.refreshBelowHeader(false);
214 refreshPart(findUiProvider(loginScreenPid), ui.getBelowHeader(), context);
215 if (footerUiProvider != null)
216 refreshPart(footerUiProvider, ui.getFooter(), context);
217 ui.layout(true, true);
218 setState(ui, LOGIN);
219 } else {
220 if (LOGIN.equals(state))
221 state = null;
222 CmsSession cmsSession = cmsView.getCmsSession();
223 if (ui.getUserDirNode() == null) {
224 // FIXME NPE on CMSSession when logging in from anonymous
225 if (cmsSession == null || cmsView.isAnonymous()) {
226 assert publicBasePath != null;
227 Content userDir = contentSession
228 .get(ContentUtils.SLASH + CmsConstants.SYS_WORKSPACE + publicBasePath);
229 ui.setUserDir(userDir);
230 // ui.initSessions(getRepository(), publicBasePath);
231 } else {
232 // Session adminSession = null;
233 // try {
234 // adminSession = CmsJcrUtils.openDataAdminSession(getRepository(), null);
235 // Node userDirNode = SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
236 // Content userDir = contentSession.get(CmsConstants.SYS_WORKSPACE + userDirNode.getPath());
237 // ui.setUserDir(userDir);
238 //// ui.initSessions(getRepository(), userDirNode.getPath());
239 // } finally {
240 // Jcr.logout(adminSession);
241 // }
242 Content userDir = contentSession.getSessionRunDir();
243 ui.setUserDir(userDir);
244 }
245 }
246 initLocale(cmsSession);
247 context = stateToNode(ui, state);
248 if (context == null)
249 context = ui.getUserDirNode();
250
251 if (headerUiProvider != null)
252 refreshPart(headerUiProvider, ui.getHeader(), context);
253 ui.refreshBelowHeader(true);
254 for (String key : layersByPid.keySet()) {
255 SuiteLayer layer = layersByPid.get(key).get();
256 ui.addLayer(key, layer);
257 }
258
259 if (leadPaneUiProvider != null)
260 refreshPart(leadPaneUiProvider, ui.getLeadPane(), context);
261 if (footerUiProvider != null)
262 refreshPart(footerUiProvider, ui.getFooter(), context);
263 ui.layout(true, true);
264 setState(ui, state != null ? state : defaultLayerPid);
265 }
266 } catch (Exception e) {
267 CmsFeedback.show("Unexpected exception", e);
268 }
269 }
270
271 private void initLocale(CmsSession cmsSession) {
272 if (cmsSession == null)
273 return;
274 Locale locale = cmsSession.getLocale();
275 UiContext.setLocale(locale);
276 LocaleUtils.setThreadLocale(locale);
277
278 }
279
280 private void refreshPart(SwtUiProvider uiProvider, Composite part, Content context) {
281 CmsSwtUtils.clear(part);
282 uiProvider.createUiPart(part, context);
283 }
284
285 private SwtUiProvider findUiProvider(String pid) {
286 if (!uiProvidersByPid.containsKey(pid))
287 return null;
288 return uiProvidersByPid.get(pid).get();
289 }
290
291 private SuiteLayer findLayer(String pid) {
292 if (!layersByPid.containsKey(pid))
293 return null;
294 return layersByPid.get(pid).get();
295 }
296
297 private <T> T findByType(Map<String, RankedObject<T>> byType, Content content) {
298 if (content == null)
299 throw new IllegalArgumentException("A node should be provided");
300
301 if (content instanceof JcrContent) {
302 Node context = ((JcrContent) content).getJcrNode();
303 try {
304 // mixins
305 Set<String> types = new TreeSet<>();
306 for (NodeType mixinType : context.getMixinNodeTypes()) {
307 String mixinTypeName = mixinType.getName();
308 if (byType.containsKey(mixinTypeName)) {
309 types.add(mixinTypeName);
310 }
311 for (NodeType superType : mixinType.getDeclaredSupertypes()) {
312 if (byType.containsKey(superType.getName())) {
313 types.add(superType.getName());
314 }
315 }
316 }
317 // primary node type
318 NodeType primaryType = context.getPrimaryNodeType();
319 String primaryTypeName = primaryType.getName();
320 if (byType.containsKey(primaryTypeName)) {
321 types.add(primaryTypeName);
322 }
323 for (NodeType superType : primaryType.getDeclaredSupertypes()) {
324 if (byType.containsKey(superType.getName())) {
325 types.add(superType.getName());
326 }
327 }
328 // entity type
329 if (context.isNodeType(EntityType.entity.get())) {
330 if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
331 String entityTypeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
332 if (byType.containsKey(entityTypeName)) {
333 types.add(entityTypeName);
334 }
335 }
336 }
337
338 // if (context.getPath().equals("/")) {// root node
339 // types.add("nt:folder");
340 // }
341 if (CmsJcrUtils.isUserHome(context) && byType.containsKey("nt:folder")) {// home node
342 types.add("nt:folder");
343 }
344
345 if (types.size() == 0)
346 throw new IllegalArgumentException(
347 "No type found for " + context + " (" + listTypes(context) + ")");
348 String type = types.iterator().next();
349 if (!byType.containsKey(type))
350 throw new IllegalArgumentException("No component found for " + context + " with type " + type);
351 return byType.get(type).get();
352 } catch (RepositoryException e) {
353 throw new IllegalStateException(e);
354 }
355
356 } else {
357
358 List<QName> objectClasses = content.getContentClasses();
359 Set<String> types = new TreeSet<>();
360 for (QName cc : objectClasses) {
361 String type = cc.getPrefix() + ":" + cc.getLocalPart();
362 if (byType.containsKey(type))
363 types.add(type);
364 }
365 if (types.size() == 0)
366 throw new IllegalArgumentException("No type found for " + content + " (" + objectClasses + ")");
367 String type = types.iterator().next();
368 if (!byType.containsKey(type))
369 throw new IllegalArgumentException("No component found for " + content + " with type " + type);
370 return byType.get(type).get();
371 // throw new UnsupportedOperationException("Content " +
372 // content.getClass().getName() + " is not supported.");
373 }
374 }
375
376 private static String listTypes(Node context) {
377 try {
378 StringBuilder sb = new StringBuilder();
379 sb.append(context.getPrimaryNodeType().getName());
380 for (NodeType superType : context.getPrimaryNodeType().getDeclaredSupertypes()) {
381 sb.append(' ');
382 sb.append(superType.getName());
383 }
384
385 for (NodeType nodeType : context.getMixinNodeTypes()) {
386 sb.append(' ');
387 sb.append(nodeType.getName());
388 if (nodeType.getName().equals(EntityType.local.get()))
389 sb.append('/').append(context.getProperty(EntityNames.ENTITY_TYPE).getString());
390 for (NodeType superType : nodeType.getDeclaredSupertypes()) {
391 sb.append(' ');
392 sb.append(superType.getName());
393 }
394 }
395 return sb.toString();
396 } catch (RepositoryException e) {
397 throw new JcrException(e);
398 }
399 }
400
401 @Override
402 public void setState(CmsUi cmsUi, String state) {
403 if (state == null)
404 return;
405 if (!state.startsWith("/")) {
406 if (cmsUi instanceof SuiteUi) {
407 SuiteUi ui = (SuiteUi) cmsUi;
408 if (LOGIN.equals(state)) {
409 String appTitle = "";
410 if (ui.getTitle() != null)
411 appTitle = ui.getTitle().lead();
412 ui.getCmsView().stateChanged(state, appTitle);
413 return;
414 }
415 Map<String, Object> properties = new HashMap<>();
416 String layerId = HOME_STATE.equals(state) ? defaultLayerPid : state;
417 properties.put(SuiteEvent.LAYER, layerId);
418 properties.put(SuiteEvent.NODE_PATH, HOME_STATE);
419 ui.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), properties);
420 }
421 return;
422 }
423 SuiteUi suiteUi = (SuiteUi) cmsUi;
424 Content node = stateToNode(suiteUi, state);
425 if (node == null) {
426 suiteUi.getCmsView().navigateTo(HOME_STATE);
427 } else {
428 suiteUi.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
429 suiteUi.getCmsView().sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
430 }
431 }
432
433 // TODO move it to an internal package?
434 static String nodeToState(Content node) {
435 return node.getPath();
436 }
437
438 private Content stateToNode(SuiteUi suiteUi, String state) {
439 if (suiteUi == null)
440 return null;
441 if (state == null || !state.startsWith("/"))
442 return null;
443
444 String path = state;
445 // String path = state.substring(1);
446 // String workspace;
447 // if (path.equals("")) {
448 // workspace = null;
449 // path = "/";
450 // } else {
451 // int index = path.indexOf('/');
452 // if (index == 0) {
453 // log.error("Cannot interpret " + state);
454 //// cmsView.navigateTo("~");
455 // return null;
456 // } else if (index > 0) {
457 // workspace = path.substring(0, index);
458 // path = path.substring(index);
459 // } else {// index<0, assuming root node
460 // workspace = path;
461 // path = "/";
462 // }
463 // }
464
465 ProvidedSession contentSession = (ProvidedSession) CmsUxUtils.getContentSession(contentRepository,
466 suiteUi.getCmsView());
467 return contentSession.get(path);
468 // Session session = jcrContentProvider.getJcrSession(contentSession, workspace);
469 //// Session session = suiteUi.getSession(workspace);
470 // if (session == null)
471 // return null;
472 // Node node = Jcr.getNode(session, path);
473 // return node;
474 }
475
476 /*
477 * Events management
478 */
479
480 @Override
481 public void onEvent(String topic, Map<String, Object> event) {
482
483 // Specific UI related events
484 SuiteUi ui = getRelatedUi(event);
485 if (ui == null)
486 return;
487 ui.getCmsView().runAs(() -> {
488 try {
489 String appTitle = "";
490 if (ui.getTitle() != null)
491 appTitle = ui.getTitle().lead() + " - ";
492
493 // String currentLayerId = ui.getCurrentLayerId();
494 // SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null;
495 if (SuiteUiUtils.isTopic(topic, SuiteEvent.refreshPart)) {
496 Content node = getNode(ui, event);
497 if (node == null)
498 return;
499 SwtUiProvider uiProvider = findByType(uiProvidersByType, node);
500 SuiteLayer layer = findByType(layersByType, node);
501 ui.switchToLayer(layer, node);
502 layer.view(uiProvider, ui.getCurrentWorkArea(), node);
503 ui.getCmsView().stateChanged(nodeToState(node), appTitle + CmsUxUtils.getTitle(node));
504 } else if (SuiteUiUtils.isTopic(topic, SuiteEvent.openNewPart)) {
505 Content node = getNode(ui, event);
506 if (node == null)
507 return;
508 SwtUiProvider uiProvider = findByType(uiProvidersByType, node);
509 SuiteLayer layer = findByType(layersByType, node);
510 ui.switchToLayer(layer, node);
511 layer.open(uiProvider, ui.getCurrentWorkArea(), node);
512 ui.getCmsView().stateChanged(nodeToState(node), appTitle + CmsUxUtils.getTitle(node));
513 } else if (SuiteUiUtils.isTopic(topic, SuiteEvent.switchLayer)) {
514 String layerId = get(event, SuiteEvent.LAYER);
515 if (layerId != null) {
516 // ui.switchToLayer(layerId, ui.getUserDir());
517 SuiteLayer suiteLayer = findLayer(layerId);
518 if (suiteLayer == null)
519 throw new IllegalArgumentException("No layer '" + layerId + "' available.");
520 Localized layerTitle = suiteLayer.getTitle();
521 // FIXME make sure we don't rebuild the work area twice
522 Composite workArea = ui.switchToLayer(layerId, ui.getUserDirNode());
523 String title = null;
524 if (layerTitle != null)
525 title = layerTitle.lead();
526 Content nodeFromState = getNode(ui, event);
527 if (nodeFromState != null && nodeFromState.getPath().equals(ui.getUserDirNode().getPath())) {
528 // default layer view is forced
529 String state = defaultLayerPid.equals(layerId) ? "~" : layerId;
530 ui.getCmsView().stateChanged(state, appTitle + title);
531 suiteLayer.view(null, workArea, nodeFromState);
532 } else {
533 Content layerCurrentContext = suiteLayer.getCurrentContext(workArea);
534 if (layerCurrentContext != null) {
535 // layer was already showing a context so we set the state to it
536 ui.getCmsView().stateChanged(nodeToState(layerCurrentContext),
537 appTitle + CmsUxUtils.getTitle(layerCurrentContext));
538 } else {
539 // no context was shown
540 ui.getCmsView().stateChanged(layerId, appTitle + title);
541 }
542 }
543 } else {
544 Content node = getNode(ui, event);
545 if (node != null) {
546 SuiteLayer layer = findByType(layersByType, node);
547 ui.switchToLayer(layer, node);
548 }
549 }
550 }
551 } catch (Exception e) {
552 log.error("Cannot handle event " + event, e);
553 // CmsView.getCmsView(ui).exception(e);
554 }
555 });
556 }
557
558 private Content getNode(SuiteUi ui, Map<String, Object> event) {
559 ProvidedSession contentSession = (ProvidedSession) CmsUxUtils.getContentSession(contentRepository,
560 ui.getCmsView());
561
562 String path = get(event, SuiteEvent.CONTENT_PATH);
563
564 // String nodePath = get(event, SuiteEvent.NODE_PATH);
565 if (path != null && path.equals(HOME_STATE))
566 return ui.getUserDir();
567 // String workspace = get(event, SuiteEvent.WORKSPACE);
568
569 // Session session = jcrContentProvider.getJcrSession(contentSession, workspace);
570 //// Session session = ui.getSession(workspace);
571 Content node;
572 if (path == null) {
573 // look for a user
574 String username = get(event, SuiteEvent.USERNAME);
575 if (username == null)
576 return null;
577 User user = cmsUserManager.getUser(username);
578 if (user == null)
579 return null;
580 node = ContentUtils.roleToContent(cmsUserManager, contentSession, user);
581 // LdapName userDn;
582 // try {
583 // userDn = new LdapName(user.getName());
584 // } catch (InvalidNameException e) {
585 // throw new IllegalArgumentException("Badly formatted username", e);
586 // }
587 // String userNodePath = SuiteUtils.getUserNodePath(userDn);
588 // FIXME deal with home path
589 // return null;
590 // if (Jcr.itemExists(session, userNodePath))
591 // node = Jcr.getNode(session, userNodePath);
592 // else {
593 // Session adminSession = null;
594 // try {
595 // adminSession = CmsJcrUtils.openDataAdminSession(getRepository(), workspace);
596 // SuiteUtils.getOrCreateUserNode(adminSession, userDn);
597 // } finally {
598 // Jcr.logout(adminSession);
599 // }
600 // node = Jcr.getNode(session, userNodePath);
601 // }
602 } else {
603 node = contentSession.get(path);
604 }
605 return node;
606 }
607
608 private SuiteUi getRelatedUi(Map<String, Object> eventProperties) {
609 return managedUis.get(get(eventProperties, CMS_VIEW_UID_PROPERTY));
610 }
611
612 public static String get(Map<String, Object> eventProperties, String key) {
613 Object value = eventProperties.get(key);
614 if (value == null)
615 return null;
616 // throw new IllegalArgumentException("Property " + key + " must be set");
617 return value.toString();
618
619 }
620
621 /*
622 * Dependency injection.
623 */
624
625 public void addUiProvider(SwtUiProvider uiProvider, Map<String, Object> properties) {
626 if (properties.containsKey(Constants.SERVICE_PID)) {
627 String pid = (String) properties.get(Constants.SERVICE_PID);
628 RankedObject.putIfHigherRank(uiProvidersByPid, pid, uiProvider, properties);
629 }
630 if (properties.containsKey(EntityConstants.TYPE)) {
631 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
632 for (String type : types)
633 RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties);
634 }
635 }
636
637 public void removeUiProvider(SwtUiProvider uiProvider, Map<String, Object> properties) {
638 if (properties.containsKey(Constants.SERVICE_PID)) {
639 String pid = (String) properties.get(Constants.SERVICE_PID);
640 if (uiProvidersByPid.containsKey(pid)) {
641 if (uiProvidersByPid.get(pid).equals(new RankedObject<SwtUiProvider>(uiProvider, properties))) {
642 uiProvidersByPid.remove(pid);
643 }
644 }
645 }
646 if (properties.containsKey(EntityConstants.TYPE)) {
647 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
648 for (String type : types) {
649 if (uiProvidersByType.containsKey(type)) {
650 if (uiProvidersByType.get(type).equals(new RankedObject<SwtUiProvider>(uiProvider, properties))) {
651 uiProvidersByType.remove(type);
652 }
653 }
654 }
655 }
656 }
657
658 public void addLayer(SuiteLayer layer, Map<String, Object> properties) {
659 if (properties.containsKey(Constants.SERVICE_PID)) {
660 String pid = (String) properties.get(Constants.SERVICE_PID);
661 RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
662 }
663 if (properties.containsKey(EntityConstants.TYPE)) {
664 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
665 for (String type : types)
666 RankedObject.putIfHigherRank(layersByType, type, layer, properties);
667 }
668 }
669
670 public void removeLayer(SuiteLayer layer, Map<String, Object> properties) {
671 if (properties.containsKey(Constants.SERVICE_PID)) {
672 String pid = (String) properties.get(Constants.SERVICE_PID);
673 if (layersByPid.containsKey(pid)) {
674 if (layersByPid.get(pid).equals(new RankedObject<SuiteLayer>(layer, properties))) {
675 layersByPid.remove(pid);
676 }
677 }
678 }
679 if (properties.containsKey(EntityConstants.TYPE)) {
680 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
681 for (String type : types) {
682 if (layersByType.containsKey(type)) {
683 if (layersByType.get(type).equals(new RankedObject<SuiteLayer>(layer, properties))) {
684 layersByType.remove(type);
685 }
686 }
687 }
688 }
689 }
690
691 public void setCmsUserManager(CmsUserManager cmsUserManager) {
692 this.cmsUserManager = cmsUserManager;
693 }
694
695 // protected Repository getRepository() {
696 // return repository;
697 // }
698 //
699 // public void setRepository(Repository repository) {
700 // this.repository = repository;
701 // }
702
703 protected ContentRepository getContentRepository() {
704 return contentRepository;
705 }
706
707 public void setContentRepository(ContentRepository contentRepository) {
708 this.contentRepository = contentRepository;
709 }
710
711 // public void setJcrContentProvider(JcrContentProvider jcrContentProvider) {
712 // this.jcrContentProvider = jcrContentProvider;
713 // }
714
715 }