001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 * Contributors:
016 *     Nuxeo - initial API and implementation
017 */
018
019package org.nuxeo.ecm.platform.shibboleth.web.tree;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import org.nuxeo.ecm.core.api.DocumentModel;
025import org.nuxeo.ecm.platform.shibboleth.web.service.ShibbolethGroupsService;
026import org.nuxeo.runtime.api.Framework;
027
028/**
029 * Helper class to provide some method with UserTreeNode
030 *
031 * @author <a href="mailto:akervern@nuxeo.com">Arnaud Kervern</a>
032 * @see org.nuxeo.ecm.platform.shibboleth.web.tree.UserTreeNode
033 */
034public class UserTreeNodeHelper {
035
036    /**
037     * Build UserTreeNode Tree by parsing the name of all docs passed by argument. It uses Shibboleth Service parse char
038     * definition to split doc name.
039     *
040     * @param docs list groups that want to be parsed
041     * @return tree built, and an empty list if docs is null or empty.
042     */
043    public static List<UserTreeNode> getHierarcicalNodes(List<DocumentModel> docs) {
044        List<UserTreeNode> root = new ArrayList<UserTreeNode>();
045
046        if (docs == null || docs.size() == 0) {
047            return root;
048        }
049
050        String previousBasePath = null;
051        List<DocumentModel> nodesToCreate = new ArrayList<DocumentModel>();
052        for (DocumentModel doc : docs) {
053            String id = doc.getId();
054            int pos = id.lastIndexOf(getParseString());
055
056            String currentBasePath;
057            if (pos < 0) {
058                currentBasePath = "";
059            } else {
060                currentBasePath = id.substring(0, pos + getParseStringLength());
061            }
062
063            if (previousBasePath != null && !currentBasePath.equals(previousBasePath)) {
064                appendNodes(root, previousBasePath, nodesToCreate);
065                nodesToCreate = new ArrayList<DocumentModel>();
066            }
067            nodesToCreate.add(doc);
068            previousBasePath = currentBasePath;
069        }
070        appendNodes(root, previousBasePath, nodesToCreate);
071
072        return root;
073    }
074
075    /**
076     * Append and create UserTreeNode from nodesToCreate list to the rootList. It create or use defined node in the root
077     * to create wanted nodes.
078     *
079     * @param root the root UserNodeTree List, may contains some part of the destination path
080     * @param destinationPath destination path, not splitted.
081     * @param nodesToCreate list of documentModel to be created at the destination path
082     */
083    protected static void appendNodes(List<UserTreeNode> root, String destinationPath, List<DocumentModel> nodesToCreate) {
084        UserTreeNode currentNode = null;
085
086        if (nodesToCreate == null || nodesToCreate.size() < 1) {
087            return;
088        }
089
090        if (destinationPath == null || destinationPath.equals("")) {
091            root.addAll(UserTreeNode.constructNodes(nodesToCreate));
092            return;
093        }
094
095        for (String path : destinationPath.split(getParseString())) {
096            UserTreeNode node = searchNode(currentNode == null ? root : currentNode.getChildrens(), path);
097            if (node == null) {
098                node = new UserTreeNode(path);
099                if (currentNode == null) {
100                    root.add(node);
101                } else {
102                    currentNode.addChildren(node);
103                }
104            }
105            currentNode = node;
106        }
107
108        assert currentNode != null;
109        currentNode.getChildrens().addAll(UserTreeNode.constructNodes(nodesToCreate));
110    }
111
112    /**
113     * Search a Node where param name is equals to the nodeId
114     *
115     * @return null if not found
116     */
117    protected static UserTreeNode searchNode(List<UserTreeNode> from, String name) {
118        for (UserTreeNode node : from) {
119            if (node.getId().equals(name)) {
120                return node;
121            }
122        }
123        return null;
124    }
125
126    public static List<UserTreeNode> buildBranch(String branch, List<DocumentModel> docs) {
127        List<UserTreeNode> nodeBranch = new ArrayList<UserTreeNode>();
128        appendNodes(nodeBranch, branch, docs);
129        return nodeBranch;
130    }
131
132    public static String getParseString() {
133        return getService().getParseString();
134    }
135
136    public static int getParseStringLength() {
137        String str = getService().getParseString();
138        return str == null ? -1 : str.length();
139    }
140
141    public static String getShibbGroupBasePath() {
142        return getService().getShibbGroupBasePath();
143    }
144
145    protected static ShibbolethGroupsService getService() {
146        return Framework.getService(ShibbolethGroupsService.class);
147    }
148
149}