001/*
002 *  Copyright 2016 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.plugins.userdirectory.page;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Locale;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.commons.lang.StringUtils;
025
026import org.ametys.cms.repository.Content;
027import org.ametys.core.group.GroupIdentity;
028import org.ametys.core.right.ProfileAssignmentStorage.AnonymousOrAnyConnectedKeys;
029import org.ametys.core.right.ProfileAssignmentStorage.UserOrGroup;
030import org.ametys.core.right.RightManager;
031import org.ametys.core.user.UserIdentity;
032import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection;
033import org.ametys.plugins.repository.ACLAmetysObject;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.AmetysObjectIterable;
036import org.ametys.plugins.repository.AmetysRepositoryException;
037import org.ametys.plugins.repository.CollectionIterable;
038import org.ametys.plugins.repository.UnknownAmetysObjectException;
039import org.ametys.plugins.repository.data.holder.ModelLessDataHolder;
040import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder;
041import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
042import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
043import org.ametys.web.repository.page.Page;
044import org.ametys.web.repository.page.virtual.AbstractConfigurableVirtualPage;
045import org.ametys.web.repository.page.virtual.VirtualPageConfiguration;
046
047/**
048 * Page representing a second-level page.
049 */
050public class UserPage extends AbstractConfigurableVirtualPage<UserPageFactory> implements ACLAmetysObject
051{
052    private int _initialDepth;
053    private String _title;
054    private String _path;
055    private Content _syncContent;
056    
057    /**
058     * Constructor.
059     * @param root the root page.
060     * @param syncContent the synchronized content
061     * @param path the path
062     * @param configuration The abstract virtual page's configuration
063     * @param scheme The scheme
064     * @param factory The user page factory
065     */
066    public UserPage(Page root, VirtualPageConfiguration configuration, String scheme, UserPageFactory factory, Content syncContent, String path)
067    {
068        super(root, configuration, scheme, factory);
069        
070        _path = path;
071        _syncContent = syncContent;
072        
073        _title = _syncContent.getTitle(new Locale(root.getSitemapName()));
074        _initialDepth = _factory.getUserDirectoryPageHandler().getDepth(_root);
075    }
076
077    /**
078     * Compute a page id
079     * @param path The path
080     * @param rootId The root page id
081     * @param contentId The content id
082     * @return The id
083     */
084    public static String getId(String path, String rootId, String contentId)
085    {
086        // E.g: uduser://path?rootId=...&contentId=...
087        return "uduser://" + (StringUtils.isEmpty(path) ? "_root" : path) + "?rootId=" + rootId + "&contentId=" + contentId;
088    }
089    
090    /**
091     * Returns the associated synchronizable {@link Content}.
092     * @return the associated synchronizable {@link Content}.
093     */
094    @SuppressWarnings("unchecked")
095    @Override
096    public Content getContent()
097    {
098        return _syncContent;
099    }
100    
101    
102    public int getDepth() throws AmetysRepositoryException
103    {
104        return _root.getDepth() + _initialDepth + 1;
105    }
106
107    @Override
108    public Set<String> getReferers() throws AmetysRepositoryException
109    {
110        return null;
111    }
112
113    public String getTitle() throws AmetysRepositoryException
114    {
115        return _title;
116    }
117    
118    
119    public String getLongTitle() throws AmetysRepositoryException
120    {
121        return _title;
122    }
123    
124    public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException
125    {
126        List<Page> children = new ArrayList<>();
127        return new CollectionIterable<>(children);
128    }
129
130    
131    public String getPathInSitemap() throws AmetysRepositoryException
132    {
133        if (_path.equals("_root"))
134        {
135            return _root.getPathInSitemap() + "/" + getName();
136        }
137        else
138        {
139            String path = StringUtils.lowerCase(_path);
140            return _root.getPathInSitemap() + "/" + path + "/" + getName();
141        }
142    }
143    
144    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
145    {
146        if (path.isEmpty())
147        {
148            throw new AmetysRepositoryException("path must be non empty");
149        }
150        
151        return null;
152    }
153
154    @SuppressWarnings("unchecked")
155    
156    public AmetysObjectIterable<? extends AmetysObject> getChildren() throws AmetysRepositoryException
157    {
158        return getChildrenPages();
159    }
160
161    
162    public boolean hasChild(String name) throws AmetysRepositoryException
163    {
164        return false;
165    }
166    
167    
168    public String getId() throws AmetysRepositoryException
169    {
170        return getId(_path, _root.getId(), _syncContent.getId());
171    }
172
173    
174    public String getName() throws AmetysRepositoryException
175    {
176        return _syncContent.getName();
177    }
178    
179    @SuppressWarnings("unchecked")
180    
181    public Page getParent() throws AmetysRepositoryException
182    {
183        if (_initialDepth > 0)
184        {
185            String pathName = StringUtils.substringAfterLast(_path, "/");
186            String name = _factory.getUserDirectoryPageHandler().getName(pathName);
187            
188            return _factory.getTransitionalPageFactory().createTransitionalPage(_root, name, _path);
189        }
190        else
191        {
192            return _root;
193        }
194    }
195
196    
197    public String getParentPath() throws AmetysRepositoryException
198    {
199        if (_initialDepth > 0)
200        {
201            String path = StringUtils.lowerCase(_path);
202            return _root.getPath() + "/" + path;
203        }
204        else
205        {
206            return _root.getPath();
207        }
208    }
209
210    public ModelLessDataHolder getDataHolder()
211    {
212        RepositoryData repositoryData = new MemoryRepositoryData(getName());
213        return new DefaultModelLessDataHolder(_factory.getPageDataTypeEP(), repositoryData);
214    }
215    
216    public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePage) throws AmetysRepositoryException
217    {
218        List<Page> children = new ArrayList<>();
219        return new CollectionIterable<>(children);
220    }
221
222    @Override
223    public boolean isVisible() throws AmetysRepositoryException
224    {
225        return false;
226    }
227
228    
229    public Page getChildPageAt(int index) throws UnknownAmetysObjectException, AmetysRepositoryException
230    {
231        throw new UnknownAmetysObjectException("There is no child for user page");
232    }
233
234    public Map<AnonymousOrAnyConnectedKeys, Set<String>> getProfilesForAnonymousAndAnyConnectedUser()
235    {
236        Set<String> collectionIds = _factory.getSccHelper().getSynchronizableCollectionIds(_syncContent);
237        for (String collectionId : collectionIds)
238        {
239            SynchronizableContentsCollection collection = _factory.getSynchronizableContentsCollectionDAO().getSynchronizableContentsCollection(collectionId);
240            if (collection != null)
241            {
242                String restrictedField = collection.getRestrictedField();
243                if (!StringUtils.isEmpty(restrictedField))
244                {
245                    Boolean restricted = _syncContent.getValue(restrictedField);
246                    if (restricted != null && restricted.booleanValue())
247                    {
248                        return Map.of(AnonymousOrAnyConnectedKeys.ANONYMOUS_DENIED, Set.of(RightManager.READER_PROFILE_ID));
249                    }
250                }
251            }
252        }
253        
254        return Map.of();
255    }
256    
257    public Map<GroupIdentity, Map<UserOrGroup, Set<String>>> getProfilesForGroups(Set<GroupIdentity> groups)
258    {
259        return Map.of();
260    }
261    
262    public Map<UserIdentity, Map<UserOrGroup, Set<String>>> getProfilesForUsers(UserIdentity user)
263    {
264        return Map.of();
265    }
266    
267    public boolean isInheritanceDisallowed()
268    {
269        return false;
270    }
271}