1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.social.core.space.impl;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Set;
26
27 import org.exoplatform.application.registry.Application;
28 import org.exoplatform.application.registry.ApplicationCategory;
29 import org.exoplatform.container.ExoContainer;
30 import org.exoplatform.container.ExoContainerContext;
31 import org.exoplatform.container.PortalContainer;
32 import org.exoplatform.container.xml.InitParams;
33 import org.exoplatform.portal.config.DataStorage;
34 import org.exoplatform.portal.config.UserACL;
35 import org.exoplatform.portal.config.UserPortalConfigService;
36 import org.exoplatform.portal.config.model.ApplicationType;
37 import org.exoplatform.portal.config.model.Container;
38 import org.exoplatform.portal.config.model.ModelObject;
39 import org.exoplatform.portal.config.model.Page;
40 import org.exoplatform.portal.config.model.PortalConfig;
41 import org.exoplatform.portal.config.model.TransientApplicationState;
42 import org.exoplatform.portal.mop.SiteKey;
43 import org.exoplatform.portal.mop.navigation.NavigationContext;
44 import org.exoplatform.portal.mop.navigation.NavigationService;
45 import org.exoplatform.portal.mop.navigation.NodeContext;
46 import org.exoplatform.portal.mop.navigation.NodeModel;
47 import org.exoplatform.portal.mop.navigation.NodeState;
48 import org.exoplatform.portal.mop.navigation.NodeState.Builder;
49 import org.exoplatform.portal.mop.navigation.Scope;
50 import org.exoplatform.portal.mop.page.PageContext;
51 import org.exoplatform.portal.mop.page.PageKey;
52 import org.exoplatform.portal.mop.page.PageService;
53 import org.exoplatform.portal.mop.page.PageState;
54 import org.exoplatform.portal.mop.user.UserNode;
55 import org.exoplatform.portal.pom.config.Utils;
56 import org.exoplatform.portal.pom.spi.gadget.Gadget;
57 import org.exoplatform.portal.pom.spi.portlet.Portlet;
58 import org.exoplatform.portal.pom.spi.portlet.PortletBuilder;
59 import org.exoplatform.portal.webui.portal.UIPortal;
60 import org.exoplatform.portal.webui.util.Util;
61 import org.exoplatform.services.log.ExoLogger;
62 import org.exoplatform.services.log.Log;
63 import org.exoplatform.social.core.space.*;
64 import org.exoplatform.social.core.space.model.Space;
65 import org.exoplatform.social.core.space.spi.SpaceApplicationHandler;
66 import org.exoplatform.social.core.space.spi.SpaceService;
67 import org.exoplatform.social.core.space.spi.SpaceTemplateService;
68 import org.exoplatform.webui.application.WebuiRequestContext;
69
70
71
72
73
74
75
76
77
78 public class DefaultSpaceApplicationHandler implements SpaceApplicationHandler {
79 private static final Log LOG = ExoLogger.getLogger(DefaultSpaceApplicationHandler.class);
80
81 public static final String NAME = "classic";
82
83 private static final String TEMPLATE_NAME_PARAM = "templateName";
84
85 public static final String SPACE_TEMPLATE_PAGE_ID = "portal::classic::spacetemplate";
86
87 public static final String APPLICATION_CONTAINER = "Application";
88
89
90
91
92
93
94 private static final String GROUP_ID_PREFERENCE = "{groupId}";
95
96
97
98
99
100
101 private static final String MODIFIED_GROUP_ID_PREFERENCE = "{modifiedGroupId}";
102
103
104
105
106
107
108 private static final String PAGE_NAME_PREFERENCE = "{pageName}";
109
110
111
112
113
114
115 private static final String PAGE_URL_PREFERENCE = "{pageUrl}";
116
117 private PortalContainer container = PortalContainer.getInstance();
118
119 private DataStorage dataStorage = null;
120 private PageService pageService = null;
121
122 private SpaceService spaceService;
123
124 private SpaceTemplateService spaceTemplateService;
125
126 private Map<ApplicationCategory, List<Application>> appStoreCache = null;
127
128 private static List<Application> appCache = new ArrayList<Application>();
129
130 private String templateName;
131
132
133
134
135
136
137 public DefaultSpaceApplicationHandler(InitParams params, DataStorage dataStorage, PageService pageService, SpaceTemplateService spaceTemplateService) {
138 this.dataStorage = dataStorage;
139 this.pageService = pageService;
140 this.spaceTemplateService = spaceTemplateService;
141 if (params == null) {
142 templateName = NAME;
143 } else {
144 templateName = params.getValueParam(TEMPLATE_NAME_PARAM).getValue();
145 }
146 }
147
148
149
150
151 public void initApps(Space space, SpaceTemplate spaceTemplate) throws SpaceException {
152 try {
153 ExoContainer container = ExoContainerContext.getCurrentContainer();
154 NavigationService navService = (NavigationService) container.getComponentInstance(NavigationService.class);
155 NavigationContext navContext = SpaceUtils.createGroupNavigation(space.getGroupId());
156
157 NodeContext<NodeContext<?>> parentNodeCtx = navService.loadNode(NodeModel.SELF_MODEL, navContext, Scope.CHILDREN, null);
158
159
160 SpaceApplication homeApplication = spaceTemplate.getSpaceHomeApplication();
161 if (homeApplication == null) {
162 throw new IllegalStateException("Could not find space home application for template "
163 + spaceTemplate.getName() == null ? "" : spaceTemplate.getName() + ". Could not init space apps");
164 }
165 NodeContext<NodeContext<?>> homeNodeCtx = createPageNodeFromApplication(navContext, parentNodeCtx, space, homeApplication, null, true);
166 SpaceService spaceService = getSpaceService();
167
168
169 List<SpaceApplication> spaceApplications = spaceTemplate.getSpaceApplicationList();
170 if (spaceApplications != null) {
171 for (SpaceApplication spaceApplication : spaceApplications) {
172 createPageNodeFromApplication(navContext, homeNodeCtx, space, spaceApplication, null, false);
173 spaceService.installApplication(space, spaceApplication.getPortletName());
174 }
175 }
176
177 navService.saveNode(parentNodeCtx, null);
178 } catch (Exception e) {
179 throw new SpaceException(SpaceException.Code.UNABLE_TO_INIT_APP, e);
180 }
181 }
182
183
184
185
186
187
188
189
190 public void deInitApp(Space space) throws SpaceException {
191 try {
192 String groupId = space.getGroupId();
193 NavigationContext spaceNavCtx = SpaceUtils.getGroupNavigationContext(groupId);
194
195 if (spaceNavCtx == null) {
196 return;
197 }
198 NodeContext<NodeContext<?>> homeNodeCtx = SpaceUtils.getHomeNodeWithChildren(spaceNavCtx, groupId);
199
200 for (NodeContext<?> child : homeNodeCtx.getNodes()) {
201 @SuppressWarnings("unchecked")
202 NodeContext<NodeContext<?>> childNode = (NodeContext<NodeContext<?>>) child;
203 Page page = dataStorage.getPage(childNode.getState().getPageRef().format());
204 dataStorage.remove(page);
205 }
206
207
208 SpaceUtils.removeGroupNavigation(groupId);
209 } catch (Exception e) {
210 throw new SpaceException(SpaceException.Code.UNABLE_TO_DEINIT_APP, e);
211 }
212 }
213
214
215
216
217 public void activateApplication(Space space, String appId, String appName) throws SpaceException {
218 ExoContainer container = ExoContainerContext.getCurrentContainer();
219 NavigationService navService = (NavigationService) container.getComponentInstance(NavigationService.class);
220 NavigationContext navContext;
221 NodeContext<NodeContext<?>> homeNodeCtx = null;
222
223 try {
224 navContext = SpaceUtils.getGroupNavigationContext(space.getGroupId());
225 homeNodeCtx = SpaceUtils.getHomeNodeWithChildren(navContext, space.getUrl());
226
227 } catch (Exception e) {
228 LOG.warn("space navigation not found.", e);
229 return;
230 }
231 SpaceApplication spaceApplication = null;
232 String spaceTemplateName = space.getTemplate();
233 SpaceTemplate spaceTemplate = spaceTemplateService.getSpaceTemplateByName(spaceTemplateName);
234 if (spaceTemplate == null) {
235 throw new IllegalStateException("Space template with name " + spaceTemplateName +" wasn't found");
236 }
237 for(SpaceApplication application : spaceTemplate.getSpaceApplicationList()){
238 if (appId.equals(application.getPortletName()) && !SpaceUtils.isInstalledApp(space, appId)) {
239 spaceApplication = application;
240 }
241 }
242
243 if(spaceApplication == null) {
244 spaceApplication = new SpaceApplication();
245 spaceApplication.setPortletName(appId);
246 }
247 createPageNodeFromApplication(navContext, homeNodeCtx, space, spaceApplication, appName, false);
248 navService.saveNode(homeNodeCtx, null);
249 }
250
251
252
253
254 public void deactiveApplication(Space space, String appId) throws SpaceException {
255 deactivateApplicationClassic(space, appId);
256 }
257
258
259
260
261 public void installApplication(Space space, String appId) throws SpaceException {
262
263 }
264
265
266
267
268 public void removeApplication(Space space, String appId, String appName) throws SpaceException {
269 removeApplicationClassic(space, appId, appName);
270 }
271
272
273
274
275 public void removeApplications(Space space) throws SpaceException {
276 try {
277 String[] apps = space.getApp().split(",");
278 String[] appPart = null;
279 for (int i = 0; i < apps.length; i++) {
280 appPart = apps[i].split(":");
281 removeApplication(space, appPart[0], appPart[1]);
282 }
283 } catch (Exception e) {
284 throw new SpaceException(SpaceException.Code.UNABLE_TO_REMOVE_APPLICATIONS, e);
285 }
286 }
287
288
289
290
291 public String getName() {
292 return templateName;
293 }
294
295 @Override
296 public void setName(String s) {
297
298 }
299
300 @Override
301 public String getDescription() {
302 return null;
303 }
304
305 @Override
306 public void setDescription(String s) {
307
308 }
309
310
311
312
313
314
315
316 private void deactivateApplicationClassic(Space space, String appId) {
317
318 }
319
320
321
322
323
324
325
326
327 private void removeApplicationClassic(Space space, String appId, String appName) throws SpaceException {
328 try {
329
330 UserNode spaceUserNode = SpaceUtils.getSpaceUserNode(space);
331 UserNode removedNode = spaceUserNode.getChild(appName);
332
333 if (removedNode == null) {
334
335 String spaceTemplateName = space.getTemplate();
336 SpaceTemplate spaceTemplate = spaceTemplateService.getSpaceTemplateByName(spaceTemplateName);
337 if (spaceTemplate == null) {
338 throw new IllegalStateException("Space template with name " + spaceTemplateName +" wasn't found");
339 }
340 List<SpaceApplication> spaceApplications = spaceTemplate.getSpaceApplicationList();
341 for (SpaceApplication spaceApplication : spaceApplications) {
342 if (appId.equals(spaceApplication.getPortletName())) {
343 removedNode = spaceUserNode.getChild(spaceApplication.getUri());
344 }
345 }
346 }
347
348 if (removedNode != null) {
349 spaceUserNode.removeChild(removedNode.getName());
350 } else {
351 return;
352 }
353
354
355 if (removedNode != null) {
356 PageKey pageRef = removedNode.getPageRef();
357 if (pageRef.format() != null && pageRef.format().length() > 0) {
358
359 if (WebuiRequestContext.getCurrentInstance() != null) {
360 UIPortal uiPortal = Util.getUIPortal();
361
362 uiPortal.setUIPage(pageRef.format(), null);
363 }
364 pageService.destroyPage(pageRef);
365 }
366 }
367
368 SpaceUtils.getUserPortal().saveNode(spaceUserNode, null);
369
370 } catch (Exception e) {
371 throw new SpaceException(SpaceException.Code.UNABLE_TO_REMOVE_APPLICATION, e);
372 }
373
374 }
375
376
377
378
379
380
381
382
383 private Application getApplication(List<Application> apps, String appId) {
384 for (Application app : apps) {
385 if (app.getApplicationName().equals(appId)) {
386 return app;
387 }
388 }
389 return null;
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403 private NodeContext<NodeContext<?>> createPageNodeFromApplication(NavigationContext navContext, NodeContext<NodeContext<?>> nodeCtx, Space space,
404 SpaceApplication spaceApplication,
405 String appName,
406 boolean isRoot) throws SpaceException {
407 String appId = spaceApplication.getPortletName();
408 Application app = getApplication(space, appId);
409 String contentId = app.getContentId();
410 if (contentId == null) {
411 contentId = app.getCategoryName() + "/" + app.getApplicationName();
412 }
413 String appInstanceId = PortalConfig.GROUP_TYPE + "#" + space.getGroupId() + ":/" + contentId
414 + "/" + app.getApplicationName() + System.currentTimeMillis();
415 org.exoplatform.portal.config.model.Application<Gadget> gadgetApplication = null;
416 org.exoplatform.portal.config.model.Application<Portlet> portletApplication = null;
417
418 if (app.getType() == ApplicationType.GADGET) {
419 TransientApplicationState<Gadget> gadgetState = new TransientApplicationState<Gadget>(app.getApplicationName());
420 gadgetApplication = org.exoplatform.portal.config.model.Application.createGadgetApplication();
421 gadgetApplication.setState(gadgetState);
422 gadgetApplication.setAccessPermissions(new String[]{"*:" + space.getGroupId()});
423 gadgetApplication.setShowInfoBar(false);
424 } else {
425 portletApplication = createPortletApplication(appInstanceId, space, isRoot);
426 portletApplication.setAccessPermissions(new String[]{"*:" + space.getGroupId()});
427 portletApplication.setShowInfoBar(false);
428 }
429
430 String pageTitle = space.getDisplayName() + " - " + app.getDisplayName();
431 String pageName = app.getApplicationName();
432
433 if (SpaceUtils.isInstalledApp(space, appId) && (appName != null)) {
434 pageName = appName;
435 }
436 UserPortalConfigService userPortalConfigService = getUserPortalConfigService();
437 Page page = null;
438 try {
439 if (isRoot) {
440 page = userPortalConfigService.createPageTemplate("spaceHomePage",
441 PortalConfig.GROUP_TYPE,
442 space.getGroupId());
443 setPermissionForPage(page.getChildren(), "*:" + space.getGroupId());
444 } else {
445 page = userPortalConfigService.createPageTemplate("space",
446 PortalConfig.GROUP_TYPE,
447 space.getGroupId());
448
449 setPage(space, app, gadgetApplication, portletApplication, page);
450 }
451 page.setName(pageName);
452 page.setTitle(pageTitle);
453
454
455 String visibility = space.getVisibility();
456 if (visibility.equals(Space.PUBLIC)) {
457 page.setAccessPermissions(new String[]{UserACL.EVERYONE});
458 } else {
459 page.setAccessPermissions(new String[]{"*:" + space.getGroupId()});
460 }
461 page.setEditPermission("manager:" + space.getGroupId());
462
463
464 SiteKey siteKey = navContext.getKey();
465 PageKey pageKey = new PageKey(siteKey, page.getName());
466 PageState pageState = new PageState(
467 page.getTitle(),
468 page.getDescription(),
469 page.isShowMaxWindow(),
470 page.getFactoryId(),
471 page.getAccessPermissions() != null ? Arrays.asList(page.getAccessPermissions()) : null,
472 page.getEditPermission(), Arrays.asList(page.getMoveAppsPermissions()), Arrays.asList(page.getMoveContainersPermissions()));
473
474 pageService.savePage(new PageContext(pageKey, pageState));
475 dataStorage.save(page);
476 page = dataStorage.getPage(page.getPageId());
477 PageContext pageContext = pageService.loadPage(PageKey.parse(page.getPageId()));
478 pageContext.update(page);
479 } catch (Exception e) {
480 LOG.warn(e.getMessage(), e);
481 }
482
483
484 if (isRoot) {
485 pageName = space.getUrl();
486 } else {
487 if (spaceApplication.getUri() != null && !spaceApplication.getUri().isEmpty()) {
488 pageName = spaceApplication.getUri();
489 }
490
491 }
492 NodeContext<NodeContext<?>> childNodeCtx = nodeCtx.add(null, pageName);
493 Builder nodeStateBuilder = new NodeState.Builder().icon(spaceApplication.getIcon()).pageRef(PageKey.parse(page.getPageId()));
494 WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
495 if (context != null && !context.getApplicationResourceBundle().containsKey(appId + ".label.name")) {
496 nodeStateBuilder.label(app.getDisplayName());
497 }
498 childNodeCtx.setState(nodeStateBuilder.build());
499 return childNodeCtx;
500 }
501
502
503
504
505
506
507
508
509
510 private Application getApplication(Space space, String appId) throws SpaceException {
511 Application app = getApplication(appCache, appId);
512 if (app == null) {
513 try {
514 if (appStoreCache == null) {
515 appStoreCache = SpaceUtils.getAppStore(space);
516 }
517 app = getApplication(appStoreCache, appId);
518 if (app == null) {
519
520 appStoreCache = SpaceUtils.getAppStore(space);
521 app = getApplication(appStoreCache, appId);
522 if (app == null) {
523 app = SpaceUtils.getAppFromPortalContainer(appId);
524 if (app == null) {
525 throw new Exception("app is null!");
526 }
527 }
528 }
529 appCache.add(app);
530 } catch (Exception e) {
531 throw new SpaceException(SpaceException.Code.UNABLE_TO_LIST_AVAILABLE_APPLICATIONS, e);
532 }
533 }
534 return app;
535 }
536
537 @SuppressWarnings("unchecked")
538 private void setPage(Space space,
539 Application app,
540 org.exoplatform.portal.config.model.Application<Gadget> gadgetApplication,
541 org.exoplatform.portal.config.model.Application<Portlet> portletApplication,
542 Page page) {
543
544 ArrayList<ModelObject> pageChilds = page.getChildren();
545
546
547 Container container = SpaceUtils.findContainerById(pageChilds, SpaceUtils.APPLICATION_CONTAINER);
548 ArrayList<ModelObject> children = container.getChildren();
549
550 if (app.getType() == ApplicationType.GADGET) {
551 children.add(gadgetApplication);
552 } else {
553 children.add(portletApplication);
554 }
555 container.setChildren(children);
556 pageChilds = setContainerById(pageChilds, container);
557 page.setChildren(pageChilds);
558 setPermissionForPage(page.getChildren(), "*:" + space.getGroupId());
559 }
560
561
562
563
564
565
566
567
568 private Application getApplication(Map<ApplicationCategory, List<Application>> appStore,
569 String appId) {
570 Iterator<ApplicationCategory> categoryItr = appStore.keySet().iterator();
571 while (categoryItr.hasNext()) {
572 ApplicationCategory category = categoryItr.next();
573 List<Application> appList = category.getApplications();
574 Iterator<Application> appListItr = appList.iterator();
575 while (appListItr.hasNext()) {
576 Application app = appListItr.next();
577 if (app.getApplicationName().equals(appId)) {
578 return app;
579 }
580 }
581 }
582 return null;
583 }
584
585
586
587
588
589
590
591
592 @SuppressWarnings("unchecked")
593 private void setPermissionForPage(ArrayList<ModelObject> children, String perm) {
594 for (ModelObject modelObject : children) {
595 if (modelObject instanceof org.exoplatform.portal.config.model.Application<?>) {
596 ((org.exoplatform.portal.config.model.Application) modelObject).setAccessPermissions(new String[]{perm});
597 } else if (modelObject instanceof Container) {
598 ((Container) modelObject).setAccessPermissions(new String[]{perm});
599 setPermissionForPage(((Container) modelObject).getChildren(), perm);
600 }
601 }
602 }
603
604
605
606
607
608
609
610
611 private ArrayList<ModelObject> setContainerById(ArrayList<ModelObject> childs, Container container) {
612 ArrayList<ModelObject> result = childs;
613 int index = result.indexOf(container);
614
615 if (index != -1) {
616 result.set(index, container);
617 } else {
618 for (int i = 0; i < result.size(); i++) {
619 ModelObject obj = result.get(i);
620 if (org.exoplatform.portal.config.model.Application.class.isInstance(obj)) {
621 continue;
622 }
623 Container objContainer = (Container) obj;
624 ArrayList<ModelObject> tmp = setContainerById(objContainer.getChildren(), container);
625 objContainer.setChildren(tmp);
626 result.set(i, objContainer);
627 }
628 }
629 return result;
630 }
631
632
633
634
635
636
637
638 private org.exoplatform.portal.config.model.Application<Portlet> createPortletApplication(String instanceId,
639 Space space,
640 boolean isRoot) {
641 int i0 = instanceId.indexOf("#");
642 int i1 = instanceId.indexOf(":/", i0 + 1);
643 String ownerType = instanceId.substring(0, i0);
644 String ownerId = instanceId.substring(i0 + 1, i1);
645 String persistenceid = instanceId.substring(i1 + 2);
646 String[] persistenceChunks = Utils.split("/", persistenceid);
647 PortletBuilder pb = new PortletBuilder();
648
649 String spaceTemplateName = space.getTemplate();
650 SpaceTemplate spaceTemplate = spaceTemplateService.getSpaceTemplateByName(spaceTemplateName);
651 if (spaceTemplate == null) {
652 throw new IllegalStateException("Space template with name " + spaceTemplateName +" wasn't found");
653 }
654 List<SpaceApplication> spaceApplicationList = spaceTemplate.getSpaceApplicationList();
655 SpaceApplication spaceApplication = null;
656 for (Iterator<SpaceApplication> iterator = spaceApplicationList.iterator(); iterator.hasNext() && spaceApplication == null;) {
657 SpaceApplication tmpSpaceApplication = iterator.next();
658 if (instanceId.contains(tmpSpaceApplication.getPortletName())) {
659 spaceApplication = tmpSpaceApplication;
660 }
661 }
662 if (spaceApplication != null && spaceApplication.getPreferences() != null) {
663 Set<Entry<String, String>> entrySet = spaceApplication.getPreferences().entrySet();
664 try {
665 for (Map.Entry<String, String> preference : entrySet) {
666 pb.add(preference.getKey(), getSubstituteValueFromPattern(space, spaceApplication, preference.getValue()));
667 }
668 } catch (Exception exception) {
669 LOG.warn(exception.getMessage(), exception);
670 }
671 }
672
673 TransientApplicationState<Portlet> portletState = new TransientApplicationState<Portlet>(persistenceChunks[0]
674 + "/"
675 + persistenceChunks[1],
676 pb.build(),
677 ownerType,
678 ownerId);
679 org.exoplatform.portal.config.model.Application<Portlet> portletApp =
680 org.exoplatform.portal.config.model.Application.createPortletApplication();
681 portletApp.setState(portletState);
682 return portletApp;
683 }
684
685 private String getSubstituteValueFromPattern(Space space, SpaceApplication spaceApplication, String pattern) {
686 if (!pattern.contains("{") || !pattern.contains("}")) {
687 return pattern;
688 }
689
690 if (pattern.contains(GROUP_ID_PREFERENCE)) {
691 pattern = pattern.replace(GROUP_ID_PREFERENCE, space.getGroupId());
692 } else if (pattern.contains(MODIFIED_GROUP_ID_PREFERENCE)) {
693 String modifiedGroupId = space.getGroupId().replace("/", ".");
694 pattern = pattern.replace(MODIFIED_GROUP_ID_PREFERENCE, modifiedGroupId);
695 } else if (pattern.contains(PAGE_NAME_PREFERENCE)) {
696 pattern = pattern.replace(PAGE_NAME_PREFERENCE, spaceApplication.getAppTitle());
697 } else if (pattern.contains(PAGE_URL_PREFERENCE)) {
698 pattern = pattern.replace(PAGE_URL_PREFERENCE, spaceApplication.getUri());
699 }
700 return pattern;
701 }
702
703
704
705
706
707
708 private UserPortalConfigService getUserPortalConfigService() {
709 return (UserPortalConfigService) container.getComponentInstanceOfType(UserPortalConfigService.class);
710 }
711
712 private SpaceService getSpaceService() {
713 ExoContainer container = ExoContainerContext.getCurrentContainer();
714 if (spaceService == null) {
715 spaceService = (SpaceService) container.getComponentInstance(SpaceService.class);
716 }
717
718 return spaceService;
719 }
720 }