001/*
002 *  Copyright 2010 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.odfweb.repository;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Optional;
021import java.util.stream.Collectors;
022
023import org.ametys.odf.program.Program;
024import org.ametys.plugins.repository.AmetysObject;
025import org.ametys.plugins.repository.AmetysObjectIterable;
026import org.ametys.plugins.repository.AmetysRepositoryException;
027import org.ametys.plugins.repository.CollectionIterable;
028import org.ametys.plugins.repository.UnknownAmetysObjectException;
029import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
030import org.ametys.plugins.repository.data.holder.ModelLessDataHolder;
031import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder;
032import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
033import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
034import org.ametys.plugins.repository.jcr.NameHelper;
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;
040
041/**
042 * Page representing a second-level page.
043 */
044public class SecondLevelPage extends AbstractLevelPage
045{
046    private Page _root;
047    private String _name;
048    private String _title;
049    private String _level1;
050    private FirstLevelPage _level1Page;
051    
052    private SecondLevelPageFactory _factory;
053    
054    /**
055     * Constructor.
056     * @param factory the factory
057     * @param root the odf root page.
058     * @param level1Key the parent first level code (name)
059     * @param name the page's name.
060     * @param title the page's title.
061     */
062    public SecondLevelPage(SecondLevelPageFactory factory, Page root, String level1Key, String name, String title)
063    {
064        this(factory, root, level1Key, name, title, null);
065    }
066    
067    /**
068     * Constructor.
069     * @param factory the factory
070     * @param root the odf root page.
071     * @param level1Key the parent first level code (name)
072     * @param name the page's name.
073     * @param title the page's title.
074     * @param firstLevelPage The parent first level page.
075     */
076    public SecondLevelPage(SecondLevelPageFactory factory, Page root, String level1Key, String name, String title, FirstLevelPage firstLevelPage)
077    {
078        _factory = factory;
079        _root = root;
080        _name = name;
081        _title = title;
082        _level1 = level1Key;
083        _level1Page = firstLevelPage;
084    }
085    
086    @Override
087    public int getDepth() throws AmetysRepositoryException
088    {
089        return _root.getDepth() + 2;
090    }
091
092    @Override
093    public String getTitle() throws AmetysRepositoryException
094    {
095        return _title;
096    }
097    
098    @Override
099    public String getLongTitle() throws AmetysRepositoryException
100    {
101        return getParent().getTitle() + " - "  + _title;
102    }
103
104    @Override
105    public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException
106    {
107        if (!"default".equals(name))
108        {
109            throw new IllegalArgumentException("Only the zone named 'default' is actually supported on virtual program pages.");
110        }
111        
112        return new SecondLevelZone(this, _factory.getZoneDataTypeEP(), _factory.getServiceEP(), _factory.getZoneItemDataTypeEP());
113    }
114
115    @Override
116    public AmetysObjectIterable<? extends Zone> getZones() throws AmetysRepositoryException
117    {
118        ArrayList<Zone> zones = new ArrayList<>();
119        zones.add(new SecondLevelZone(this, _factory.getZoneDataTypeEP(), _factory.getServiceEP(), _factory.getZoneItemDataTypeEP()));
120        return new CollectionIterable<>(zones);
121    }
122
123    @Override
124    public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException
125    {
126        List<ProgramPage> pages = _getChildrenFromCache()
127            .orElseGet(() -> _factory.getODFPageHandler().getProgramsWithRestrictions(_root, _level1, _name, null, null))
128            .stream()
129            .map(this::_toProgramPage)
130            .collect(Collectors.toList());
131        
132        return new CollectionIterable<>(pages);
133    }
134    
135    private Optional<AmetysObjectIterable<Program>> _getChildrenFromCache()
136    {
137        return Optional.ofNullable(_factory.getODFPageCache().getProgramCache(_root, false))
138            .map(firstLevelCache -> firstLevelCache.get(_level1))
139            .map(secondLevelCache -> secondLevelCache.get(_name))
140            .map(CollectionIterable<Program>::new);
141    }
142    
143    private ProgramPage _toProgramPage(Program program)
144    {
145        return new ProgramPage(_factory.getProgramPageFactory(), _root, program, null, null, this);
146    }
147    
148    @Override
149    public String getPathInSitemap() throws AmetysRepositoryException
150    {
151        return _root.getPathInSitemap() + "/" + getParent().getName() + "/" + getName();
152    }
153
154    @Override
155    public Site getSite() throws AmetysRepositoryException
156    {
157        return _root.getSite();
158    }
159
160    @Override
161    public String getSiteName() throws AmetysRepositoryException
162    {
163        return _root.getSiteName();
164    }
165
166    @Override
167    public Sitemap getSitemap() throws AmetysRepositoryException
168    {
169        return _root.getSitemap();
170    }
171
172    @Override
173    public String getSitemapName() throws AmetysRepositoryException
174    {
175        return _root.getSitemapName();
176    }
177
178    @SuppressWarnings("unchecked")
179    @Override
180    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
181    {
182        return (A) _factory.getODFPageCache().getChildProgramPage(_root, this, _level1, _name, path);
183    }
184
185    @Override
186    public boolean hasChild(String name) throws AmetysRepositoryException
187    {
188        return _factory.getODFPageCache().getProgramFromPageName(_root, _level1, _name, name).isPresent();
189    }
190    
191    @Override
192    public String getId() throws AmetysRepositoryException
193    {
194        // E.g: odfLevel2://XA/ALL?rootId=...
195        return "odfLevel2://" + _factory.getODFPageHandler().encodeLevelValue(_level1) + "/" + _factory.getODFPageHandler().encodeLevelValue(_name) + "?rootId=" + _root.getId();
196    }
197
198    @Override
199    public String getName() throws AmetysRepositoryException
200    {
201        // E.g: arts-lettres-langues-ALL
202        return NameHelper.filterName(_title) + "-" + _factory.getODFPageHandler().encodeLevelValue(_name);
203    }
204    
205    @SuppressWarnings("unchecked")
206    @Override
207    public Page getParent() throws AmetysRepositoryException
208    {
209        if (_level1Page == null)
210        {
211            _level1Page = _factory.getODFPageHandler().findFirstLevelPage(_root, _level1);
212        }
213        
214        return _level1Page; 
215    }
216
217    @Override
218    public String getParentPath() throws AmetysRepositoryException
219    {
220        return _root.getPath() + "/" + getParent().getName();
221    }
222
223    public ModelLessDataHolder getDataHolder()
224    {
225        RepositoryData repositoryData = new MemoryRepositoryData(getName());
226        return new DefaultModelLessDataHolder(_factory.getPageDataTypeEP(), repositoryData);
227    }
228    
229    public ModelAwareDataHolder getTemplateParametersHolder() throws AmetysRepositoryException
230    {
231        return null;
232    }
233}