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