1 package org
.argeo
.app
.ui
;
3 import static org
.argeo
.api
.cms
.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
.jcr
.Node
;
17 import javax
.jcr
.Repository
;
18 import javax
.jcr
.RepositoryException
;
19 import javax
.jcr
.Session
;
20 import javax
.jcr
.nodetype
.NodeType
;
21 import javax
.naming
.InvalidNameException
;
22 import javax
.naming
.ldap
.LdapName
;
24 import org
.argeo
.api
.acr
.Content
;
25 import org
.argeo
.api
.acr
.ContentRepository
;
26 import org
.argeo
.api
.acr
.ContentSession
;
27 import org
.argeo
.api
.acr
.spi
.ProvidedSession
;
28 import org
.argeo
.api
.cms
.CmsConstants
;
29 import org
.argeo
.api
.cms
.CmsLog
;
30 import org
.argeo
.api
.cms
.CmsSession
;
31 import org
.argeo
.api
.cms
.CmsTheme
;
32 import org
.argeo
.api
.cms
.CmsUi
;
33 import org
.argeo
.api
.cms
.CmsView
;
34 import org
.argeo
.app
.api
.EntityConstants
;
35 import org
.argeo
.app
.api
.EntityNames
;
36 import org
.argeo
.app
.api
.EntityType
;
37 import org
.argeo
.app
.api
.RankedObject
;
38 import org
.argeo
.app
.core
.SuiteUtils
;
39 import org
.argeo
.cms
.AbstractCmsApp
;
40 import org
.argeo
.cms
.CmsUserManager
;
41 import org
.argeo
.cms
.LocaleUtils
;
42 import org
.argeo
.cms
.Localized
;
43 import org
.argeo
.cms
.jcr
.CmsJcrUtils
;
44 import org
.argeo
.cms
.jcr
.acr
.JcrContent
;
45 import org
.argeo
.cms
.jcr
.acr
.JcrContentProvider
;
46 import org
.argeo
.cms
.swt
.CmsSwtUtils
;
47 import org
.argeo
.cms
.swt
.dialogs
.CmsFeedback
;
48 import org
.argeo
.cms
.ui
.CmsUiProvider
;
49 import org
.argeo
.cms
.ux
.CmsUxUtils
;
50 import org
.argeo
.eclipse
.ui
.specific
.UiContext
;
51 import org
.argeo
.jcr
.Jcr
;
52 import org
.argeo
.jcr
.JcrException
;
53 import org
.argeo
.util
.LangUtils
;
54 import org
.eclipse
.swt
.SWT
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.osgi
.framework
.Constants
;
57 import org
.osgi
.service
.event
.Event
;
58 import org
.osgi
.service
.event
.EventHandler
;
59 import org
.osgi
.service
.useradmin
.User
;
61 /** The Argeo Suite App. */
62 public class SuiteApp
extends AbstractCmsApp
implements EventHandler
{
63 private final static CmsLog log
= CmsLog
.getLog(SuiteApp
.class);
65 public final static String PUBLIC_BASE_PATH_PROPERTY
= "publicBasePath";
66 public final static String DEFAULT_UI_NAME_PROPERTY
= "defaultUiName";
67 public final static String DEFAULT_THEME_ID_PROPERTY
= "defaultThemeId";
68 public final static String DEFAULT_LAYER_PROPERTY
= "defaultLayer";
69 private final static String LOGIN
= "login";
70 private final static String HOME_STATE
= "~";
72 private String publicBasePath
= null;
74 private String pidPrefix
;
75 private String headerPid
;
76 private String footerPid
;
77 private String leadPanePid
;
78 private String adminLeadPanePid
;
79 private String loginScreenPid
;
81 private String defaultUiName
= "app";
82 private String adminUiName
= "admin";
84 // FIXME such default names make refactoring more dangerous
86 private String defaultLayerPid
= "argeo.suite.ui.dashboardLayer";
88 private String defaultThemeId
= "org.argeo.app.theme.default";
90 private Map
<String
, RankedObject
<CmsUiProvider
>> uiProvidersByPid
= Collections
.synchronizedMap(new HashMap
<>());
91 private Map
<String
, RankedObject
<CmsUiProvider
>> uiProvidersByType
= Collections
.synchronizedMap(new HashMap
<>());
92 private Map
<String
, RankedObject
<SuiteLayer
>> layersByPid
= Collections
.synchronizedSortedMap(new TreeMap
<>());
93 private Map
<String
, RankedObject
<SuiteLayer
>> layersByType
= Collections
.synchronizedSortedMap(new TreeMap
<>());
95 private CmsUserManager cmsUserManager
;
97 // TODO make more optimal or via CmsSession/CmsView
98 private Map
<String
, SuiteUi
> managedUis
= new HashMap
<>();
101 private ContentRepository contentRepository
;
102 private JcrContentProvider jcrContentProvider
;
105 private Repository repository
;
107 public void init(Map
<String
, Object
> properties
) {
108 if (log
.isDebugEnabled())
109 log
.info("Argeo Suite App started");
111 if (properties
.containsKey(DEFAULT_UI_NAME_PROPERTY
))
112 defaultUiName
= LangUtils
.get(properties
, DEFAULT_UI_NAME_PROPERTY
);
113 if (properties
.containsKey(DEFAULT_THEME_ID_PROPERTY
))
114 defaultThemeId
= LangUtils
.get(properties
, DEFAULT_THEME_ID_PROPERTY
);
115 if (properties
.containsKey(DEFAULT_LAYER_PROPERTY
))
116 defaultLayerPid
= LangUtils
.get(properties
, DEFAULT_LAYER_PROPERTY
);
117 publicBasePath
= LangUtils
.get(properties
, PUBLIC_BASE_PATH_PROPERTY
);
119 if (properties
.containsKey(Constants
.SERVICE_PID
)) {
120 String servicePid
= properties
.get(Constants
.SERVICE_PID
).toString();
121 if (servicePid
.endsWith(".app")) {
122 pidPrefix
= servicePid
.substring(0, servicePid
.length() - "app".length());
126 if (pidPrefix
== null)
127 throw new IllegalArgumentException("PID prefix must be set.");
129 headerPid
= pidPrefix
+ "header";
130 footerPid
= pidPrefix
+ "footer";
131 leadPanePid
= pidPrefix
+ "leadPane";
132 adminLeadPanePid
= pidPrefix
+ "adminLeadPane";
133 loginScreenPid
= pidPrefix
+ "loginScreen";
136 public void destroy(Map
<String
, Object
> properties
) {
137 for (SuiteUi ui
: managedUis
.values())
138 if (!ui
.isDisposed()) {
139 ui
.getDisplay().syncExec(() -> ui
.dispose());
141 if (log
.isDebugEnabled())
142 log
.info("Argeo Suite App stopped");
147 public Set
<String
> getUiNames() {
148 HashSet
<String
> uiNames
= new HashSet
<>();
149 uiNames
.add(defaultUiName
);
150 uiNames
.add(adminUiName
);
155 public CmsUi
initUi(Object parent
) {
156 Composite uiParent
= (Composite
) parent
;
157 String uiName
= uiParent
.getData(UI_NAME_PROPERTY
) != null ? uiParent
.getData(UI_NAME_PROPERTY
).toString()
159 CmsView cmsView
= CmsSwtUtils
.getCmsView(uiParent
);
161 throw new IllegalStateException("No CMS view is registered.");
162 CmsTheme theme
= getTheme(uiName
);
164 CmsSwtUtils
.registerCmsTheme(uiParent
.getShell(), theme
);
165 SuiteUi argeoSuiteUi
= new SuiteUi(uiParent
, SWT
.INHERIT_DEFAULT
);
166 String uid
= cmsView
.getUid();
167 managedUis
.put(uid
, argeoSuiteUi
);
168 argeoSuiteUi
.addDisposeListener((e
) -> {
169 managedUis
.remove(uid
);
170 if (log
.isDebugEnabled())
171 log
.debug("Suite UI " + uid
+ " has been disposed.");
177 public String
getThemeId(String uiName
) {
178 String themeId
= System
.getProperty("org.argeo.app.theme.default");
181 return defaultThemeId
;
185 public void refreshUi(CmsUi cmsUi
, String state
) {
187 Content context
= null;
188 SuiteUi ui
= (SuiteUi
) cmsUi
;
190 String uiName
= Objects
.toString(ui
.getParent().getData(UI_NAME_PROPERTY
), null);
192 throw new IllegalStateException("UI name should not be null");
193 CmsView cmsView
= CmsSwtUtils
.getCmsView(ui
);
195 ContentSession contentSession
= CmsUxUtils
.getContentSession(contentRepository
, cmsView
);
197 CmsUiProvider headerUiProvider
= findUiProvider(headerPid
);
198 CmsUiProvider footerUiProvider
= findUiProvider(footerPid
);
199 CmsUiProvider leadPaneUiProvider
;
200 if (adminUiName
.equals(uiName
)) {
201 leadPaneUiProvider
= findUiProvider(adminLeadPanePid
);
203 leadPaneUiProvider
= findUiProvider(leadPanePid
);
206 Localized appTitle
= null;
207 if (headerUiProvider
instanceof DefaultHeader
) {
208 appTitle
= ((DefaultHeader
) headerUiProvider
).getTitle();
210 ui
.setTitle(appTitle
);
212 if (cmsView
.isAnonymous() && publicBasePath
== null) {// internal app, must login
214 if (headerUiProvider
!= null)
215 refreshPart(headerUiProvider
, ui
.getHeader(), context
);
216 ui
.refreshBelowHeader(false);
217 refreshPart(findUiProvider(loginScreenPid
), ui
.getBelowHeader(), context
);
218 if (footerUiProvider
!= null)
219 refreshPart(footerUiProvider
, ui
.getFooter(), context
);
220 ui
.layout(true, true);
223 if (LOGIN
.equals(state
))
225 CmsSession cmsSession
= cmsView
.getCmsSession();
226 if (ui
.getUserDirNode() == null) {
227 // FIXME NPE on CMSSession when logging in from anonymous
228 if (cmsSession
== null || cmsView
.isAnonymous()) {
229 assert publicBasePath
!= null;
230 Content userDir
= contentSession
.get(CmsConstants
.SYS_WORKSPACE
+ publicBasePath
);
231 ui
.setUserDir(userDir
);
232 // ui.initSessions(getRepository(), publicBasePath);
234 Session adminSession
= null;
236 adminSession
= CmsJcrUtils
.openDataAdminSession(getRepository(), null);
237 Node userDirNode
= SuiteUtils
.getOrCreateCmsSessionNode(adminSession
, cmsSession
);
238 Content userDir
= contentSession
.get(CmsConstants
.SYS_WORKSPACE
+ userDirNode
.getPath());
239 ui
.setUserDir(userDir
);
240 // ui.initSessions(getRepository(), userDirNode.getPath());
242 Jcr
.logout(adminSession
);
246 initLocale(cmsSession
);
247 context
= stateToNode(ui
, state
);
249 context
= ui
.getUserDirNode();
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
);
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
);
266 } catch (Exception e
) {
267 CmsFeedback
.show("Unexpected exception", e
);
271 private void initLocale(CmsSession cmsSession
) {
272 if (cmsSession
== null)
274 Locale locale
= cmsSession
.getLocale();
275 UiContext
.setLocale(locale
);
276 LocaleUtils
.setThreadLocale(locale
);
280 private void refreshPart(CmsUiProvider uiProvider
, Composite part
, Content context
) {
281 CmsSwtUtils
.clear(part
);
282 uiProvider
.createUiPart(part
, context
);
285 private CmsUiProvider
findUiProvider(String pid
) {
286 if (!uiProvidersByPid
.containsKey(pid
))
288 return uiProvidersByPid
.get(pid
).get();
291 private SuiteLayer
findLayer(String pid
) {
292 if (!layersByPid
.containsKey(pid
))
294 return layersByPid
.get(pid
).get();
297 private <T
> T
findByType(Map
<String
, RankedObject
<T
>> byType
, Content content
) {
299 throw new IllegalArgumentException("A node should be provided");
301 if(content
instanceof JcrContent
) {
302 Node context
= ((JcrContent
)content
).getJcrNode();
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
);
311 for (NodeType superType
: mixinType
.getDeclaredSupertypes()) {
312 if (byType
.containsKey(superType
.getName())) {
313 types
.add(superType
.getName());
318 NodeType primaryType
= context
.getPrimaryNodeType();
319 String primaryTypeName
= primaryType
.getName();
320 if (byType
.containsKey(primaryTypeName
)) {
321 types
.add(primaryTypeName
);
323 for (NodeType superType
: primaryType
.getDeclaredSupertypes()) {
324 if (byType
.containsKey(superType
.getName())) {
325 types
.add(superType
.getName());
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
);
338 // if (context.getPath().equals("/")) {// root node
339 // types.add("nt:folder");
341 if (CmsJcrUtils
.isUserHome(context
) && byType
.containsKey("nt:folder")) {// home node
342 types
.add("nt:folder");
345 if (types
.size() == 0)
346 throw new IllegalArgumentException("No type found for " + context
+ " (" + listTypes(context
) + ")");
347 String type
= types
.iterator().next();
348 if (!byType
.containsKey(type
))
349 throw new IllegalArgumentException("No component found for " + context
+ " with type " + type
);
350 return byType
.get(type
).get();
351 } catch (RepositoryException e
) {
352 throw new IllegalStateException(e
);
356 throw new UnsupportedOperationException("Content "+content
.getClass().getName()+" is not supported.");
360 private static String
listTypes(Node context
) {
362 StringBuilder sb
= new StringBuilder();
363 sb
.append(context
.getPrimaryNodeType().getName());
364 for (NodeType superType
: context
.getPrimaryNodeType().getDeclaredSupertypes()) {
366 sb
.append(superType
.getName());
369 for (NodeType nodeType
: context
.getMixinNodeTypes()) {
371 sb
.append(nodeType
.getName());
372 if (nodeType
.getName().equals(EntityType
.local
.get()))
373 sb
.append('/').append(context
.getProperty(EntityNames
.ENTITY_TYPE
).getString());
374 for (NodeType superType
: nodeType
.getDeclaredSupertypes()) {
376 sb
.append(superType
.getName());
379 return sb
.toString();
380 } catch (RepositoryException e
) {
381 throw new JcrException(e
);
386 public void setState(CmsUi cmsUi
, String state
) {
389 if (!state
.startsWith("/")) {
390 if (cmsUi
instanceof SuiteUi
) {
391 SuiteUi ui
= (SuiteUi
) cmsUi
;
392 if (LOGIN
.equals(state
)) {
393 String appTitle
= "";
394 if (ui
.getTitle() != null)
395 appTitle
= ui
.getTitle().lead();
396 ui
.getCmsView().stateChanged(state
, appTitle
);
399 Map
<String
, Object
> properties
= new HashMap
<>();
400 String layerId
= HOME_STATE
.equals(state
) ? defaultLayerPid
: state
;
401 properties
.put(SuiteEvent
.LAYER
, layerId
);
402 properties
.put(SuiteEvent
.NODE_PATH
, HOME_STATE
);
403 ui
.getCmsView().sendEvent(SuiteEvent
.switchLayer
.topic(), properties
);
407 SuiteUi suiteUi
= (SuiteUi
) cmsUi
;
408 Content node
= stateToNode(suiteUi
, state
);
410 suiteUi
.getCmsView().navigateTo(HOME_STATE
);
412 suiteUi
.getCmsView().sendEvent(SuiteEvent
.switchLayer
.topic(), SuiteEvent
.eventProperties(node
));
413 suiteUi
.getCmsView().sendEvent(SuiteEvent
.refreshPart
.topic(), SuiteEvent
.eventProperties(node
));
417 // TODO move it to an internal package?
418 static String
nodeToState(Content node
) {
419 return node
.getPath();
422 private Content
stateToNode(SuiteUi suiteUi
, String state
) {
425 if (state
== null || !state
.startsWith("/"))
429 // String path = state.substring(1);
431 // if (path.equals("")) {
435 // int index = path.indexOf('/');
437 // log.error("Cannot interpret " + state);
438 //// cmsView.navigateTo("~");
440 // } else if (index > 0) {
441 // workspace = path.substring(0, index);
442 // path = path.substring(index);
443 // } else {// index<0, assuming root node
449 ProvidedSession contentSession
= (ProvidedSession
) CmsUxUtils
.getContentSession(contentRepository
,
450 suiteUi
.getCmsView());
451 return contentSession
.get(path
);
452 // Session session = jcrContentProvider.getJcrSession(contentSession, workspace);
453 //// Session session = suiteUi.getSession(workspace);
454 // if (session == null)
456 // Node node = Jcr.getNode(session, path);
465 public void handleEvent(Event event
) {
467 // Specific UI related events
468 SuiteUi ui
= getRelatedUi(event
);
472 String appTitle
= "";
473 if (ui
.getTitle() != null)
474 appTitle
= ui
.getTitle().lead() + " - ";
476 // String currentLayerId = ui.getCurrentLayerId();
477 // SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null;
478 if (SuiteUiUtils
.isTopic(event
, SuiteEvent
.refreshPart
)) {
479 Content node
= getNode(ui
, event
);
482 CmsUiProvider uiProvider
= findByType(uiProvidersByType
, node
);
483 SuiteLayer layer
= findByType(layersByType
, node
);
484 ui
.switchToLayer(layer
, node
);
485 ui
.getCmsView().runAs(() -> layer
.view(uiProvider
, ui
.getCurrentWorkArea(), node
));
486 ui
.getCmsView().stateChanged(nodeToState(node
), appTitle
+ CmsUxUtils
.getTitle(node
));
487 } else if (SuiteUiUtils
.isTopic(event
, SuiteEvent
.openNewPart
)) {
488 Content node
= getNode(ui
, event
);
491 CmsUiProvider uiProvider
= findByType(uiProvidersByType
, node
);
492 SuiteLayer layer
= findByType(layersByType
, node
);
493 ui
.switchToLayer(layer
, node
);
494 ui
.getCmsView().runAs(() -> layer
.open(uiProvider
, ui
.getCurrentWorkArea(), node
));
495 ui
.getCmsView().stateChanged(nodeToState(node
), appTitle
+ CmsUxUtils
.getTitle(node
));
496 } else if (SuiteUiUtils
.isTopic(event
, SuiteEvent
.switchLayer
)) {
497 String layerId
= get(event
, SuiteEvent
.LAYER
);
498 if (layerId
!= null) {
499 // ui.switchToLayer(layerId, ui.getUserDir());
500 SuiteLayer suiteLayer
= findLayer(layerId
);
501 if (suiteLayer
== null)
502 throw new IllegalArgumentException("No layer '" + layerId
+ "' available.");
503 Localized layerTitle
= suiteLayer
.getTitle();
504 // FIXME make sure we don't rebuild the work area twice
505 Composite workArea
= ui
.getCmsView().doAs(() -> ui
.switchToLayer(layerId
, ui
.getUserDirNode()));
507 if (layerTitle
!= null)
508 title
= layerTitle
.lead();
509 Content nodeFromState
= getNode(ui
, event
);
510 if (nodeFromState
!= null && nodeFromState
.getPath().equals(ui
.getUserDirNode().getPath())) {
511 // default layer view is forced
512 String state
= defaultLayerPid
.equals(layerId
) ?
"~" : layerId
;
513 ui
.getCmsView().stateChanged(state
, appTitle
+ title
);
514 suiteLayer
.view(null, workArea
, nodeFromState
);
516 Content layerCurrentContext
= suiteLayer
.getCurrentContext(workArea
);
517 if (layerCurrentContext
!= null) {
518 // layer was already showing a context so we set the state to it
519 ui
.getCmsView().stateChanged(nodeToState(layerCurrentContext
),
520 appTitle
+ CmsUxUtils
.getTitle(layerCurrentContext
));
522 // no context was shown
523 ui
.getCmsView().stateChanged(layerId
, appTitle
+ title
);
527 Content node
= getNode(ui
, event
);
529 SuiteLayer layer
= findByType(layersByType
, node
);
530 ui
.getCmsView().runAs(() -> ui
.switchToLayer(layer
, node
));
534 } catch (Exception e
) {
535 log
.error("Cannot handle event " + event
, e
);
536 // CmsView.getCmsView(ui).exception(e);
541 private Content
getNode(SuiteUi ui
, Event event
) {
542 ProvidedSession contentSession
= (ProvidedSession
) CmsUxUtils
.getContentSession(contentRepository
,
545 String path
= get(event
,SuiteEvent
.CONTENT_PATH
);
547 // String nodePath = get(event, SuiteEvent.NODE_PATH);
548 if (path
!= null && path
.equals(HOME_STATE
))
549 return ui
.getUserDir();
550 // String workspace = get(event, SuiteEvent.WORKSPACE);
552 // Session session = jcrContentProvider.getJcrSession(contentSession, workspace);
553 //// Session session = ui.getSession(workspace);
557 String username
= get(event
, SuiteEvent
.USERNAME
);
558 if (username
== null)
560 User user
= cmsUserManager
.getUser(username
);
565 userDn
= new LdapName(user
.getName());
566 } catch (InvalidNameException e
) {
567 throw new IllegalArgumentException("Badly formatted username", e
);
569 String userNodePath
= SuiteUtils
.getUserNodePath(userDn
);
570 // FIXME deal with home path
572 // if (Jcr.itemExists(session, userNodePath))
573 // node = Jcr.getNode(session, userNodePath);
575 // Session adminSession = null;
577 // adminSession = CmsJcrUtils.openDataAdminSession(getRepository(), workspace);
578 // SuiteUtils.getOrCreateUserNode(adminSession, userDn);
580 // Jcr.logout(adminSession);
582 // node = Jcr.getNode(session, userNodePath);
585 node
= contentSession
.get(path
);
590 private SuiteUi
getRelatedUi(Event event
) {
591 return managedUis
.get(get(event
, CMS_VIEW_UID_PROPERTY
));
594 public static String
get(Event event
, String key
) {
595 Object value
= event
.getProperty(key
);
598 // throw new IllegalArgumentException("Property " + key + " must be set");
599 return value
.toString();
604 * Dependency injection.
607 public void addUiProvider(CmsUiProvider uiProvider
, Map
<String
, Object
> properties
) {
608 if (properties
.containsKey(Constants
.SERVICE_PID
)) {
609 String pid
= (String
) properties
.get(Constants
.SERVICE_PID
);
610 RankedObject
.putIfHigherRank(uiProvidersByPid
, pid
, uiProvider
, properties
);
612 if (properties
.containsKey(EntityConstants
.TYPE
)) {
613 List
<String
> types
= LangUtils
.toStringList(properties
.get(EntityConstants
.TYPE
));
614 for (String type
: types
)
615 RankedObject
.putIfHigherRank(uiProvidersByType
, type
, uiProvider
, properties
);
619 public void removeUiProvider(CmsUiProvider uiProvider
, Map
<String
, Object
> properties
) {
620 if (properties
.containsKey(Constants
.SERVICE_PID
)) {
621 String pid
= (String
) properties
.get(Constants
.SERVICE_PID
);
622 if (uiProvidersByPid
.containsKey(pid
)) {
623 if (uiProvidersByPid
.get(pid
).equals(new RankedObject
<CmsUiProvider
>(uiProvider
, properties
))) {
624 uiProvidersByPid
.remove(pid
);
628 if (properties
.containsKey(EntityConstants
.TYPE
)) {
629 List
<String
> types
= LangUtils
.toStringList(properties
.get(EntityConstants
.TYPE
));
630 for (String type
: types
) {
631 if (uiProvidersByType
.containsKey(type
)) {
632 if (uiProvidersByType
.get(type
).equals(new RankedObject
<CmsUiProvider
>(uiProvider
, properties
))) {
633 uiProvidersByType
.remove(type
);
640 public void addLayer(SuiteLayer layer
, Map
<String
, Object
> properties
) {
641 if (properties
.containsKey(Constants
.SERVICE_PID
)) {
642 String pid
= (String
) properties
.get(Constants
.SERVICE_PID
);
643 RankedObject
.putIfHigherRank(layersByPid
, pid
, layer
, properties
);
645 if (properties
.containsKey(EntityConstants
.TYPE
)) {
646 List
<String
> types
= LangUtils
.toStringList(properties
.get(EntityConstants
.TYPE
));
647 for (String type
: types
)
648 RankedObject
.putIfHigherRank(layersByType
, type
, layer
, properties
);
652 public void removeLayer(SuiteLayer layer
, Map
<String
, Object
> properties
) {
653 if (properties
.containsKey(Constants
.SERVICE_PID
)) {
654 String pid
= (String
) properties
.get(Constants
.SERVICE_PID
);
655 if (layersByPid
.containsKey(pid
)) {
656 if (layersByPid
.get(pid
).equals(new RankedObject
<SuiteLayer
>(layer
, properties
))) {
657 layersByPid
.remove(pid
);
661 if (properties
.containsKey(EntityConstants
.TYPE
)) {
662 List
<String
> types
= LangUtils
.toStringList(properties
.get(EntityConstants
.TYPE
));
663 for (String type
: types
) {
664 if (layersByType
.containsKey(type
)) {
665 if (layersByType
.get(type
).equals(new RankedObject
<SuiteLayer
>(layer
, properties
))) {
666 layersByType
.remove(type
);
673 public void setCmsUserManager(CmsUserManager cmsUserManager
) {
674 this.cmsUserManager
= cmsUserManager
;
677 protected Repository
getRepository() {
681 public void setRepository(Repository repository
) {
682 this.repository
= repository
;
685 protected ContentRepository
getContentRepository() {
686 return contentRepository
;
689 public void setContentRepository(ContentRepository contentRepository
) {
690 this.contentRepository
= contentRepository
;
693 public void setJcrContentProvider(JcrContentProvider jcrContentProvider
) {
694 this.jcrContentProvider
= jcrContentProvider
;