/**
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.portal.webui.page;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.UserACL;
import org.exoplatform.portal.config.UserPortalConfigService;
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.mop.page.PageKey;
import org.exoplatform.portal.mop.page.PageService;
import org.exoplatform.portal.webui.application.UIPortlet;
import org.exoplatform.portal.webui.container.UIContainer;
import org.exoplatform.portal.webui.portal.UIPortalComposer;
import org.exoplatform.portal.webui.util.PortalDataMapper;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.portal.webui.workspace.UIMaskWorkspace;
import org.exoplatform.portal.webui.workspace.UIPortalApplication;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.config.InitParams;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.ComponentConfigs;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.config.annotation.ParamConfig;
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.core.model.SelectItemOption;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.form.UIFormInputItemSelector;
import org.exoplatform.webui.form.UIFormInputSet;
import org.exoplatform.webui.form.UIFormPopupWindow;
import org.exoplatform.webui.form.UIFormSelectBox;
import org.exoplatform.webui.form.UIFormStringInput;
import org.exoplatform.webui.form.UIFormTabPane;
import org.exoplatform.webui.form.input.UICheckBoxInput;
import org.exoplatform.webui.form.validator.MandatoryValidator;
import org.exoplatform.webui.form.validator.NotHTMLTagValidator;
import org.exoplatform.webui.form.validator.StringLengthValidator;
import org.exoplatform.webui.form.validator.UserConfigurableValidator;
import org.exoplatform.webui.organization.UIGroupMembershipSelector;
import org.exoplatform.webui.organization.UIListPermissionSelector;
import org.exoplatform.webui.organization.UIListPermissionSelector.EmptyIteratorValidator;
import org.exoplatform.webui.organization.UIPermissionSelector;
@ComponentConfigs({
@ComponentConfig(lifecycle = UIFormLifecycle.class, template = "system:/groovy/webui/form/UIFormTabPane.gtmpl", events = {
@EventConfig(listeners = UIPageForm.SaveActionListener.class),
@EventConfig(listeners = UIPageForm.ChangeOwnerTypeActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIPageForm.SelectMembershipActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIPageForm.ChangeOwnerIdActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIMaskWorkspace.CloseActionListener.class, phase = Phase.DECODE) }, initParams = @ParamConfig(name = "PageTemplate", value = "system:/WEB-INF/conf/uiconf/portal/webui/page/PageTemplate.groovy")),
@ComponentConfig(type = UIFormInputSet.class, id = "PermissionSetting", template = "system:/groovy/webui/core/UITabSelector.gtmpl", events = { @EventConfig(listeners = UIFormInputSet.SelectComponentActionListener.class) }) })
public class UIPageForm extends UIFormTabPane {
private UIPage uiPage_;
protected UIFormInputSet uiPermissionSetting;
protected UIListPermissionSelector uiAccessPermissionSelector;
protected UIPermissionSelector uiEditPermission;
protected UIListPermissionSelector uiMoveAppsPermissionSelector;
protected UIListPermissionSelector uiMoveContainersPermissionSelector;
protected UIFormSelectBox groupIdSelectBox = null;
protected UIFormStringInput ownerIdInput = null;
public static final String OWNER_TYPE = "ownerType";
public static final String OWNER_ID = "ownerId";
public UIPageForm(InitParams initParams) throws Exception {
super("UIPageForm");
setActions(new String[] { "Save", "Close" });
}
public UIPage getUIPage() {
return uiPage_;
}
/**
* @deprecated use {@link #buildForm(UIPage)} to initialize page form instead
*
* @param uiPage
* @throws Exception
*/
@Deprecated
public void setValues(UIPage uiPage) throws Exception {
buildForm(uiPage);
}
public void invokeSetBindingBean(Object bean) throws Exception {
String ownerType = getUIFormSelectBox("ownerType").getValue();
String ownerId = getUIStringInput("ownerId").getValue();
// As ownerId is now normalized, we have to maker sure that owenerId of 'group' type starts with a '/'
if (SiteType.GROUP.getName().equals(ownerType) && ownerId.charAt(0) != '/') {
ownerId = "/" + ownerId;
}
Page page = (Page) bean;
page.setPageId(getUIStringInput("pageId").getValue());
page.setOwnerType(ownerType);
page.setOwnerId(ownerId);
page.setName(getUIStringInput("name").getValue());
// Check if the page exists
PageService pageService = getApplicationComponent(PageService.class);
PageKey pageKey = new SiteKey(ownerType, ownerId).page(page.getName());
if (pageService.loadPage(pageKey) == null) {
// Set defaults only on new pages
UserPortalConfigService configService = getApplicationComponent(UserPortalConfigService.class);
configService.setDefaultPermissions(page);
}
String title = getUIStringInput("title").getValue();
if (title == null || title.trim().length() < 1) {
title = page.getName();
}
page.setTitle(title);
if (!page.isShowMaxWindow()) {
page.setShowMaxWindow(getUICheckBoxInput("showMaxWindow").getValue());
}
if (!SiteType.USER.getName().equals(page.getOwnerType())) {
page.setAccessPermissions(uiAccessPermissionSelector.getValue());
page.setEditPermission(uiEditPermission.getValue());
//
if(uiMoveAppsPermissionSelector != null) {
page.setMoveAppsPermissions(uiMoveAppsPermissionSelector.getValue());
}
if(uiMoveContainersPermissionSelector != null) {
page.setMoveContainersPermissions(uiMoveContainersPermissionSelector.getValue());
}
}
UserACL userACL = getApplicationComponent(UserACL.class);
userACL.hasPermission(page);
UIFormInputItemSelector<?> uiTemplate = getChildById("Template");
if (uiTemplate != null) {
SelectItemOption<?> itemOption = uiTemplate.getSelectedItemOption();
if (itemOption != null) {
page.setFactoryId(itemOption.getIcon());
// page.setTemplate((String)itemOption.getValue());
}
}
UIPageTemplateOptions uiConfigOptions = getChild(UIPageTemplateOptions.class);
if (uiConfigOptions != null) {
Page selectedPage = uiConfigOptions.createPageFromSelectedOption(page.getOwnerType(), page.getOwnerId());
if (selectedPage != null) {
page.setChildren(selectedPage.getChildren());
page.setFactoryId(selectedPage.getFactoryId());
}
}
}
private void loadMakableGroupNavigations() throws Exception {
if (groupIdSelectBox == null) {
UIFormInputSet uiSettingSet = getChildById("PageSetting");
PortalRequestContext pcontext = Util.getPortalRequestContext();
UserPortalConfigService userPortalConfigService = getApplicationComponent(UserPortalConfigService.class);
List<String> groups = userPortalConfigService.getMakableNavigations(pcontext.getRemoteUser(), true);
if (groups.size() > 0) {
Collections.sort(groups);
List<SelectItemOption<String>> groupsItem = new ArrayList<SelectItemOption<String>>();
for (String group : groups) {
groupsItem.add(new SelectItemOption<String>(group));
}
groupIdSelectBox = new UIFormSelectBox(OWNER_ID, OWNER_ID, groupsItem);
groupIdSelectBox.setOnChange("ChangeOwnerId");
groupIdSelectBox.setParent(uiSettingSet);
}
}
}
public void buildForm(UIPage uiPage) throws Exception {
PortalRequestContext pcontext = Util.getPortalRequestContext();
DataStorage dataStorage = getApplicationComponent(DataStorage.class);
PortalConfig pConfig = dataStorage.getPortalConfig(pcontext.getPortalOwner());
ExoContainer container = ExoContainerContext.getCurrentContainer();
UserACL acl = (UserACL) container.getComponentInstanceOfType(UserACL.class);
UIFormInputSet uiSettingSet = new UIFormInputSet("PageSetting");
uiSettingSet.addUIFormInput(new UIFormStringInput("pageId", "pageId", null).setReadOnly(true));
List<SelectItemOption<String>> ownerTypes = new ArrayList<SelectItemOption<String>>();
if (pConfig != null && acl.hasEditPermission(pConfig)) {
ownerTypes.add(new SelectItemOption<String>(SiteType.PORTAL.getName()));
}
UserPortalConfigService userPortalConfigService = getApplicationComponent(UserPortalConfigService.class);
List<String> groups = userPortalConfigService.getMakableNavigations(pcontext.getRemoteUser(), true);
if (groups.size() > 0) {
ownerTypes.add(new SelectItemOption<String>(SiteType.GROUP.getName()));
}
ownerTypes.add(new SelectItemOption<String>(SiteType.USER.getName()));
UIFormSelectBox uiSelectBoxOwnerType = new UIFormSelectBox(OWNER_TYPE, OWNER_TYPE, ownerTypes);
uiSelectBoxOwnerType.setOnChange("ChangeOwnerType");
uiSettingSet.addUIFormInput(uiSelectBoxOwnerType);
ownerIdInput = new UIFormStringInput(OWNER_ID, OWNER_ID, null);
ownerIdInput.setReadOnly(true).setValue(pcontext.getRemoteUser());
uiSettingSet.addUIFormInput(ownerIdInput);
uiSettingSet
.addUIFormInput(new UIFormStringInput("name", "name", null)
.addValidator(UserConfigurableValidator.class, UserConfigurableValidator.PAGE_NAME)
.addValidator(MandatoryValidator.class))
.addUIFormInput(new UIFormStringInput("title", "title", null).addValidator(StringLengthValidator.class, 3, 120)
.addValidator(NotHTMLTagValidator.class))
.addUIFormInput(new UICheckBoxInput("showMaxWindow", "showMaxWindow", false));
addUIFormInput(uiSettingSet);
setSelectedTab(uiSettingSet.getId());
if (uiPage == null) {
UIPageTemplateOptions uiTemplateConfig = createUIComponent(UIPageTemplateOptions.class, null, null);
addUIFormInput(uiTemplateConfig);
}
if (uiPage == null
|| (!uiPage.getSiteKey().getType().equals(SiteType.USER) && getChildById("PermissionSetting") == null)) {
uiPermissionSetting = createUIComponent(UIFormInputSet.class, "PermissionSetting", null);
uiAccessPermissionSelector = createUIComponent(UIListPermissionSelector.class, null, null);
uiAccessPermissionSelector.configure(WebuiRequestContext.generateUUID("UIListPermissionSelector"), "accessPermissions");
uiAccessPermissionSelector.addValidator(EmptyIteratorValidator.class);
uiPermissionSetting.addChild(uiAccessPermissionSelector);
uiPermissionSetting.setSelectedComponent(uiAccessPermissionSelector.getId());
uiEditPermission = createUIComponent(UIPermissionSelector.class, null, null);
uiEditPermission.setRendered(false);
uiEditPermission.addValidator(org.exoplatform.webui.organization.UIPermissionSelector.MandatoryValidator.class);
uiEditPermission.setEditable(false);
uiEditPermission.configure("UIPermissionSelector", "editPermission");
uiPermissionSetting.addChild(uiEditPermission);
//build move* permission form for edit page
//for the case add new page, we'll build form in ChangeOwnerType action listener
if (uiPage != null) {
buildMovePermissionForm(uiPage.getSiteKey());
}
// TODO: This following line is fixed for bug PORTAL-2127
uiAccessPermissionSelector.getChild(UIFormPopupWindow.class).setId("UIPageFormPopupGroupMembershipSelector");
addUIFormInput(uiPermissionSetting);
uiEditPermission.setEditable(true);
}
if (uiPage != null) {
uiPage_ = uiPage;
Page page = (Page) PortalDataMapper.buildModelObject(uiPage);
invokeGetBindingBean(page);
getUIStringInput("name").setReadOnly(true);
getUIStringInput("pageId").setValue(uiPage.getPageId());
getUIStringInput("title").setValue(uiPage.getTitle());
getUICheckBoxInput("showMaxWindow").setValue(uiPage.isShowMaxWindow());
getUIFormSelectBox(OWNER_TYPE).setDisabled(true).setValue(uiPage.getSiteKey().getTypeName());
}
}
private void buildMovePermissionForm(SiteKey siteKey) throws Exception {
if(canChangeMovePermission(siteKey)) {
//Move permission
if (uiMoveAppsPermissionSelector == null) {
/* Create the widget if not there yet */
uiMoveAppsPermissionSelector = createUIComponent(UIListPermissionSelector.class, null, null);
uiMoveAppsPermissionSelector.setPublicMode(true);
uiMoveAppsPermissionSelector.configure(WebuiRequestContext.generateUUID("UIListMoveAppsPermissionSelector"), "moveAppsPermissions");
}
if (findComponentById(uiMoveAppsPermissionSelector.getId()) == null) {
/* Add the widget if not there already */
uiPermissionSetting.addChild(uiMoveAppsPermissionSelector);
}
if (uiMoveContainersPermissionSelector == null) {
/* Create the widget if not there yet */
uiMoveContainersPermissionSelector = createUIComponent(UIListPermissionSelector.class, null, null);
uiMoveContainersPermissionSelector.setPublicMode(true);
uiMoveContainersPermissionSelector.configure(WebuiRequestContext.generateUUID("UIListMoveContainersPermissionSelector"), "moveContainersPermissions");
}
if (findComponentById(uiMoveContainersPermissionSelector.getId()) == null) {
/* Add the widget if not there already */
uiPermissionSetting.addChild(uiMoveContainersPermissionSelector);
}
} else {
/* Cannot move permissions - discard the widgets */
uiPermissionSetting.setSelectedComponent(1);
if (uiMoveAppsPermissionSelector != null) {
uiPermissionSetting.removeChildById(uiMoveAppsPermissionSelector.getId());
uiMoveAppsPermissionSelector = null;
}
if (uiMoveContainersPermissionSelector != null) {
uiPermissionSetting.removeChildById(uiMoveContainersPermissionSelector.getId());
uiMoveContainersPermissionSelector = null;
}
}
}
private boolean canChangeMovePermission(SiteKey siteKey) {
boolean canEditMovePermission = false;
UserACL acl = getApplicationComponent(UserACL.class);
switch (siteKey.getType()) {
case GROUP:
canEditMovePermission = acl.hasEditPermissionOnNavigation(siteKey);
break;
case USER:
/* uses */
PortalRequestContext pcontext = Util.getPortalRequestContext();
canEditMovePermission = siteKey.getName().equals(pcontext.getRemoteUser()) || acl.isUserInGroup(acl.getAdminGroups());
break;
default:
canEditMovePermission = acl.isSuperUser() || acl.isUserInGroup(acl.getAdminGroups());
break;
}
return canEditMovePermission;
}
public static class SaveActionListener extends EventListener<UIPageForm> {
public void execute(Event<UIPageForm> event) throws Exception {
UIPageForm uiPageForm = event.getSource();
UIPortalApplication uiPortalApp = uiPageForm.getAncestorOfType(UIPortalApplication.class);
PortalRequestContext pcontext = (PortalRequestContext) event.getRequestContext();
UIMaskWorkspace uiMaskWS = uiPortalApp.getChildById(UIPortalApplication.UI_MASK_WS_ID);
UIPage uiPage = uiPageForm.getUIPage();
if (uiPage == null)
return;
Page page = new Page();
uiPageForm.invokeSetBindingBean(page);
uiPage.setAccessPermissions(page.getAccessPermissions());
uiPage.setEditPermission(page.getEditPermission());
if(uiPageForm.canChangeMovePermission(uiPage.getSiteKey())) {
uiPage.setMoveAppsPermissions(page.getMoveAppsPermissions());
uiPage.setMoveContainersPermissions(page.getMoveContainersPermissions());
} else {
/* set defaults if the page does not exist yet */
UserPortalConfigService configService = uiPageForm.getApplicationComponent(UserPortalConfigService.class);
PageKey pageKey = new PageKey(new SiteKey(page.getOwnerType(), page.getOwnerId()), page.getName());
if (configService.getPageService().loadPage(pageKey) == null) {
configService.setDefaultPermissions(page);
uiPage.setMoveAppsPermissions(page.getMoveAppsPermissions());
uiPage.setMoveContainersPermissions(page.getMoveContainersPermissions());
}
}
uiPage.setTitle(page.getTitle());
uiPage.setShowMaxWindow(page.isShowMaxWindow());
uiMaskWS.createEvent("Close", Phase.DECODE, pcontext).broadcast();
pcontext.getJavascriptManager().require("SHARED/portalComposer", "portalComposer")
.addScripts("portalComposer.toggleSaveButton();");
UIPortalComposer portalComposer = uiPortalApp.findFirstComponentOfType(UIPortalComposer.class);
portalComposer.updateWorkspaceComponent();
pcontext.ignoreAJAXUpdateOnPortlets(true);
}
protected void findAllPortlet(List<UIPortlet<?, ?>> list, UIContainer uiContainer) {
List<UIComponent> children = uiContainer.getChildren();
for (UIComponent ele : children) {
if (ele instanceof UIPortlet)
list.add((UIPortlet<?, ?>) ele);
else if (ele instanceof UIContainer)
findAllPortlet(list, (UIContainer) ele);
}
}
}
public static class ChangeOwnerTypeActionListener extends EventListener<UIPageForm> {
public void execute(Event<UIPageForm> event) throws Exception {
UIPageForm uiForm = event.getSource();
UIFormSelectBox uiSelectBox = uiForm.getUIFormSelectBox(OWNER_TYPE);
String ownerType = uiSelectBox.getValue();
PortalRequestContext prContext = Util.getPortalRequestContext();
UIFormInputSet uiSettingSet = uiForm.getChildById("PageSetting");
uiForm.setSelectedTab("PageSetting");
List<UIComponent> list = uiSettingSet.getChildren();
String ownerId = null;
if (SiteType.PORTAL.getName().equals(ownerType)) {
ownerId = prContext.getPortalOwner();
list.remove(2);
list.add(2, uiForm.ownerIdInput);
uiForm.ownerIdInput.setValue(ownerId);
} else if (SiteType.GROUP.getName().equals(ownerType)) {
list.remove(2);
uiForm.loadMakableGroupNavigations();
list.add(2, uiForm.groupIdSelectBox);
ownerId = uiForm.groupIdSelectBox.getValue();
} else {
/* if you feel something should happen for SiteType.USER, change this accordingly */
throw new IllegalStateException("Unexpected page owner type '"+ ownerType +"'.");
}
uiForm.buildMovePermissionForm(new SiteKey(ownerType, ownerId));
uiForm.setDefaultPermissions(ownerType, ownerId);
prContext.addUIComponentToUpdateByAjax(uiForm.getParent());
}
}
public static class ChangeOwnerIdActionListener extends EventListener<UIPageForm> {
public void execute(Event<UIPageForm> event) throws Exception {
UIPageForm uiForm = event.getSource();
UIFormSelectBox uiSelectBox = uiForm.getUIFormSelectBox(OWNER_TYPE);
String ownerType = uiSelectBox.getValue();
uiForm.buildMovePermissionForm(new SiteKey(ownerType, uiForm.ownerIdInput.getValue()));
if (SiteType.GROUP.getName().equals(ownerType)) {
String ownerId = uiForm.groupIdSelectBox.getValue();
uiForm.setDefaultPermissions(ownerType, ownerId);
} else {
/* this handler should be called only on change of groupIdSelectBox
* everything else is unexpected */
throw new IllegalStateException("Unexpected page owner type '"+ ownerType +"'.");
}
event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getParent());
}
}
public static class SelectMembershipActionListener extends EventListener<UIGroupMembershipSelector> {
public void execute(Event<UIGroupMembershipSelector> event) throws Exception {
UIPageForm uiForm = event.getSource().getAncestorOfType(UIPageForm.class);
event.getRequestContext().addUIComponentToUpdateByAjax(uiForm.getParent());
}
}
/**
* @param ownerType
* @param ownerId
* @throws Exception
*
*/
public void setDefaultPermissions(String ownerType, String ownerId) throws Exception {
Page page = null;
UIPageTemplateOptions uiConfigOptions = getChild(UIPageTemplateOptions.class);
if (uiConfigOptions != null) {
/* This will initialize the move*Permissions from the page.xml template */
page = uiConfigOptions.createPageFromSelectedOption(ownerType, ownerId);
}
if (page == null) {
page = new Page(ownerType, ownerId, "fake");
}
UserPortalConfigService configService = getApplicationComponent(UserPortalConfigService.class);
configService.setDefaultPermissions(page);
uiAccessPermissionSelector.setValue(page.getAccessPermissions());
uiEditPermission.setValue(page.getEditPermission());
if (uiMoveAppsPermissionSelector != null) {
uiMoveAppsPermissionSelector.setValue(page.getMoveAppsPermissions());
}
if (uiMoveContainersPermissionSelector != null) {
uiMoveContainersPermissionSelector.setValue(page.getMoveContainersPermissions());
}
}
}