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