001/*
002 *  Copyright 2018 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.ugc.page;
017
018import java.util.ArrayList;
019import java.util.Collections;
020import java.util.Locale;
021import java.util.Map;
022import java.util.Set;
023
024import org.ametys.cms.repository.Content;
025import org.ametys.plugins.explorer.resources.ResourceCollection;
026import org.ametys.plugins.repository.AmetysObject;
027import org.ametys.plugins.repository.AmetysObjectIterable;
028import org.ametys.plugins.repository.AmetysObjectResolver;
029import org.ametys.plugins.repository.AmetysRepositoryException;
030import org.ametys.plugins.repository.CollectionIterable;
031import org.ametys.plugins.repository.UnknownAmetysObjectException;
032import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
033import org.ametys.plugins.repository.data.holder.ModelLessDataHolder;
034import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder;
035import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
036import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
037import org.ametys.web.data.type.ModelItemTypeExtensionPoint;
038import org.ametys.web.repository.page.Page;
039import org.ametys.web.repository.page.UnknownZoneException;
040import org.ametys.web.repository.page.Zone;
041import org.ametys.web.repository.site.Site;
042import org.ametys.web.repository.sitemap.Sitemap;
043import org.ametys.web.service.ServiceExtensionPoint;
044import org.ametys.web.skin.Skin;
045import org.ametys.web.skin.SkinsManager;
046
047/**
048 * Page representing an UGC page.
049 */
050public class UGCPage implements Page
051{
052    private static final String __UGC_PAGE_TEMPLATE = "ugc-page";
053    
054    private Page _root;
055    private String _title;
056    private AmetysObjectResolver _resolver;
057    private UGCPageHandler _ugcPageHandler;
058    private SkinsManager _skinsManager;
059    private String _path;
060    private Content _ugcContent;
061    private ModelItemTypeExtensionPoint _pageDataTypeExtensionPoint;
062    private ModelItemTypeExtensionPoint _zoneDataTypeExtensionPoint;
063    private ServiceExtensionPoint _serviceExtensionPoint;
064    private ModelItemTypeExtensionPoint _zoneItemDataTypeExtensionPoint;
065    
066    /**
067     * Constructor.
068     * @param root the root page.
069     * @param syncContent the synchronized content
070     * @param path the path
071     * @param resolver the {@link AmetysObjectResolver}.
072     * @param ugcPageHandler the ugc page handler
073     * @param skinsManager the skins manager
074     * @param pageDataTypeExtensionPoint the extension point with available data types for pages
075     * @param zoneDataTypeExtensionPoint the extension point with available data types for zones
076     * @param serviceExtensionPoint the service extension point
077     * @param zoneItemDataTypeExtensionPoint the extension point with available data types for zone items
078     */
079    public UGCPage(Page root, Content syncContent, String path, AmetysObjectResolver resolver, UGCPageHandler ugcPageHandler, SkinsManager skinsManager, ModelItemTypeExtensionPoint pageDataTypeExtensionPoint, ModelItemTypeExtensionPoint zoneDataTypeExtensionPoint, ServiceExtensionPoint serviceExtensionPoint, ModelItemTypeExtensionPoint zoneItemDataTypeExtensionPoint)
080    {
081        _root = root;
082        _path = path;
083        _resolver = resolver;
084        _ugcPageHandler = ugcPageHandler;
085        _skinsManager = skinsManager;
086        _ugcContent = syncContent;
087        _title = _ugcContent.getTitle(new Locale(root.getSitemapName()));
088        
089        _pageDataTypeExtensionPoint = pageDataTypeExtensionPoint;
090        _zoneDataTypeExtensionPoint = zoneDataTypeExtensionPoint;
091        _serviceExtensionPoint = serviceExtensionPoint;
092        _zoneItemDataTypeExtensionPoint = zoneItemDataTypeExtensionPoint;
093    }
094    
095    /**
096     * Returns the associated UGC {@link Content}.
097     * @return the associated UGC {@link Content}.
098     */
099    public Content getUgcContent()
100    {
101        return _ugcContent;
102    }
103    
104    public int getDepth() throws AmetysRepositoryException
105    {
106        return _root.getDepth() + (_path.equals("_root") ? 1 : 2);
107    }
108
109    public Set<String> getReferers() throws AmetysRepositoryException
110    {
111        return null;
112    }
113
114    public ResourceCollection getRootAttachments() throws AmetysRepositoryException
115    {
116        return null;
117    }
118
119    public String getTemplate() throws AmetysRepositoryException
120    {
121        Skin skin = _skinsManager.getSkin(getSite().getSkinId());
122        
123        if (skin.getTemplate(__UGC_PAGE_TEMPLATE) != null)
124        {
125            return __UGC_PAGE_TEMPLATE;
126        }
127        
128        return "page"; 
129    }
130
131    public String getTitle() throws AmetysRepositoryException
132    {
133        return _title;
134    }
135    
136    public String getLongTitle() throws AmetysRepositoryException
137    {
138        return _title;
139    }
140
141    public PageType getType() throws AmetysRepositoryException
142    {
143        return PageType.CONTAINER;
144    }
145
146    public String getURL() throws AmetysRepositoryException
147    {
148        throw new UnsupportedOperationException("#getURL is not supported on virtual ugc pages");
149    }
150
151    public LinkType getURLType() throws AmetysRepositoryException
152    {
153        throw new UnsupportedOperationException("#getURLType is not supported on virtual ugc pages");
154    }
155
156    public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException
157    {
158        if (!"default".equals(name))
159        {
160            throw new IllegalArgumentException("Only the zone named 'default' is actually supported on virtual ugc pages.");
161        }
162        
163        return new UGCZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint);
164    }
165
166    public AmetysObjectIterable< ? extends Zone> getZones() throws AmetysRepositoryException
167    {
168        ArrayList<Zone> zones = new ArrayList<>();
169        zones.add(new UGCZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint));
170        return new CollectionIterable<>(zones);
171    }
172
173    public boolean hasZone(String name) throws AmetysRepositoryException
174    {
175        return "default".equals(name);
176    }
177
178    public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException
179    {
180        ArrayList<Page> children = new ArrayList<>();
181        return new CollectionIterable<>(children);
182    }
183
184    public String getPathInSitemap() throws AmetysRepositoryException
185    {
186        if (_path.equals("_root"))
187        {
188            return _root.getPathInSitemap() + "/" + getName();
189        }
190        else
191        {
192            return _root.getPathInSitemap() + "/" + _path + "/" + getName();
193        }
194    }
195
196    public Site getSite() throws AmetysRepositoryException
197    {
198        return _root.getSite();
199    }
200
201    public String getSiteName() throws AmetysRepositoryException
202    {
203        return _root.getSiteName();
204    }
205
206    public Sitemap getSitemap() throws AmetysRepositoryException
207    {
208        return _root.getSitemap();
209    }
210
211    public String getSitemapName() throws AmetysRepositoryException
212    {
213        return _root.getSitemapName();
214    }
215
216    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
217    {
218        if (path.isEmpty())
219        {
220            throw new AmetysRepositoryException("path must be non empty");
221        }
222        
223        return null;
224    }
225
226    @SuppressWarnings("unchecked")
227    public AmetysObjectIterable<? extends AmetysObject> getChildren() throws AmetysRepositoryException
228    {
229        return getChildrenPages();
230    }
231
232    public boolean hasChild(String name) throws AmetysRepositoryException
233    {
234        return false;
235    }
236    
237    public String getId() throws AmetysRepositoryException
238    {
239        return _ugcPageHandler.computePageId(_path, _root, _ugcContent);
240    }
241
242    public String getName() throws AmetysRepositoryException
243    {
244        return _ugcContent.getName();
245    }
246    
247    @SuppressWarnings("unchecked")
248    public Page getParent() throws AmetysRepositoryException
249    {
250        if (!_path.equals("_root"))
251        {
252            String name = _path;
253            Map<String, Map<String, String>> transitionalPageName = _ugcPageHandler.getTransitionalPage(_root);
254            Map<String, String> attributes = transitionalPageName.get(name);
255            String title = attributes.get(UGCPageHandler.ATTRIBUTE_TRANSITIONAL_PAGE_TITLE);
256            String metadataValue = attributes.get(UGCPageHandler.ATTRIBUTE_TRANSITIONAL_PAGE_METADATA_VALUE);
257            return new UGCTransitionalPage(_root, title, metadataValue, name, _resolver, _ugcPageHandler, _skinsManager, _pageDataTypeExtensionPoint, _zoneDataTypeExtensionPoint, _serviceExtensionPoint, _zoneItemDataTypeExtensionPoint);
258        }
259        else
260        {
261            return _root;
262        }
263    }
264
265    public String getParentPath() throws AmetysRepositoryException
266    {
267        if (!_path.equals("_root"))
268        {
269            return _root.getPath() + "/" + _path;
270        }
271        else
272        {
273            return _root.getPath();
274        }
275    }
276
277    public String getPath() throws AmetysRepositoryException
278    {
279        return getParentPath() + "/" + getName();
280    }
281
282    public ModelLessDataHolder getDataHolder()
283    {
284        RepositoryData repositoryData = new MemoryRepositoryData(getName());
285        return new DefaultModelLessDataHolder(_pageDataTypeExtensionPoint, repositoryData);
286    }
287
288    public Set<String> getTags() throws AmetysRepositoryException
289    {
290        return Collections.emptySet();
291    }
292
293    public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePage) throws AmetysRepositoryException
294    {
295        ArrayList<Page> children = new ArrayList<>();
296        return new CollectionIterable<>(children);
297    }
298
299    public boolean isVisible() throws AmetysRepositoryException
300    {
301        return true;
302    }
303
304    public Page getChildPageAt(int index) throws UnknownAmetysObjectException, AmetysRepositoryException
305    {
306        throw new UnknownAmetysObjectException("There is no child for ugc page");
307    }
308
309    public ModelAwareDataHolder getTemplateParametersHolder() throws AmetysRepositoryException
310    {
311        return null;
312    }
313}