001/*
002 *  Copyright 2023 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.web.repository.page.virtual;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Set;
021
022import org.apache.commons.lang3.StringUtils;
023
024import org.ametys.cms.repository.Content;
025import org.ametys.plugins.explorer.resources.ResourceCollection;
026import org.ametys.plugins.repository.AbstractAmetysObject;
027import org.ametys.plugins.repository.AmetysObjectIterable;
028import org.ametys.plugins.repository.AmetysRepositoryException;
029import org.ametys.plugins.repository.CollectionIterable;
030import org.ametys.plugins.repository.data.holder.DataHolder;
031import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
032import org.ametys.plugins.repository.data.holder.impl.DefaultDataHolder;
033import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
034import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
035import org.ametys.web.repository.page.Page;
036import org.ametys.web.repository.page.UnknownZoneException;
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;
041
042/**
043 * An abstract configurable virtual page.
044 * @param <T> The type of page factory to use
045 */
046public abstract class AbstractConfigurableVirtualPage<T extends AbstractConfigurableVirtualPageFactory> extends AbstractAmetysObject implements Page 
047{
048    /** The root page */
049    protected Page _root;
050    /** The AbstractVirtualPageConfiguration */
051    protected VirtualPageConfiguration _configuration;
052    /** The ModelItemTypeExtensionPoint for zones */
053    /** The page's scheme */
054    protected String _scheme;
055    /** The factory */
056    protected T _factory;
057    
058    /**
059     * The constructor for an abstract configurable virtual page
060     * @param root The root page
061     * @param configuration The abstract virtual page configuration
062     * @param scheme The page's scheme
063     * @param factory The page's factory
064     */
065    public AbstractConfigurableVirtualPage(Page root, VirtualPageConfiguration configuration, String scheme, T factory)
066    {
067        _root = root;
068        _configuration = configuration;
069        _factory = factory;
070        _scheme = scheme;
071    }
072    
073    @Override
074    public ResourceCollection getRootAttachments() throws AmetysRepositoryException
075    {
076        // Attachments not available on virtual pages
077        return null;
078    }
079    /**
080     * Get a zone configuration by its name
081     * @param name The zone name
082     * @return the VirtualPageZoneConfiguration
083     */
084    public VirtualZoneConfiguration getZoneConfiguration(String name) 
085    {
086        return _configuration.getZoneConfiguration(name, _root);
087    }
088    
089    @Override
090    public String getTemplate() throws AmetysRepositoryException 
091    {
092        Skin skin = _factory.getSkinsManager().getSkin(getSite().getSkinId());
093        
094        String template = _configuration.getTemplate(_root);
095        
096        if (StringUtils.isNotEmpty(template) && skin.getTemplate(template) != null)
097        {
098            return template;
099        }
100        else
101        {
102            return "page"; 
103        }
104    }
105
106    @Override
107    public boolean hasZone(String name) throws AmetysRepositoryException 
108    {
109        return _configuration.hasZoneConfiguration(name, _root);
110    }
111
112    @Override
113    public PageType getType() throws AmetysRepositoryException 
114    {
115        return PageType.CONTAINER;
116    }
117
118    @Override
119    public String getURL() throws AmetysRepositoryException 
120    {
121        throw new UnsupportedOperationException("getURL not supported on virtual pages");
122    }
123
124    @Override
125    public LinkType getURLType() throws AmetysRepositoryException 
126    {
127        throw new UnsupportedOperationException("getURLType not supported on virtual pages");
128    }
129
130    @Override
131    public Set<String> getReferers() throws AmetysRepositoryException 
132    {
133        throw new UnsupportedOperationException("getReferers not supported on virtual pages");
134    }
135
136    @Override
137    public Site getSite() throws AmetysRepositoryException
138    {
139        return _root.getSite();
140    }
141    
142    @Override
143    public String getSiteName() throws AmetysRepositoryException
144    {
145        return _root.getSiteName();
146    }
147
148    @Override
149    public Sitemap getSitemap() throws AmetysRepositoryException
150    {
151        return _root.getSitemap();
152    }
153
154    @Override
155    public String getSitemapName() throws AmetysRepositoryException
156    {
157        return _root.getSitemapName();
158    }
159    
160    @Override
161    public String getPath() throws AmetysRepositoryException
162    {
163        return getParentPath() + "/" + getName();
164    }
165    
166    @Override
167    public Set<String> getTags() throws AmetysRepositoryException
168    {
169        return Set.of();
170    }
171    
172    @Override
173    public boolean isVisible() throws AmetysRepositoryException 
174    {
175        return true;
176    }
177
178    /**
179     * Get the page's content
180     * @param <C> The content's type
181     * @return The content
182     */
183    public <C extends Content> C getContent() 
184    {
185        throw new UnsupportedOperationException("This virtual page does not have a content and the overriding configuration requires one.");
186    }
187    
188    @Override
189    public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException
190    {
191        return _factory.getZoneFactory().createZone(this, name);
192    }
193
194    @Override
195    public AmetysObjectIterable< ? extends Zone> getZones() throws AmetysRepositoryException
196    {
197        List<Zone> zones = new ArrayList<>();
198        
199        for (VirtualZoneConfiguration zoneConfiguration : _configuration.getZonesConfigurations(_root)) 
200        {
201            zones.add(getZone(zoneConfiguration.getId()));
202        }
203        
204        return new CollectionIterable<>(zones);
205    }
206    
207    @Override
208    public ModelAwareDataHolder getTemplateParametersHolder() throws AmetysRepositoryException
209    {
210        // Template's parameters not available on virtual pages
211        return null;
212    }
213    
214    /**
215     * Get the page's scheme
216     * @return The scheme of the page
217     */
218    public String getScheme() 
219    {
220        return _scheme;
221    }
222    
223    public boolean isIndexable()
224    {
225        return _root.isIndexable();
226    }
227    
228    @Override
229    protected DataHolder getDataHolder()
230    {
231        RepositoryData repositoryData = new MemoryRepositoryData(getName());
232        return new DefaultDataHolder(_factory.getPageDataTypeExtensionPoint(), repositoryData);
233    }
234}