1 package org
.argeo
.app
.swt
.ux
;
3 import static org
.argeo
.api
.cms
.ux
.CmsView
.CMS_VIEW_UID_PROPERTY
;
5 import java
.util
.Collections
;
6 import java
.util
.HashMap
;
7 import java
.util
.HashSet
;
9 import java
.util
.Locale
;
11 import java
.util
.Objects
;
13 import java
.util
.TreeMap
;
14 import java
.util
.TreeSet
;
16 import javax
.xml
.namespace
.QName
;
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
;
50 /** The Argeo Suite App. */
51 public class SwtArgeoApp
extends AbstractArgeoApp
implements CmsEventSubscriber
{
52 private final static CmsLog log
= CmsLog
.getLog(SwtArgeoApp
.class);
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
= "~";
61 private String publicBasePath
= null;
63 private String pidPrefix
;
64 private String headerPid
;
65 private String footerPid
;
66 private String leadPanePid
;
67 private String adminLeadPanePid
;
68 private String loginScreenPid
;
70 private String defaultUiName
= "app";
71 private String adminUiName
= "admin";
73 // FIXME such default names make refactoring more dangerous
75 private String defaultLayerPid
= "argeo.suite.ui.dashboardLayer";
77 private String defaultThemeId
= "org.argeo.app.theme.default";
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
<>());
85 // private CmsUserManager cmsUserManager;
87 // TODO make more optimal or via CmsSession/CmsView
88 private Map
<String
, SwtAppUi
> managedUis
= new HashMap
<>();
91 private ContentRepository contentRepository
;
92 private AppUserState appUserState
;
94 // private Repository repository;
96 public void init(Map
<String
, Object
> properties
) {
97 for (SuiteUxEvent event
: SuiteUxEvent
.values()) {
98 getCmsContext().getCmsEventBus().addEventSubscriber(event
.topic(), this);
101 if (log
.isDebugEnabled())
102 log
.info("Argeo Suite App started");
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
);
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());
119 if (pidPrefix
== null)
120 throw new IllegalArgumentException("PID prefix must be set.");
122 headerPid
= pidPrefix
+ "header";
123 footerPid
= pidPrefix
+ "footer";
124 leadPanePid
= pidPrefix
+ "leadPane";
125 adminLeadPanePid
= pidPrefix
+ "adminLeadPane";
126 loginScreenPid
= pidPrefix
+ "loginScreen";
129 public void destroy(Map
<String
, Object
> properties
) {
130 for (SwtAppUi ui
: managedUis
.values())
131 if (!ui
.isDisposed()) {
132 ui
.getDisplay().syncExec(() -> ui
.dispose());
134 if (log
.isDebugEnabled())
135 log
.info("Argeo Suite App stopped");
140 public Set
<String
> getUiNames() {
141 HashSet
<String
> uiNames
= new HashSet
<>();
142 uiNames
.add(defaultUiName
);
143 uiNames
.add(adminUiName
);
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()
152 CmsView cmsView
= CmsSwtUtils
.getCmsView(uiParent
);
154 throw new IllegalStateException("No CMS view is registered.");
155 CmsTheme theme
= getTheme(uiName
);
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.");
170 public String
getThemeId(String uiName
) {
171 String themeId
= System
.getProperty("org.argeo.app.theme.default");
174 return defaultThemeId
;
178 public void refreshUi(CmsUi cmsUi
, String state
) {
180 Content context
= null;
181 SwtAppUi ui
= (SwtAppUi
) cmsUi
;
183 String uiName
= Objects
.toString(ui
.getParent().getData(UI_NAME_PROPERTY
), null);
185 throw new IllegalStateException("UI name should not be null");
186 CmsView cmsView
= CmsSwtUtils
.getCmsView(ui
);
188 ProvidedSession contentSession
= (ProvidedSession
) CmsUxUtils
.getContentSession(contentRepository
, cmsView
);
190 SwtUiProvider headerUiProvider
= findUiProvider(headerPid
);
191 SwtUiProvider footerUiProvider
= findUiProvider(footerPid
);
192 SwtUiProvider leadPaneUiProvider
;
193 if (adminUiName
.equals(uiName
)) {
194 leadPaneUiProvider
= findUiProvider(adminLeadPanePid
);
196 leadPaneUiProvider
= findUiProvider(leadPanePid
);
199 Localized appTitle
= null;
200 if (headerUiProvider
instanceof DefaultHeader
) {
201 appTitle
= ((DefaultHeader
) headerUiProvider
).getTitle();
203 ui
.setTitle(appTitle
);
205 if (cmsView
.isAnonymous() && publicBasePath
== null) {// internal app, must login
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);
217 if (LOGIN
.equals(state
))
219 if (ui
.isLoginScreen()) {
220 ui
.setLoginScreen(false);
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
);
231 Content userDir
= appUserState
.getOrCreateSessionDir(contentSession
, cmsSession
);
232 ui
.setUserDir(userDir
);
233 // Node userDirNode = jcrContentProvider.doInAdminSession((adminSession) -> {
234 // Node node = SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
237 // Content userDir = contentSession
238 // .get(ContentUtils.SLASH + CmsConstants.SYS_WORKSPACE + userDirNode.getPath());
239 // ui.setUserDir(userDir);
242 initLocale(cmsSession
);
243 context
= stateToNode(ui
, state
);
245 context
= ui
.getUserDir();
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
);
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
);
262 } catch (Exception e
) {
263 CmsFeedback
.error("Unexpected exception", e
);
267 private void initLocale(CmsSession cmsSession
) {
268 if (cmsSession
== null)
270 Locale locale
= cmsSession
.getLocale();
271 UiContext
.setLocale(locale
);
272 LocaleUtils
.setThreadLocale(locale
);
276 private void refreshPart(SwtUiProvider uiProvider
, Composite part
, Content context
) {
277 CmsSwtUtils
.clear(part
);
278 uiProvider
.createUiPart(part
, context
);
281 private SwtUiProvider
findUiProvider(String pid
) {
282 if (!uiProvidersByPid
.containsKey(pid
))
284 return uiProvidersByPid
.get(pid
).get();
287 private SwtAppLayer
findLayer(String pid
) {
288 if (!layersByPid
.containsKey(pid
))
290 return layersByPid
.get(pid
).get();
293 private <T
> T
findByType(Map
<String
, RankedObject
<T
>> byType
, Content content
) {
295 throw new IllegalArgumentException("A node should be provided");
297 // boolean checkJcr = false;
298 // if (checkJcr && content instanceof JcrContent) {
299 // Node context = ((JcrContent) content).getJcrNode();
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);
308 // for (NodeType superType : mixinType.getDeclaredSupertypes()) {
309 // if (byType.containsKey(superType.getName())) {
310 // types.add(superType.getName());
314 // // primary node type
315 // NodeType primaryType = context.getPrimaryNodeType();
316 // String primaryTypeName = primaryType.getName();
317 // if (byType.containsKey(primaryTypeName)) {
318 // types.add(primaryTypeName);
320 // for (NodeType superType : primaryType.getDeclaredSupertypes()) {
321 // if (byType.containsKey(superType.getName())) {
322 // types.add(superType.getName());
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);
335 // if (CmsJcrUtils.isUserHome(context) && byType.containsKey("nt:folder")) {// home node
336 // types.add("nt:folder");
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);
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
))
358 List
<QName
> objectClasses
= content
.getContentClasses();
359 for (QName cc
: objectClasses
) {
360 String type
= cc
.getPrefix() + ":" + cc
.getLocalPart();
361 if (byType
.containsKey(type
))
364 if (types
.size() == 0) {
365 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();
374 // private static String listTypes(Node context) {
376 // StringBuilder sb = new StringBuilder();
377 // sb.append(context.getPrimaryNodeType().getName());
378 // for (NodeType superType : context.getPrimaryNodeType().getDeclaredSupertypes()) {
380 // sb.append(superType.getName());
383 // for (NodeType nodeType : context.getMixinNodeTypes()) {
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()) {
390 // sb.append(superType.getName());
393 // return sb.toString();
394 // } catch (RepositoryException e) {
395 // throw new JcrException(e);
400 public void setState(CmsUi cmsUi
, String state
) {
401 AppUi ui
= (AppUi
) cmsUi
;
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
);
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
);
422 // SwtAppUi suiteUi = (SwtAppUi) cmsUi;
423 if (ui
.isLoginScreen()) {
427 Content node
= stateToNode(ui
, state
);
429 ui
.getCmsView().navigateTo(HOME_STATE
);
431 ui
.getCmsView().sendEvent(SuiteUxEvent
.switchLayer
.topic(), SuiteUxEvent
.eventProperties(node
));
432 ui
.getCmsView().sendEvent(SuiteUxEvent
.refreshPart
.topic(), SuiteUxEvent
.eventProperties(node
));
436 // TODO move it to an internal package?
437 public static String
nodeToState(Content node
) {
438 return node
.getPath();
441 private Content
stateToNode(CmsUi suiteUi
, String state
) {
444 if (state
== null || !state
.startsWith("/"))
449 ProvidedSession contentSession
= (ProvidedSession
) CmsUxUtils
.getContentSession(contentRepository
,
450 suiteUi
.getCmsView());
451 return contentSession
.get(path
);
459 public void onEvent(String topic
, Map
<String
, Object
> event
) {
461 // Specific UI related events
462 SwtAppUi ui
= getRelatedUi(event
);
465 ui
.getCmsView().runAs(() -> {
467 String appTitle
= "";
468 if (ui
.getTitle() != null)
469 appTitle
= ui
.getTitle().lead() + " - ";
471 if (isTopic(topic
, SuiteUxEvent
.refreshPart
)) {
472 Content node
= getContentFromEvent(ui
, event
);
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
);
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());
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
);
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
));
514 // no context was shown
515 ui
.getCmsView().stateChanged(layerId
, appTitle
+ title
);
519 Content node
= getContentFromEvent(ui
, event
);
521 SwtAppLayer layer
= findByType(layersByType
, node
);
522 ui
.switchToLayer(layer
, node
);
526 } catch (Exception e
) {
527 CmsFeedback
.error("Cannot handle event " + topic
+ " " + event
, e
);
528 // log.error("Cannot handle event " + event, e);
533 private boolean isTopic(String topic
, CmsEvent cmsEvent
) {
534 Objects
.requireNonNull(topic
);
535 return topic
.equals(cmsEvent
.topic());
538 protected Content
getContentFromEvent(SwtAppUi ui
, Map
<String
, Object
> event
) {
539 ProvidedSession contentSession
= (ProvidedSession
) CmsUxUtils
.getContentSession(contentRepository
,
542 String path
= get(event
, SuiteUxEvent
.CONTENT_PATH
);
544 if (path
!= null && (path
.equals(HOME_STATE
) || path
.equals("")))
545 return ui
.getUserDir();
549 // // look for a user
550 // String username = get(event, SuiteUxEvent.USERNAME);
551 // if (username == null)
553 // User user = cmsUserManager.getUser(username);
556 // node = ContentUtils.roleToContent(cmsUserManager, contentSession, user);
558 node
= contentSession
.get(path
);
563 private SwtAppUi
getRelatedUi(Map
<String
, Object
> eventProperties
) {
564 return managedUis
.get(get(eventProperties
, CMS_VIEW_UID_PROPERTY
));
567 public static String
get(Map
<String
, Object
> eventProperties
, String key
) {
568 Object value
= eventProperties
.get(key
);
571 return value
.toString();
576 * Dependency injection.
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
646 // public void setCmsUserManager(CmsUserManager cmsUserManager) {
647 // this.cmsUserManager = cmsUserManager;
650 // protected ContentRepository getContentRepository() {
651 // return contentRepository;
654 public void setContentRepository(ContentRepository contentRepository
) {
655 this.contentRepository
= contentRepository
;
658 public void setAppUserState(AppUserState appUserState
) {
659 this.appUserState
= appUserState
;