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