001/*
002 *  Copyright 2021 Anyware Services
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 */
016package org.ametys.cms.tag;
017
018import java.util.Collection;
019import java.util.Map;
020import java.util.Set;
021import java.util.stream.Collectors;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.commons.lang3.StringUtils;
027
028import org.ametys.core.group.Group;
029import org.ametys.core.group.GroupDirectoryContextHelper;
030import org.ametys.core.group.GroupDirectoryDAO;
031import org.ametys.core.group.GroupIdentity;
032import org.ametys.core.group.GroupManager;
033import org.ametys.core.group.directory.GroupDirectory;
034import org.ametys.runtime.i18n.I18nizableText;
035
036
037/**
038 * Class representing a group tag provider. <br>
039 * @param <T> the tag class
040 */
041public class GroupTagProvider<T extends CMSTag> extends AbstractTagProvider<CMSTag> implements Serviceable
042{
043    /** The Avalon role */
044    public static final String ROLE = GroupTagProvider.class.getName();
045    
046    private static final String _GROUP_TAG_PREFIX = "group_";
047    private static final String _GROUP_ID_SEPERATOR = "#";
048    
049    /** The group manager */
050    protected GroupManager _groupManager;
051    
052    /** The group directory DAO */
053    protected GroupDirectoryDAO _groupDirectoryDAO;
054    
055    /** The tag target type extension point */
056    protected TagTargetTypeExtensionPoint _targetTypeEP;
057    
058    /** The group directory context helper */
059    protected GroupDirectoryContextHelper _groupDirectoryContextHelper;
060    
061    public void service(ServiceManager manager) throws ServiceException
062    {
063        _groupManager = (GroupManager) manager.lookup(GroupManager.ROLE);
064        _groupDirectoryDAO = (GroupDirectoryDAO) manager.lookup(GroupDirectoryDAO.ROLE);
065        _targetTypeEP = (TagTargetTypeExtensionPoint) manager.lookup(TagTargetTypeExtensionPoint.ROLE);
066        _groupDirectoryContextHelper = (GroupDirectoryContextHelper) manager.lookup(GroupDirectoryContextHelper.ROLE);
067    }
068    
069    public Map<String, CMSTag> getTags(Map<String, Object> contextualParameters)
070    {
071        Set<String> contexts = _getContexts();
072        return _groupDirectoryContextHelper.getGroupDirectoriesOnContexts(contexts)
073                    .stream()
074                    .map(id -> _groupDirectoryDAO.getGroupDirectory(id))
075                    .map(this::_getCMSTag)
076                    .collect(Collectors.toMap(t -> t.getId(), t -> t));
077    }
078    
079    public CMSTag getTag(String tagName, Map<String, Object> contextualParameters)
080    {
081        if (!tagName.contains(_GROUP_TAG_PREFIX))
082        {
083            return null;
084        }
085        
086        String tagNameWithoutPrefix = StringUtils.substringAfter(tagName, _GROUP_TAG_PREFIX);
087        if (tagNameWithoutPrefix.contains(_GROUP_ID_SEPERATOR))
088        {
089            String groupDirectoryId = StringUtils.substringBefore(tagNameWithoutPrefix, _GROUP_ID_SEPERATOR);
090            String groupId = StringUtils.substringAfter(tagNameWithoutPrefix, _GROUP_ID_SEPERATOR);
091            Group group = _groupManager.getGroup(groupDirectoryId, groupId);
092            return _getCMSTag(groupDirectoryId, group);
093        }
094        else
095        {
096            GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(tagNameWithoutPrefix);
097            return _getCMSTag(groupDirectory);
098        }
099    }
100
101    public Collection<CMSTag> getTags(String tagName, Map<String, Object> contextualParameters)
102    {
103        return _groupManager.getGroups(tagName)
104                .stream()
105                .map(g -> _getCMSTag(tagName, g))
106                .collect(Collectors.toList());
107    }
108
109    public boolean hasTag(String tagName, Map<String, Object> contextualParameters)
110    {
111        if (!tagName.contains(_GROUP_TAG_PREFIX))
112        {
113            return false;
114        }
115        
116        String tagNameWithoutPrefix = StringUtils.substringAfter(tagName, _GROUP_TAG_PREFIX);
117        if (tagNameWithoutPrefix.contains(_GROUP_ID_SEPERATOR))
118        {
119            String groupDirectoryId = StringUtils.substringBefore(tagNameWithoutPrefix, _GROUP_ID_SEPERATOR);
120            String groupId = StringUtils.substringAfter(tagNameWithoutPrefix, _GROUP_ID_SEPERATOR);
121            return _groupManager.getGroup(groupDirectoryId, groupId) != null;
122        }
123        else
124        {
125            return _groupDirectoryDAO.getGroupDirectory(tagNameWithoutPrefix) != null;
126        }
127    }
128    
129    private CMSTag _getCMSTag(GroupDirectory groupDirectory)
130    {
131        String tagId = getGroupDirectoryTagId(groupDirectory.getId());
132        CMSTag groupDirectoryTag =  new CMSTag(
133                                        tagId, 
134                                        tagId, 
135                                        null, 
136                                        groupDirectory.getLabel(),
137                                        null,
138                                        _targetTypeEP.getTagTargetType("CONTENT")
139                                    );
140        
141        groupDirectoryTag.setTags(_groupManager.getGroups(groupDirectory)
142                                        .stream()
143                                        .map(g -> _getCMSTag(groupDirectoryTag, g))
144                                        .collect(Collectors.toMap(t -> t.getId(), t -> t))
145                                  );
146        
147        return groupDirectoryTag;
148    }
149    
150    private CMSTag _getCMSTag(String groupDirectoryId, Group group)
151    {
152        GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId);
153        CMSTag groupDirectoryTag = _getCMSTag(groupDirectory);
154        return _getCMSTag(groupDirectoryTag, group);
155    }
156    
157    private CMSTag _getCMSTag(CMSTag parentTag, Group group)
158    {
159        String tagId = getGroupTagId(parentTag.getId(), group.getIdentity());
160        return new CMSTag(
161                    tagId, 
162                    tagId, 
163                    parentTag, 
164                    new I18nizableText(group.getLabel()),
165                    null,
166                    _targetTypeEP.getTagTargetType("CONTENT")
167                );
168    }
169    
170    /**
171     * Get the set of context to get group directories
172     * @return the set of context
173     */
174    protected Set<String> _getContexts()
175    {
176        return Set.of("/application");
177    }
178    
179    /**
180     * Get tag id if from group directory
181     * @param groupDirectoryTagId the group directory id
182     * @return the tag id
183     */
184    public String getGroupDirectoryTagId(String groupDirectoryTagId)
185    {
186        return _GROUP_TAG_PREFIX + groupDirectoryTagId;
187    }
188    
189    /**
190     * Get tag id if from the group and its group directory
191     * @param groupDirectoryTagId the group directory tag id
192     * @param groupIdentity the group identity
193     * @return the tag id
194     */
195    public String getGroupTagId(String groupDirectoryTagId, GroupIdentity groupIdentity)
196    {
197        return groupDirectoryTagId + _GROUP_ID_SEPERATOR + groupIdentity.getId();
198    }
199}