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