001/*
002 * (C) Copyright 2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 * Contributors:
014 *     Nuxeo - initial API and implementation
015 */
016
017package org.nuxeo.ecm.platform.shibboleth.web.tree;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.nuxeo.ecm.core.api.DocumentModel;
023import org.nuxeo.ecm.platform.shibboleth.web.service.ShibbolethGroupsService;
024import org.nuxeo.runtime.api.Framework;
025
026/**
027 * Helper class to provide some method with UserTreeNode
028 *
029 * @author <a href="mailto:akervern@nuxeo.com">Arnaud Kervern</a>
030 * @see org.nuxeo.ecm.platform.shibboleth.web.tree.UserTreeNode
031 */
032public class UserTreeNodeHelper {
033
034    /**
035     * Build UserTreeNode Tree by parsing the name of all docs passed by argument. It uses Shibboleth Service parse char
036     * definition to split doc name.
037     *
038     * @param docs list groups that want to be parsed
039     * @return tree built, and an empty list if docs is null or empty.
040     */
041    public static List<UserTreeNode> getHierarcicalNodes(List<DocumentModel> docs) {
042        List<UserTreeNode> root = new ArrayList<UserTreeNode>();
043
044        if (docs == null || docs.size() == 0) {
045            return root;
046        }
047
048        String previousBasePath = null;
049        List<DocumentModel> nodesToCreate = new ArrayList<DocumentModel>();
050        for (DocumentModel doc : docs) {
051            String id = doc.getId();
052            int pos = id.lastIndexOf(getParseString());
053
054            String currentBasePath;
055            if (pos < 0) {
056                currentBasePath = "";
057            } else {
058                currentBasePath = id.substring(0, pos + getParseStringLength());
059            }
060
061            if (previousBasePath != null && !currentBasePath.equals(previousBasePath)) {
062                appendNodes(root, previousBasePath, nodesToCreate);
063                nodesToCreate = new ArrayList<DocumentModel>();
064            }
065            nodesToCreate.add(doc);
066            previousBasePath = currentBasePath;
067        }
068        appendNodes(root, previousBasePath, nodesToCreate);
069
070        return root;
071    }
072
073    /**
074     * Append and create UserTreeNode from nodesToCreate list to the rootList. It create or use defined node in the root
075     * to create wanted nodes.
076     *
077     * @param root the root UserNodeTree List, may contains some part of the destination path
078     * @param destinationPath destination path, not splitted.
079     * @param nodesToCreate list of documentModel to be created at the destination path
080     */
081    protected static void appendNodes(List<UserTreeNode> root, String destinationPath, List<DocumentModel> nodesToCreate) {
082        UserTreeNode currentNode = null;
083
084        if (nodesToCreate == null || nodesToCreate.size() < 1) {
085            return;
086        }
087
088        if (destinationPath == null || destinationPath.equals("")) {
089            root.addAll(UserTreeNode.constructNodes(nodesToCreate));
090            return;
091        }
092
093        for (String path : destinationPath.split(getParseString())) {
094            UserTreeNode node = searchNode(currentNode == null ? root : currentNode.getChildrens(), path);
095            if (node == null) {
096                node = new UserTreeNode(path);
097                if (currentNode == null) {
098                    root.add(node);
099                } else {
100                    currentNode.addChildren(node);
101                }
102            }
103            currentNode = node;
104        }
105
106        assert currentNode != null;
107        currentNode.getChildrens().addAll(UserTreeNode.constructNodes(nodesToCreate));
108    }
109
110    /**
111     * Search a Node where param name is equals to the nodeId
112     *
113     * @return null if not found
114     */
115    protected static UserTreeNode searchNode(List<UserTreeNode> from, String name) {
116        for (UserTreeNode node : from) {
117            if (node.getId().equals(name)) {
118                return node;
119            }
120        }
121        return null;
122    }
123
124    public static List<UserTreeNode> buildBranch(String branch, List<DocumentModel> docs) {
125        List<UserTreeNode> nodeBranch = new ArrayList<UserTreeNode>();
126        appendNodes(nodeBranch, branch, docs);
127        return nodeBranch;
128    }
129
130    public static String getParseString() {
131        return getService().getParseString();
132    }
133
134    public static int getParseStringLength() {
135        String str = getService().getParseString();
136        return str == null ? -1 : str.length();
137    }
138
139    public static String getShibbGroupBasePath() {
140        return getService().getShibbGroupBasePath();
141    }
142
143    protected static ShibbolethGroupsService getService() {
144        return Framework.getService(ShibbolethGroupsService.class);
145    }
146
147}