package org.exoplatform.platform.component; import org.apache.commons.lang.StringUtils; import org.exoplatform.commons.utils.ListAccess; import org.exoplatform.container.PortalContainer; import org.exoplatform.portal.application.PortalRequestContext; import org.exoplatform.portal.application.RequestNavigationData; import org.exoplatform.portal.mop.user.UserNavigation; import org.exoplatform.portal.mop.user.UserNode; import org.exoplatform.portal.webui.util.Util; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.social.core.space.SpaceUtils; import org.exoplatform.social.core.space.model.Space; import org.exoplatform.social.core.space.spi.SpaceService; import org.exoplatform.social.webui.Utils; import org.exoplatform.webui.config.annotation.ComponentConfig; import org.exoplatform.webui.config.annotation.EventConfig; import org.exoplatform.webui.core.UIComponent; import org.exoplatform.webui.core.UIPortletApplication; import org.exoplatform.webui.core.lifecycle.UIApplicationLifecycle; import org.exoplatform.webui.event.Event; import org.exoplatform.webui.event.EventListener; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * @author <a href="rtouzi@exoplatform.com">rtouzi</a> */ @ComponentConfig(lifecycle = UIApplicationLifecycle.class, template = "app:/groovy/platformNavigation/portlet/UISpaceNavigationPortlet/UISpaceNavigationPortlet.gtmpl", events = { @EventConfig(listeners = UISpaceNavigationPortlet.IncrementActionListener.class), @EventConfig(listeners = UISpaceNavigationPortlet.SelectSpaceActionListener.class) } ) public class UISpaceNavigationPortlet extends UIPortletApplication { private static final Log LOG = ExoLogger.getLogger(UISpaceNavigationPortlet.class); private static final String MY_SPACE_REST_URL = "/space/user/searchSpace/"; private static final String SPACE_URL_PATTERN = ":spaces"; private SpaceService spaceService = null; private ListAccess<Space> spaceListAccess; private LinkedList<Space> spaceList = new LinkedList<Space>(); private static final int MY_SPACES_MAX_NUMBER = 10; private static String portalContainerName = ""; private int offset = 0; private boolean reload = false; private String oldNavigation = null; private String currentNavigation = null; private String selectedSpaceId = null; private String userId = null; public UISpaceNavigationPortlet() throws Exception { try { spaceService = ((SpaceService)getApplicationComponent(SpaceService.class)); portalContainerName = PortalContainer.getCurrentPortalContainerName(); if (spaceService != null) { this.spaceListAccess = spaceService.getLastAccessedSpace(getUserId(), null); setReload(true); } setOldNavigation(Util.getPortalRequestContext().getRequest().getRequestURI()); } catch (Exception exception) { LOG.error("SpaceService could be 'null' when the Social profile isn't activated ", exception); } } /** * * @return */ public List<Space> getSpaces() { Space space = Utils.getSpaceByContext(); if (space != null) { putTop(space); } // Workaround to load only the 10 first space in the next iteration if (selectedSpaceId != null) { setSelectedSpaceId(null); } int from = 0; int to = this.offset + MY_SPACES_MAX_NUMBER; if (to >= this.spaceList.size()) { return this.spaceList; } return this.spaceList.subList(from, to); } /** * Refresh loaded spaces in left component UI * @throws Exception */ public void refresh() throws Exception { setCurrentNavigation(Util.getPortalRequestContext().getRequest().getRequestURI()); boolean navChanged = getCurrentNavigation().equals(getOldNavigation()); if ((this.reload && selectedSpaceId == null) || !navChanged) { this.spaceList.clear(); this.offset = 0; loadSpaces(); } setOldNavigation(getCurrentNavigation()); } /** * Complete the rendered Spaces list with the 10 next spaces * @throws Exception */ private void loadSpaces() throws Exception { if (spaceListAccess != null) { this.spaceList.addAll(Arrays.asList(spaceListAccess.load(this.offset, MY_SPACES_MAX_NUMBER))); } } public Space putTop(String spaceId) { selectedSpaceId = spaceId; Space space = new Space(); space.setId(spaceId); return putTop(space); } private Space putTop(Space space) { int idx = this.spaceList.indexOf(space); Space got = null; if (idx >= 0) { got = this.spaceList.remove(idx); } else { got = Utils.getSpaceService().getSpaceById(space.getId()); } this.spaceList.addFirst(got); return got; } public int numberOfRemainSpaces() throws Exception { if (spaceListAccess != null) { int to = this.offset + MY_SPACES_MAX_NUMBER; int newLimit = Math.min(to, this.spaceList.size()); return spaceListAccess.getSize() - newLimit; } return 0; } private String getUserId() { if (userId == null) { userId = Util.getPortalRequestContext().getRemoteUser(); } return userId; } /** * Builds the Space URI * @param space * @return * @throws Exception */ public String buildSpaceURL(Space space) throws Exception { return Utils.getSpaceHomeURL(space); } public Boolean isSelectedSpace(Space space) throws Exception { String groupId = Util.getPortalRequestContext().getControllerContext().getParameter(RequestNavigationData.REQUEST_SITE_NAME); return space.getGroupId().equalsIgnoreCase(groupId); } public static class SelectSpaceActionListener extends EventListener<UISpaceNavigationPortlet> { public void execute(Event<UISpaceNavigationPortlet> event) throws Exception { PortalRequestContext pContext = Util.getPortalRequestContext(); UISpaceNavigationPortlet uisource = (UISpaceNavigationPortlet) event.getSource(); String spaceId = event.getRequestContext().getRequestParameter(UIComponent.OBJECTID); Space space = uisource.putTop(spaceId); //--- Get the space URL using reouter API String spaceURL = Utils.getSpaceHomeURL(space); //---- Get only the GROUP navigation if (spaceURL.contains(portalContainerName)) { spaceURL = spaceURL.substring(portalContainerName.length()+2); } String fullUrl = ((HttpServletRequest) pContext.getRequest()).getRequestURL().toString(); String subUrl = StringUtils.substringBefore(fullUrl,Util.getPortalRequestContext().getRequest().getRequestURI()); subUrl +="/"+ portalContainerName; String applicationDisplayed = ""; String constructURL = fullUrl.substring(subUrl.length()+1); subUrl =new StringBuffer(subUrl).append("/").append(spaceURL).toString(); if (fullUrl.contains(SPACE_URL_PATTERN)) { int count = StringUtils.countMatches(constructURL, "/"); if(count != 2){ applicationDisplayed = constructURL.substring(constructURL.lastIndexOf("/") + 1); String selectedAppNodeName = uisource.checkAndGetExistingAppNodeName(space, applicationDisplayed); if (selectedAppNodeName != null) subUrl =new StringBuffer(subUrl).append("/").append(selectedAppNodeName).toString(); } } uisource.setReload(true); event.getRequestContext().getJavascriptManager().getRequireJS().require("SHARED/navigation-spaces-search", "spaceSearchNavigationPortlet").addScripts("spaceSearchNavigationPortlet.ajaxRedirect('"+subUrl+"');"); } } public static class IncrementActionListener extends EventListener<UISpaceNavigationPortlet> { public void execute(Event<UISpaceNavigationPortlet> event) throws Exception { HttpServletRequest request = Util.getPortalRequestContext().getRequest(); UISpaceNavigationPortlet uisource = (UISpaceNavigationPortlet) event.getSource(); uisource.loadMore(MY_SPACES_MAX_NUMBER); uisource.setReload(false); event.getRequestContext().addUIComponentToUpdateByAjax(uisource); } } protected String getRestUrl() { return getCurrentRestURL().concat(MY_SPACE_REST_URL); } public static String getCurrentRestURL() { StringBuilder sb = new StringBuilder(); sb.append("/").append(PortalContainer.getCurrentPortalContainerName()).append("/"); sb.append(PortalContainer.getCurrentRestContextName()); return sb.toString(); } public void loadMore(int capacity) throws Exception { this.offset += capacity; loadSpaces(); } public void setReload(boolean reload) { this.reload = reload; } public void setSelectedSpaceId(String selectedSpaceId) { this.selectedSpaceId = selectedSpaceId; } public String getCurrentNavigation() { return currentNavigation; } public void setCurrentNavigation(String currentNavigation) { this.currentNavigation = currentNavigation; } public String getOldNavigation() { return oldNavigation; } public void setOldNavigation(String oldNavigation) { this.oldNavigation = oldNavigation; } private String checkAndGetExistingAppNodeName(Space space, String appId) throws Exception { if (appId == null) return null; String groupId = space.getGroupId(); UserNavigation userNav = SpaceUtils.getGroupNavigation(groupId); UserNode homeNode = SpaceUtils.getHomeNodeWithChildren(userNav, space.getUrl()); for (UserNode node : homeNode.getChildren()) { if (appId.equals(node.getName())) return appId; } // in case application name has been changed String leftSpaceGroupId = Util.getPortalRequestContext() .getControllerContext().getParameter(RequestNavigationData.REQUEST_SITE_NAME); Space leftSpace = spaceService.getSpaceByGroupId(leftSpaceGroupId); String[] leftSpaceApps = leftSpace.getApp().split(","); String selectedAppId = ""; for (String app : leftSpaceApps) { if (app.contains(appId.replace("_", " "))) { selectedAppId = app.split(":")[0]; break; } } if (selectedAppId.isEmpty()) return null; String[] spaceApps = space.getApp().split(","); for (String spaceApp : spaceApps) { if (spaceApp.contains(selectedAppId)) return spaceApp.split(":")[1].replace(" ", "_"); } return null; } }