001/*
002 *  Copyright 2011 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.blog.repository;
017
018import java.util.Collections;
019import java.util.Set;
020
021import org.ametys.cms.repository.Content;
022import org.ametys.plugins.explorer.resources.ResourceCollection;
023import org.ametys.plugins.repository.AmetysObject;
024import org.ametys.plugins.repository.AmetysObjectIterable;
025import org.ametys.plugins.repository.AmetysObjectResolver;
026import org.ametys.plugins.repository.AmetysRepositoryException;
027import org.ametys.plugins.repository.EmptyIterable;
028import org.ametys.plugins.repository.UnknownAmetysObjectException;
029import org.ametys.plugins.repository.data.holder.ModelLessDataHolder;
030import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder;
031import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
032import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
033import org.ametys.plugins.repository.data.type.RepositoryModelItemType;
034import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint;
035import org.ametys.web.repository.page.Page;
036import org.ametys.web.repository.page.PagesContainer;
037import org.ametys.web.repository.page.Zone;
038import org.ametys.web.repository.site.Site;
039import org.ametys.web.repository.sitemap.Sitemap;
040import org.ametys.web.skin.Skin;
041import org.ametys.web.skin.SkinsManager;
042
043/**
044 * Page representing a post.
045 */
046public class VirtualPostPage extends AbstractBlogPage
047{
048    private PagesContainer _root;
049    private Content _post;
050    private String _path;
051    private SkinsManager _skinsManager;
052    private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _pageDataTypeExtensionPoint;
053    private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _zoneDataTypeExtensionPoint;
054    private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _zoneItemDataTypeExtensionPoint;
055    
056    /**
057     * Constructor.
058     * @param skinsManager the skins manager
059     * @param resolver the {@link AmetysObjectResolver}.
060     * @param root the blog root page.
061     * @param post the post.
062     * @param path path from the virtual root
063     * @param pageDataTypeExtensionPoint the extension point with available data types for pages
064     * @param zoneDataTypeExtensionPoint the extension point with available data types for zones
065     * @param zoneItemDataTypeExtensionPoint the extension point with available data types for zone items
066     */
067    public VirtualPostPage(AmetysObjectResolver resolver, SkinsManager skinsManager, PagesContainer root, Content post, String path, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> pageDataTypeExtensionPoint, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> zoneDataTypeExtensionPoint, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> zoneItemDataTypeExtensionPoint)
068    {
069        _root = root;
070        _skinsManager = skinsManager;
071        _post = post;
072        _path = path;
073        _pageDataTypeExtensionPoint = pageDataTypeExtensionPoint;
074        _zoneDataTypeExtensionPoint = zoneDataTypeExtensionPoint;
075        _zoneItemDataTypeExtensionPoint = zoneItemDataTypeExtensionPoint;
076    }
077    
078    /**
079     * Returns the associated {@link Content}.
080     * @return the associated {@link Content}.
081     */
082    public Content getPost()
083    {
084        return _post;
085    }
086    
087    @Override
088    public int getDepth() throws AmetysRepositoryException
089    {
090        int depth = 0;
091        if (_root instanceof Page)
092        {
093            depth = ((Page) _root).getDepth();
094        }
095        
096        return depth + _path.split("/").length;
097    }
098
099    @Override
100    public Set<String> getReferers() throws AmetysRepositoryException
101    {
102        throw new UnsupportedOperationException("getReferers not supported on virtual post pages");
103    }
104
105    @Override
106    public ResourceCollection getRootAttachments() throws AmetysRepositoryException
107    {
108        return null;
109    }
110    
111    @Override
112    public String getTitle() throws AmetysRepositoryException
113    {
114        return _post.getTitle();
115    }
116
117    @Override
118    public String getLongTitle() throws AmetysRepositoryException
119    {
120        return _post.getTitle();
121    }
122    
123    @Override
124    public String getURL() throws AmetysRepositoryException
125    {
126        throw new UnsupportedOperationException("getURL not supported on virtual post pages");
127    }
128
129    @Override
130    public LinkType getURLType() throws AmetysRepositoryException
131    {
132        throw new UnsupportedOperationException("getURLType not supported on virtual post pages");
133    }
134    
135    @Override
136    protected Zone getDefaultZone()
137    {
138        return new PostZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint);
139    }
140    
141    @Override
142    public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException
143    {
144        return new EmptyIterable<>();
145    }
146    
147    @Override
148    public Page getChildPageAt(int index) throws UnknownAmetysObjectException, AmetysRepositoryException
149    {
150        throw new UnknownAmetysObjectException("There's no child page at index " + index + " for page " + this.getId());
151    }
152
153    @Override
154    public String getPathInSitemap() throws AmetysRepositoryException
155    {
156        String rootPath = _root.getPathInSitemap();
157        
158        StringBuilder buff = new StringBuilder(rootPath);
159        if (!rootPath.isEmpty())
160        {
161            buff.append('/');
162        }
163        buff.append(_path).append('/').append(_post.getName());
164        
165        return buff.toString();
166    }
167
168    @Override
169    public Site getSite() throws AmetysRepositoryException
170    {
171        return _root.getSite();
172    }
173
174    @Override
175    public String getSiteName() throws AmetysRepositoryException
176    {
177        return _root.getSiteName();
178    }
179
180    @Override
181    public Sitemap getSitemap() throws AmetysRepositoryException
182    {
183        return _root.getSitemap();
184    }
185
186    @Override
187    public String getSitemapName() throws AmetysRepositoryException
188    {
189        return _root.getSitemapName();
190    }
191
192    @Override
193    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
194    {
195        throw new UnknownAmetysObjectException("Unknown child page '" + path + "' for page " + getId());
196    }
197    
198    @SuppressWarnings("unchecked")
199    @Override
200    public AmetysObjectIterable<? extends Page> getChildren() throws AmetysRepositoryException
201    {
202        return new EmptyIterable<>();
203    }
204    
205    @Override
206    public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePages) throws AmetysRepositoryException
207    {
208        return getChildrenPages();
209    }
210
211    @Override
212    public boolean hasChild(String name) throws AmetysRepositoryException
213    {
214        return false;
215    }
216    
217    @Override
218    public String getId() throws AmetysRepositoryException
219    {
220        return "post://" + _path + "?rootId=" + _root.getId() + "&postId=" + _post.getId();
221    }
222
223    @Override
224    public String getName() throws AmetysRepositoryException
225    {
226        return _post.getName();
227    }
228
229    @SuppressWarnings("unchecked")
230    @Override
231    public Page getParent() throws AmetysRepositoryException
232    {
233        return _root.getChild(_path);
234    }
235
236    @Override
237    public String getParentPath() throws AmetysRepositoryException
238    {
239        StringBuilder path = new StringBuilder(_root.getPath());
240        if (path.length() > 0)
241        {
242            path.append('/');
243        }
244        
245        path.append(_path);
246        
247        return path.toString();
248    }
249
250    @Override
251    public String getPath() throws AmetysRepositoryException
252    {
253        return getParentPath() + "/" + _post.getName();
254    }
255
256    public ModelLessDataHolder getDataHolder()
257    {
258        RepositoryData repositoryData = new MemoryRepositoryData(getName());
259        return new DefaultModelLessDataHolder(_pageDataTypeExtensionPoint, repositoryData);
260    }
261
262    @Override
263    public Set<String> getTags() throws AmetysRepositoryException
264    {
265        return Collections.emptySet();
266    }
267    
268    @Override
269    public String getTemplate() throws AmetysRepositoryException
270    {
271        Skin skin = _skinsManager.getSkin(getSite().getSkinId());
272        
273        if (skin.getTemplate(BLOG_POST_TEMPLATE) != null)
274        {
275            return BLOG_POST_TEMPLATE;
276        }
277        
278        return super.getTemplate(); 
279    }
280
281    @Override
282    public boolean isVisible() throws AmetysRepositoryException
283    {
284        return true;
285    }
286}