/* * Copyright (C) 2010 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.mop.user; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; import org.exoplatform.portal.config.UserPortalConfigService; import org.exoplatform.portal.config.model.PortalConfig; import org.exoplatform.portal.mop.SiteKey; import org.exoplatform.portal.mop.SiteType; import org.exoplatform.portal.mop.navigation.GenericScope; import org.exoplatform.portal.mop.navigation.NavigationContext; import org.exoplatform.portal.mop.navigation.NavigationServiceException; import org.exoplatform.portal.mop.navigation.NodeChangeListener; import org.exoplatform.portal.mop.navigation.NodeContext; import org.exoplatform.portal.mop.navigation.NodeState; import org.exoplatform.portal.mop.navigation.Scope; import org.exoplatform.portal.mop.navigation.VisitMode; import org.exoplatform.services.organization.Group; /** * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> * @version $Revision$ */ public class UserPortalImpl implements UserPortal { /** . */ final UserPortalConfigService service; /** . */ private final PortalConfig portal; /** . */ final UserPortalContext context; /** . */ final String userName; /** . */ private List<UserNavigation> navigations; /** . */ private final String portalName; /** . */ private final Locale portalLocale; public UserPortalImpl( UserPortalConfigService service, String portalName, PortalConfig portal, String userName, UserPortalContext context) { if (context == null) { throw new NullPointerException("No null context argument allowed"); } // String locale = portal.getLocale(); // this.portalLocale = locale != null ? new Locale(locale) : null; this.service = service; this.portalName = portalName; this.portal = portal; this.userName = userName; this.context = context; this.navigations = null; } public Locale getLocale() { return portalLocale; } /** * Returns an immutable sorted list of the valid navigations related to the user. * * @return the navigations * @throws UserPortalException any user portal exception */ public List<UserNavigation> getNavigations() throws UserPortalException, NavigationServiceException { if (navigations == null) { List<UserNavigation> navigations = new ArrayList<UserNavigation>(userName == null ? 1 : 10); NavigationContext portalNav = service.getNavigationService().loadNavigation(new SiteKey(SiteType.PORTAL, portalName)); if (portalNav != null && portalNav.getState() != null) { navigations.add(new UserNavigation(this, portalNav, service.getUserACL().hasEditPermission(portal))); } // if (userName != null) { // Add user nav if any NavigationContext userNavigation = service.getNavigationService().loadNavigation(SiteKey.user(userName)); if (userNavigation != null && userNavigation.getState() != null) { navigations.add(new UserNavigation(this, userNavigation, true)); } // Collection<?> groups; try { if (service.getUserACL().getSuperUser().equals(userName)) { groups = service.getOrganizationService().getGroupHandler().getAllGroups(); } else { groups = service.getOrganizationService().getGroupHandler().findGroupsOfUser(userName); } } catch (Exception e) { throw new UserPortalException("Could not retrieve groups", e); } // for (Object group : groups) { Group m = (Group)group; String groupId = m.getId().trim(); if (!groupId.equals(service.getUserACL().getGuestsGroup())) { NavigationContext groupNavigation = service.getNavigationService().loadNavigation(SiteKey.group(groupId)); if (groupNavigation != null && groupNavigation.getState() != null) { navigations.add(new UserNavigation( this, groupNavigation, service.getUserACL().hasEditPermissionOnNavigation(groupNavigation.getKey()))); } } } // Sort the list finally Collections.sort(navigations, new Comparator<UserNavigation>() { public int compare(UserNavigation nav1, UserNavigation nav2) { return nav1.getPriority() - nav2.getPriority(); } }); } // this.navigations = Collections.unmodifiableList(navigations); } return navigations; } public UserNavigation getNavigation(SiteKey key) throws NullPointerException, UserPortalException, NavigationServiceException { if (key == null) { throw new NullPointerException("No null key accepted"); } for (UserNavigation navigation : getNavigations()) { if (navigation.getKey().equals(key)) { return navigation; } } // return null; } public void refresh() { navigations = null; } public UserNode getNode( UserNavigation userNavigation, Scope scope, UserNodeFilterConfig filterConfig, NodeChangeListener<UserNode> listener) throws NullPointerException, UserPortalException, NavigationServiceException { UserNodeContext context = new UserNodeContext(userNavigation, filterConfig); NodeContext<UserNode> nodeContext = service.getNavigationService().loadNode(context, userNavigation.navigation, scope, new UserNodeListener(listener)); if (nodeContext != null) { return nodeContext.getNode().filter(); } else { return null; } } public void updateNode(UserNode node, Scope scope, NodeChangeListener<UserNode> listener) throws NullPointerException, IllegalArgumentException, UserPortalException, NavigationServiceException { if (node == null) { throw new NullPointerException("No null node accepted"); } service.getNavigationService().updateNode(node.context, scope, new UserNodeListener(listener)); node.filter(); } public void rebaseNode(UserNode node, Scope scope, NodeChangeListener<UserNode> listener) throws NullPointerException, IllegalArgumentException, UserPortalException, NavigationServiceException { if (node == null) { throw new NullPointerException("No null node accepted"); } service.getNavigationService().rebaseNode(node.context, scope, new UserNodeListener(listener)); node.filter(); } public void saveNode(UserNode node, NodeChangeListener<UserNode> listener) throws NullPointerException, UserPortalException, NavigationServiceException { if (node == null) { throw new NullPointerException("No null node accepted"); } service.getNavigationService().saveNode(node.context, new UserNodeListener(listener)); node.filter(); } /** * Note : the scope implementation is not stateless but we don't care in this case. */ private class MatchingScope extends GenericScope.Branch.Visitor implements Scope { final UserNavigation userNavigation; final UserNodeFilterConfig filterConfig; final String[] match; int score; String id; UserNode userNode; MatchingScope(UserNavigation userNavigation, UserNodeFilterConfig filterConfig, String[] match) { this.userNavigation = userNavigation; this.filterConfig = filterConfig; this.match = match; } public Visitor get() { return this; } @Override protected int getSize() { return match.length; } @Override protected String getName(int index) { return match[index]; } @Override protected Visitor getFederated() { return Scope.CHILDREN.get(); } void resolve() throws NavigationServiceException { UserNodeContext context = new UserNodeContext(userNavigation, filterConfig); NodeContext<UserNode> nodeContext = service.getNavigationService().loadNode(context, userNavigation.navigation, this, null); if (context != null) { if (score > 0) { userNode = nodeContext.getNode().filter().find(id); } } } public VisitMode enter(int depth, String id, String name, NodeState state) { VisitMode vm = super.enter(depth, id, name, state); if (depth == 0) { score = 0; MatchingScope.this.id = null; } else { if (vm == VisitMode.ALL_CHILDREN) { MatchingScope.this.id = id; score++; } } return vm; } } public UserNode getDefaultPath(UserNodeFilterConfig filterConfig) throws UserPortalException, NavigationServiceException { for (UserNavigation userNavigation : getNavigations()) { UserNode node = getDefaultPath(userNavigation, filterConfig); if (node != null) { return node; } } // return null; } public UserNode getDefaultPath(UserNavigation userNavigation, UserNodeFilterConfig filterConfig) throws UserPortalException, NavigationServiceException { NavigationContext navigation = userNavigation.navigation; if (navigation.getState() != null) { UserNodeContext context = new UserNodeContext(userNavigation, filterConfig); NodeContext<UserNode> nodeContext = service.getNavigationService().loadNode(context, navigation, Scope.CHILDREN, null); if (nodeContext != null) { UserNode root = nodeContext.getNode().filter(); for (UserNode node : root.getChildren()) { return node; } } } return null; } public UserNode resolvePath(UserNodeFilterConfig filterConfig, String path) throws NullPointerException, UserPortalException, NavigationServiceException { if (path == null) { throw new NullPointerException("No null path accepted"); } // Parse path String[] segments = Utils.parsePath(path); // Find the first navigation available or return null if (segments == null) { return getDefaultPath(filterConfig); } // Get navigations List<UserNavigation> navigations = getNavigations(); // MatchingScope best = null; for (UserNavigation navigation : navigations) { MatchingScope scope = new MatchingScope(navigation, filterConfig, segments); scope.resolve(); if (scope.score == segments.length) { best = scope; break; } else { if (best == null) { best = scope; } else { if (scope.score > best.score) { best = scope; } } } } // if (best != null && best.score > 0) { return best.userNode; } else { return getDefaultPath(null); } } public UserNode resolvePath(UserNavigation navigation, UserNodeFilterConfig filterConfig, String path) throws NullPointerException, UserPortalException, NavigationServiceException { if (navigation == null) { throw new NullPointerException("No null navigation accepted"); } if (path == null) { throw new NullPointerException("No null path accepted"); } // String[] segments = Utils.parsePath(path); // if (segments == null) { return null; } // MatchingScope scope = new MatchingScope(navigation, filterConfig, segments); scope.resolve(); // if (scope.score > 0) { return scope.userNode; } else { return null; } } }