001/*
002 *  Copyright 2017 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.Collections;
020import java.util.Locale;
021import java.util.Set;
022import java.util.stream.Collectors;
023
024import org.apache.commons.lang.StringUtils;
025
026import org.ametys.cms.repository.Content;
027import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollectionDAO;
028import org.ametys.plugins.explorer.resources.ResourceCollection;
029import org.ametys.plugins.repository.AmetysObject;
030import org.ametys.plugins.repository.AmetysObjectIterable;
031import org.ametys.plugins.repository.AmetysObjectResolver;
032import org.ametys.plugins.repository.AmetysRepositoryException;
033import org.ametys.plugins.repository.CollectionIterable;
034import org.ametys.plugins.repository.UnknownAmetysObjectException;
035import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
036import org.ametys.plugins.repository.data.holder.ModelLessDataHolder;
037import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder;
038import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
039import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
040import org.ametys.plugins.repository.data.type.RepositoryModelItemType;
041import org.ametys.plugins.userdirectory.OrganisationChartPageHandler;
042import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint;
043import org.ametys.web.repository.page.Page;
044import org.ametys.web.repository.page.UnknownZoneException;
045import org.ametys.web.repository.page.Zone;
046import org.ametys.web.repository.site.Site;
047import org.ametys.web.repository.sitemap.Sitemap;
048import org.ametys.web.skin.Skin;
049import org.ametys.web.skin.SkinsManager;
050
051/**
052 * Page representing an orgUnit page.
053 */
054public class OrgUnitPage implements Page
055{
056    private static final String __ORGUNIT_PAGE_TEMPLATE = "udorgunit";
057    
058    private Page _root;
059    private String _title;
060    private AmetysObjectResolver _resolver;
061    private OrganisationChartPageHandler _organisationChartPageHandler;
062    private SynchronizableContentsCollectionDAO _syncContentsCollectionDAO;
063    private SkinsManager _skinsManager;
064    private String _path;
065    private Content _syncContent;
066    
067    private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _pageDataTypeExtensionPoint;
068    private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _zoneDataTypeExtensionPoint;
069    private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _zoneItemDataTypeExtensionPoint;
070    
071    /**
072     * Constructor.
073     * @param root the root page.
074     * @param syncContent the synchronized content
075     * @param path the path
076     * @param resolver the {@link AmetysObjectResolver}.
077     * @param organisationChartPageHandler the organisation chart page handler
078     * @param syncContentsCollectionDAO The DAO for synchronizable collections
079     * @param skinsManager the skins manager
080     * @param pageDataTypeExtensionPoint the extension point with available data types for pages
081     * @param zoneDataTypeExtensionPoint the extension point with available data types for zones
082     * @param zoneItemDataTypeExtensionPoint the extension point with available data types for zone items
083     */
084    public OrgUnitPage(Page root, Content syncContent, String path, AmetysObjectResolver resolver, OrganisationChartPageHandler organisationChartPageHandler, SynchronizableContentsCollectionDAO syncContentsCollectionDAO, SkinsManager skinsManager, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> pageDataTypeExtensionPoint, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> zoneDataTypeExtensionPoint, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> zoneItemDataTypeExtensionPoint)
085    {
086        _root = root;
087        _path = path;
088        _resolver = resolver;
089        _organisationChartPageHandler = organisationChartPageHandler;
090        _syncContentsCollectionDAO = syncContentsCollectionDAO;
091        _skinsManager = skinsManager;
092        _syncContent = syncContent;
093        
094        _title = _syncContent.getTitle(new Locale(root.getSitemapName()));
095
096        _pageDataTypeExtensionPoint = pageDataTypeExtensionPoint;
097        _zoneDataTypeExtensionPoint = zoneDataTypeExtensionPoint;
098        _zoneItemDataTypeExtensionPoint = zoneItemDataTypeExtensionPoint;
099    }
100    
101    /**
102     * Returns the associated synchronizable {@link Content}.
103     * @return the associated synchronizable {@link Content}.
104     */
105    public Content getSyncContent()
106    {
107        return _syncContent;
108    }
109    
110    
111    public int getDepth() throws AmetysRepositoryException
112    {
113        return _root.getDepth() + (_path != null ? _path.split("/").length : 0);
114    }
115
116    
117    public Set<String> getReferers() throws AmetysRepositoryException
118    {
119        return null;
120    }
121
122    
123    public ResourceCollection getRootAttachments() throws AmetysRepositoryException
124    {
125        return null;
126    }
127
128    
129    public String getTemplate() throws AmetysRepositoryException
130    {
131        Skin skin = _skinsManager.getSkin(getSite().getSkinId());
132        
133        if (skin.getTemplate(__ORGUNIT_PAGE_TEMPLATE) != null)
134        {
135            return __ORGUNIT_PAGE_TEMPLATE;
136        }
137        
138        return "page"; 
139    }
140
141    
142    public String getTitle() throws AmetysRepositoryException
143    {
144        return _title;
145    }
146    
147    
148    public String getLongTitle() throws AmetysRepositoryException
149    {
150        return _title;
151    }
152
153    
154    public PageType getType() throws AmetysRepositoryException
155    {
156        return PageType.CONTAINER;
157    }
158
159    
160    public String getURL() throws AmetysRepositoryException
161    {
162        throw new UnsupportedOperationException("#getURL is not supported on virtual orgUnit pages");
163    }
164
165    
166    public LinkType getURLType() throws AmetysRepositoryException
167    {
168        throw new UnsupportedOperationException("#getURLType is not supported on virtual orgUnit pages");
169    }
170
171    
172    public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException
173    {
174        if (!"default".equals(name))
175        {
176            throw new IllegalArgumentException("Only the zone named 'default' is actually supported on virtual orgUnit pages.");
177        }
178        
179        return new OrgUnitZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint);
180    }
181
182    
183    public AmetysObjectIterable< ? extends Zone> getZones() throws AmetysRepositoryException
184    {
185        ArrayList<Zone> zones = new ArrayList<>();
186        zones.add(new OrgUnitZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint));
187        return new CollectionIterable<>(zones);
188    }
189
190    
191    public boolean hasZone(String name) throws AmetysRepositoryException
192    {
193        return "default".equals(name);
194    }
195
196    
197    public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException
198    {
199        ArrayList<Page> children = new ArrayList<>();
200        
201        for (Content content : _organisationChartPageHandler.getChildContents(_syncContent))
202        {
203            children.add(new OrgUnitPage(_root, content, _path + "/" + content.getName() , _resolver, _organisationChartPageHandler, _syncContentsCollectionDAO, _skinsManager, _pageDataTypeExtensionPoint, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint));
204        }
205        
206        return new CollectionIterable<>(children);
207    }
208
209    
210    public String getPathInSitemap() throws AmetysRepositoryException
211    {
212        return _root.getPathInSitemap() + "/" + _path;
213    }
214
215    
216    public Site getSite() throws AmetysRepositoryException
217    {
218        return _root.getSite();
219    }
220
221    
222    public String getSiteName() throws AmetysRepositoryException
223    {
224        return _root.getSiteName();
225    }
226
227    
228    public Sitemap getSitemap() throws AmetysRepositoryException
229    {
230        return _root.getSitemap();
231    }
232
233    
234    public String getSitemapName() throws AmetysRepositoryException
235    {
236        return _root.getSitemapName();
237    }
238
239    @SuppressWarnings("unchecked")
240    
241    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
242    {
243        if (path.isEmpty())
244        {
245            throw new AmetysRepositoryException("path must be non empty");
246        }
247        
248        Content childContent = _organisationChartPageHandler.getChildFromPath(_syncContent, path);
249        if (childContent != null)
250        {
251            OrgUnitPage page = new OrgUnitPage(_root, childContent, _path + "/" + path , _resolver, _organisationChartPageHandler, _syncContentsCollectionDAO, _skinsManager, _pageDataTypeExtensionPoint, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint);
252            return (A) page;
253        }
254        
255        return null;
256    }
257    
258
259    @SuppressWarnings("unchecked")
260    
261    public AmetysObjectIterable<? extends AmetysObject> getChildren() throws AmetysRepositoryException
262    {
263        return getChildrenPages();
264    }
265
266    
267    public boolean hasChild(String name) throws AmetysRepositoryException
268    {
269        return !_organisationChartPageHandler.getChildContents(_syncContent).stream().filter(c -> c.getName().equals(name)).collect(Collectors.toList()).isEmpty();
270    }
271    
272    
273    public String getId() throws AmetysRepositoryException
274    {
275        // E.g: udorgunit://path?rootId=...&contentId=...
276        return "udorgunit://" + _path + "?rootId=" + _root.getId() + "&contentId=" + _syncContent.getId();
277    }
278
279    
280    public String getName() throws AmetysRepositoryException
281    {
282        return _syncContent.getName();
283    }
284    
285    @SuppressWarnings("unchecked")
286    
287    public Page getParent() throws AmetysRepositoryException
288    {
289        Content parentContent = _organisationChartPageHandler.getParentContent(_syncContent);
290        if (parentContent != null)
291        {
292            return new OrgUnitPage(_root, parentContent, StringUtils.substringBeforeLast(_path, "/"), _resolver, _organisationChartPageHandler, _syncContentsCollectionDAO, _skinsManager, _pageDataTypeExtensionPoint, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint);
293        }
294
295        return _root;
296    }
297
298    
299    public String getParentPath() throws AmetysRepositoryException
300    {
301        if (_path.contains("/"))
302        {
303            return _root.getPath() + "/" + StringUtils.substringBeforeLast(_path, "/");
304        }
305        else
306        {
307            return _root.getPath();
308        }
309    }
310
311    
312    public String getPath() throws AmetysRepositoryException
313    {
314        return _root.getPath() + "/" + _path;
315    }
316
317    public ModelLessDataHolder getDataHolder()
318    {
319        RepositoryData repositoryData = new MemoryRepositoryData(getName());
320        return new DefaultModelLessDataHolder(_pageDataTypeExtensionPoint, repositoryData);
321    }
322
323    
324    public Set<String> getTags() throws AmetysRepositoryException
325    {
326        return Collections.emptySet();
327    }
328
329    
330    public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePage) throws AmetysRepositoryException
331    {
332        return getChildrenPages();
333    }
334
335    
336    public boolean isVisible() throws AmetysRepositoryException
337    {
338        return true;
339    }
340
341    
342    public Page getChildPageAt(int index) throws UnknownAmetysObjectException, AmetysRepositoryException
343    {
344        throw new UnknownAmetysObjectException("There is no child for orgUnit page");
345    }
346
347    public ModelAwareDataHolder getTemplateParametersHolder() throws AmetysRepositoryException
348    {
349        return null;
350    }
351}