BuildLinkUtils.java
/*
* Copyright (C) 2003-2013 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.forum.ext.activity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.forum.common.CommonUtils;
import org.exoplatform.forum.service.Utils;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.model.ModelObject;
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.mop.navigation.NavigationContext;
import org.exoplatform.portal.mop.navigation.NavigationService;
import org.exoplatform.portal.mop.navigation.NodeContext;
import org.exoplatform.portal.mop.navigation.NodeModel;
import org.exoplatform.portal.mop.navigation.Scope;
import org.exoplatform.portal.mop.user.UserNavigation;
import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.portal.mop.user.UserPortal;
import org.exoplatform.portal.pom.data.ApplicationData;
import org.exoplatform.portal.pom.data.ComponentData;
import org.exoplatform.portal.pom.data.ContainerData;
import org.exoplatform.portal.pom.data.ModelData;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.social.core.space.SpaceUtils;
import org.exoplatform.social.core.space.model.Space;
import org.exoplatform.web.application.RequestContext;
import org.exoplatform.web.url.navigation.NavigationResource;
import org.exoplatform.web.url.navigation.NodeURL;
public class BuildLinkUtils {
public static final String SPACES_GROUP = SpaceUtils.SPACE_GROUP.substring(1);
public static final String CATEGORY = "category";
private static final Map<String, String> forumLinkData = new ConcurrentHashMap<String, String>();
public enum PORTLET_INFO {
FORUM("ForumPortlet", "Forum Portlet", "forum"),
POLL("PollPortlet", "Polls Portlet", "poll"),
ANSWER("AnswersPortlet", "Answers Portlet", "answers");
final private String name, description, pageId;
PORTLET_INFO(String name, String description, String pageId) {
this.name = name;
this.pageId = pageId;
this.description = description;
}
public String getName() {
return name;
}
public String getPageId() {
return pageId;
}
public String getDescription() {
return description;
}
}
private static String getType(String objectId) {
if (objectId.indexOf(Utils.POST) == 0)
return Utils.POST;
if (objectId.indexOf(Utils.TOPIC) == 0)
return Utils.TOPIC;
if (objectId.indexOf(Utils.FORUM) == 0)
return Utils.FORUM;
if (objectId.indexOf(Utils.POLL) == 0)
return Utils.POLL;
return "";
}
/**
* Check object to rendering is on space or not
*
* @param objectId The objectId
* + if objectId contain the id of the group on space then return true
* + if objectId is id of the forum on space then return true
* + if objectId is id of the forum category on space then return true
* + if objectId is id of the answer category on space then return true
* @return
*/
private static boolean isInSpace(String objectId) {
if (objectId.indexOf(SpaceUtils.SPACE_GROUP) >= 0)
return true;
if (objectId.indexOf(Utils.FORUM_SPACE_ID_PREFIX) == 0)
return true;
if (objectId.indexOf(Utils.CATEGORY_SPACE_ID_PREFIX) == 0)
return true;
return false;
}
private static String getGroupId(String parentObjectId, PORTLET_INFO portletInfo) {
StringBuffer spaceGroupId = new StringBuffer();
if (parentObjectId.indexOf(SpaceUtils.SPACE_GROUP) == 0) {
spaceGroupId.append(parentObjectId);
} else {
spaceGroupId.append("/").append(SPACES_GROUP).append("/");
spaceGroupId.append(parentObjectId.replace(Utils.FORUM_SPACE_ID_PREFIX, ""));
}
return spaceGroupId.toString();
}
public static String buildLink(String parentObjectId, String objectId, PORTLET_INFO portletInfo) {
return buildLink(parentObjectId, objectId, portletInfo, CommonsUtils.getCurrentSite().getName());
}
public static String buildLink(String parentObjectId, String objectId, PORTLET_INFO portletInfo, String siteName) {
if(CommonUtils.isEmpty(objectId)) {
return "#";
}
try {
String link = "";
String objectType = getType(objectId);
//
if (isInSpace(parentObjectId)) {
link = buildSpaceLink(getGroupId(parentObjectId, portletInfo), objectType, objectId, portletInfo);
} else {
//caching the topic link
String forumLink = getPublicForumLink(getType(objectType));
if (PORTLET_INFO.FORUM.equals(portletInfo) && forumLink != null && forumLink.length() > 0) {
return new StringBuffer(forumLink).append(buildLink_(objectType, objectId, portletInfo)).toString();
}
PortalRequestContext prc = Util.getPortalRequestContext();
if (!CommonUtils.isEmpty(siteName) && !prc.getSiteKey().getName().equals(siteName)) {
SiteKey siteKey = SiteKey.portal(siteName);
String nodeURI = getSiteName(siteKey, portletInfo);
//
if (!CommonUtils.isEmpty(nodeURI)) {
link = new StringBuffer(getSiteHomeURL(siteName, nodeURI)).append(buildLink_(objectType, objectId, portletInfo)).toString();
}
} else {
UserPortal userPortal = prc.getUserPortal();
UserNavigation userNav = userPortal.getNavigation(prc.getSiteKey());
UserNode rootNode = userPortal.getNode(userNav, Scope.ALL, null, null);
UserNode portletNode = getPortletNode(rootNode, portletInfo);
if (portletNode != null) {
forumLink = getNodeURL(portletNode);
//
setPublicForumLink(getType(objectType), forumLink);
link = new StringBuffer(forumLink).append(buildLink_(objectType, objectId, portletInfo)).toString();
}
}
}
//
return link;
} catch (Exception ex) {
return "";
}
}
/**
* Try to find the node that contains the application match with the id
*
* @param rootNode
* @param id id of the portlet to find
* @return the usernode associated to the app's id
*/
private static UserNode getPortletNode(UserNode rootNode, PORTLET_INFO portletInfo) {
DataStorage dataStorage = CommonsUtils.getService(DataStorage.class);
for (UserNode node : rootNode.getChildren()) {
Page page;
try {
page = dataStorage.getPage(node.getPageRef().format());
} catch (Exception e) {
continue;
}
List<ComponentData> dataModels = new ArrayList<ComponentData>();
for (ModelObject model : page.getChildren()) {
ModelData modelData = model.build();
if (modelData instanceof ComponentData) {
dataModels.add((ComponentData) modelData);
}
}
if (getUserNode(dataModels, portletInfo)) {
return node;
}
if (node.getChildrenSize() > 0) {
UserNode child = getPortletNode(node, portletInfo);
if (child != null) return child;
}
}
return null;
}
private static Boolean getUserNode(List<ComponentData> models, PORTLET_INFO portletInfo) {
for (ModelData modelData : models) {
if (modelData instanceof ApplicationData) {
ApplicationData<?> applicationData = (ApplicationData<?>) modelData;
if ((applicationData.getDescription() != null
&& applicationData.getDescription().equals(portletInfo.getDescription()))
|| (applicationData.getTitle() != null
&& applicationData.getTitle().equals(portletInfo.getDescription()))) {
return true;
}
} else if (modelData instanceof ContainerData) {
ContainerData containerData = (ContainerData) modelData;
List<ComponentData> models_ = containerData.getChildren();
return getUserNode(models_, portletInfo);
}
}
return false;
}
private static String getNodeURL(UserNode node) {
RequestContext ctx = RequestContext.getCurrentInstance();
NodeURL nodeURL = ctx.createURL(NodeURL.TYPE);
return nodeURL.setNode(node).toString();
}
private static String buildLink_(String objectType, String objectId, PORTLET_INFO portletInfo) {
StringBuffer buffer = new StringBuffer();
return buffer.append("/").append(objectType).append("/").append(objectId).toString();
}
private static String buildSpaceLink(String spaceGroupId, String objectType, String objectId, PORTLET_INFO portletInfo) throws Exception {
String nodeURI = getSiteName(SiteKey.group(spaceGroupId), portletInfo);
if (!CommonUtils.isEmpty(nodeURI)) {
Space space = ForumActivityUtils.getSpaceService().getSpaceByGroupId(spaceGroupId);
String spaceLink = org.exoplatform.social.webui.Utils.getSpaceHomeURL(space);
StringBuffer buffer = new StringBuffer(spaceLink).append("/").append(nodeURI);
return buffer.append(buildLink_(objectType, objectId, portletInfo)).toString();
}
return CommonUtils.EMPTY_STR;
}
private static String getSiteName(SiteKey siteKey, PORTLET_INFO portletInfo) {
NavigationService navService = CommonsUtils.getService(NavigationService.class);
NavigationContext nav = navService.loadNavigation(siteKey);
NodeContext<NodeContext<?>> parentNodeCtx = navService.loadNode(NodeModel.SELF_MODEL, nav, Scope.ALL, null);
if (parentNodeCtx.getSize() >= 1) {
Collection<NodeContext<?>> children = parentNodeCtx.getNodes();
if (siteKey.getType() == SiteType.GROUP) {
children = parentNodeCtx.get(0).getNodes();
}
Iterator<NodeContext<?>> it = children.iterator();
NodeContext<?> child = null;
while (it.hasNext()) {
child = it.next();
if (portletInfo.getPageId().indexOf(child.getName()) == 0 ||
child.getName().indexOf(portletInfo.getName()) >= 0) {
return child.getName();
}
}
}
return CommonUtils.EMPTY_STR;
}
private static String getSiteHomeURL(String siteName, String nodeURI) {
NodeURL nodeURL = RequestContext.getCurrentInstance().createURL(NodeURL.TYPE);
NavigationResource resource = new NavigationResource(SiteType.PORTAL, siteName, nodeURI);
return nodeURL.setResource(resource).toString();
}
private static String getPublicForumLink(String portletType) {
String currentRepositoryName = CommonsUtils.getRepository().getConfiguration().getName();
return forumLinkData.get(portletType + "_" + currentRepositoryName);
}
private static void setPublicForumLink(String portletType, String forumLink) {
String currentRepositoryName = CommonsUtils.getRepository().getConfiguration().getName();
forumLinkData.put(portletType + "_" + currentRepositoryName, forumLink);
}
}