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