001/*
002 * (C) Copyright 2006-2007 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 *
014 * Contributors:
015 *     Thierry Delprat
016 * *
017 */
018
019package org.nuxeo.ecm.platform.computedgroups;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.Collections;
024import java.util.HashMap;
025import java.util.HashSet;
026import java.util.List;
027import java.util.Map;
028import java.util.Set;
029
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.nuxeo.ecm.core.api.NuxeoGroup;
033import org.nuxeo.ecm.platform.usermanager.NuxeoPrincipalImpl;
034import org.nuxeo.runtime.model.ComponentContext;
035import org.nuxeo.runtime.model.ComponentInstance;
036import org.nuxeo.runtime.model.DefaultComponent;
037
038/**
039 * {@link ComputedGroupsService} implementation
040 *
041 * @author Thierry Delprat
042 */
043public class ComputedGroupsServiceImpl extends DefaultComponent implements ComputedGroupsService {
044
045    public static final String COMPUTER_EP = "computer";
046
047    public static final String CHAIN_EP = "computerChain";
048
049    protected static Map<String, GroupComputerDescriptor> computers = new HashMap<String, GroupComputerDescriptor>();
050
051    protected static List<String> computerNames = new ArrayList<String>();
052
053    protected boolean allowOverride = true;
054
055    protected static Log log = LogFactory.getLog(ComputedGroupsServiceImpl.class);
056
057    @Override
058    public void activate(ComponentContext context) {
059        super.activate(context);
060        computers = new HashMap<String, GroupComputerDescriptor>();
061        computerNames = new ArrayList<String>();
062    }
063
064    @Override
065    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
066
067        if (COMPUTER_EP.equals(extensionPoint)) {
068            if (contribution instanceof GroupComputerDescriptor) {
069                GroupComputerDescriptor desc = (GroupComputerDescriptor) contribution;
070
071                if (desc.isEnabled()) {
072                    log.debug("Add " + desc.getName() + " from component " + contributor.getName());
073                    computers.put(desc.getName(), desc);
074                } else {
075                    if (computers.containsKey(desc.getName())) {
076                        log.debug("Remove " + desc.getName() + " from component " + contributor.getName());
077                        computers.remove(desc.getName());
078                    } else {
079                        log.warn("Can't remove " + desc.getName() + " as not found, from component "
080                                + contributor.getName());
081                    }
082                }
083                return;
084            } else {
085                throw new RuntimeException("Waiting GroupComputerDescriptor contribution kind, please look component "
086                        + contributor.getName());
087            }
088        }
089
090        if (CHAIN_EP.equals(extensionPoint)) {
091            GroupComputerChainDescriptor desc = (GroupComputerChainDescriptor) contribution;
092            if (desc.isAppend()) {
093                computerNames.addAll(desc.getComputerNames());
094            } else {
095                computerNames = desc.getComputerNames();
096            }
097            return;
098        }
099
100        log.warn("Unkown contribution, please check the component " + contributor.getName());
101    }
102
103    @Override
104    public List<String> computeGroupsForUser(NuxeoPrincipalImpl nuxeoPrincipal) {
105        List<String> userGroups = new ArrayList<String>();
106        for (String computerName : computerNames) {
107            userGroups.addAll(computers.get(computerName).getComputer().getGroupsForUser(nuxeoPrincipal));
108        }
109        return userGroups;
110    }
111
112    @Override
113    public void updateGroupsForUser(NuxeoPrincipalImpl nuxeoPrincipal) {
114        List<String> computedGroups = computeGroupsForUser(nuxeoPrincipal);
115        Set<String> virtualGroups = new HashSet<String>(nuxeoPrincipal.getVirtualGroups());
116        virtualGroups.addAll(computedGroups);
117        nuxeoPrincipal.setVirtualGroups(new ArrayList<String>(virtualGroups));
118    }
119
120    @Override
121    public boolean allowGroupOverride() {
122        return allowOverride;
123    }
124
125    @Override
126    public NuxeoGroup getComputedGroup(String groupName) {
127        for (String name : computerNames) {
128            GroupComputer computer = computers.get(name).getComputer();
129            if (computer.hasGroup(groupName)) {
130                if (computer instanceof GroupComputerLabelled) {
131                    String groupLabel = ((GroupComputerLabelled) computer).getLabel(groupName);
132                    return new NuxeoComputedGroup(groupName, groupLabel);
133                }
134                return new NuxeoComputedGroup(groupName);
135            }
136        }
137        return null;
138    }
139
140    @Override
141    public List<String> computeGroupIds() {
142        List<String> groupIds = new ArrayList<String>();
143        for (String name : computerNames) {
144            GroupComputerDescriptor desc = computers.get(name);
145            List<String> foundGroupIds = desc.getComputer().getAllGroupIds();
146            if (foundGroupIds != null) {
147                groupIds.addAll(foundGroupIds);
148            }
149        }
150        return groupIds;
151    }
152
153    @Override
154    public List<String> getComputedGroupMembers(String groupName) {
155        List<String> members = new ArrayList<String>();
156        for (String name : computerNames) {
157            GroupComputerDescriptor desc = computers.get(name);
158            List<String> foundMembers = desc.getComputer().getGroupMembers(groupName);
159            if (foundMembers != null) {
160                members.addAll(foundMembers);
161            }
162        }
163        return members;
164    }
165
166    @Override
167    public List<String> getComputedGroupParent(String groupName) {
168        List<String> parents = new ArrayList<String>();
169        for (String name : computerNames) {
170            GroupComputerDescriptor desc = computers.get(name);
171            List<String> foundParents = desc.getComputer().getParentsGroupNames(groupName);
172            if (foundParents != null) {
173                parents.addAll(foundParents);
174            }
175        }
176        return parents;
177    }
178
179    @Override
180    public List<String> getComputedGroupSubGroups(String groupName) {
181        List<String> subGroups = new ArrayList<String>();
182        for (String name : computerNames) {
183            GroupComputerDescriptor desc = computers.get(name);
184            List<String> foundSubGroups = desc.getComputer().getSubGroupsNames(groupName);
185            if (foundSubGroups != null) {
186                subGroups.addAll(foundSubGroups);
187            }
188        }
189        return subGroups;
190    }
191
192    public List<GroupComputerDescriptor> getComputerDescriptors() {
193        List<GroupComputerDescriptor> result = new ArrayList<GroupComputerDescriptor>();
194        for (String name : computerNames) {
195            result.add(computers.get(name));
196        }
197        return result;
198    }
199
200    @Override
201    public boolean activateComputedGroups() {
202        return computerNames.size() > 0;
203    }
204
205    @Override
206    public List<String> searchComputedGroups(Map<String, Serializable> filter, Set<String> fulltext) {
207        List<String> foundGroups = new ArrayList<String>();
208        for (String name : computerNames) {
209            GroupComputerDescriptor desc = computers.get(name);
210            foundGroups.addAll(desc.getComputer().searchGroups(filter, fulltext));
211        }
212        Collections.sort(foundGroups);
213        return foundGroups;
214    }
215
216    @Override
217    public void deactivate(ComponentContext context) {
218        super.deactivate(context);
219
220    }
221}