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.List;
019import java.util.Optional;
020import java.util.stream.Collectors;
021
022import org.ametys.odf.program.Program;
023import org.ametys.plugins.repository.AmetysObject;
024import org.ametys.plugins.repository.AmetysObjectIterable;
025import org.ametys.plugins.repository.AmetysRepositoryException;
026import org.ametys.plugins.repository.CollectionIterable;
027import org.ametys.plugins.repository.UnknownAmetysObjectException;
028import org.ametys.plugins.repository.data.holder.ModelLessDataHolder;
029import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder;
030import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
031import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData;
032import org.ametys.plugins.repository.jcr.NameHelper;
033import org.ametys.web.repository.page.Page;
034import org.ametys.web.repository.page.virtual.VirtualPageConfiguration;
035
036/**
037 * Page representing a second-level page.
038 */
039public class SecondLevelPage extends AbstractOdfPage<SecondLevelPageFactory>
040{
041    private String _name;
042    private String _title;
043    private String _level1;
044    private FirstLevelPage _level1Page;
045    
046    /**
047     * Constructor.
048     * @param factory the factory
049     * @param root the odf root page.
050     * @param level1Key the parent first level code (name)
051     * @param name the page's name.
052     * @param title the page's title.
053     * @param firstLevelPage The parent first level page.
054     * @param configuration The second level virtual page's configuration
055     */
056    public SecondLevelPage(Page root, VirtualPageConfiguration configuration, SecondLevelPageFactory factory, String level1Key, String name, String title, FirstLevelPage firstLevelPage)
057    {
058        super(root, configuration, factory.getScheme(), factory);
059        
060        _name = name;
061        _title = title;
062        _level1 = level1Key;
063        _level1Page = firstLevelPage;
064    }
065    
066    @Override
067    public int getDepth() throws AmetysRepositoryException
068    {
069        return _root.getDepth() + 2;
070    }
071
072    @Override
073    public String getTitle() throws AmetysRepositoryException
074    {
075        return _title;
076    }
077    
078    @Override
079    public String getLongTitle() throws AmetysRepositoryException
080    {
081        return getParent().getTitle() + " - "  + _title;
082    }
083
084    @Override
085    public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException
086    {
087        List<ProgramPage> pages = _getChildrenFromCache()
088            .orElseGet(() -> _factory.getODFPageHandler().getProgramsWithRestrictions(_root, _level1, _name, null, null))
089            .stream()
090            .map(this::_createProgramPage)
091            .collect(Collectors.toList());
092        
093        return new CollectionIterable<>(pages);
094    }
095    
096    private Optional<AmetysObjectIterable<Program>> _getChildrenFromCache()
097    {
098        return Optional.ofNullable(_factory.getODFPageCache().getProgramCache(_root, false))
099            .map(firstLevelCache -> firstLevelCache.get(_level1))
100            .map(secondLevelCache -> secondLevelCache.get(_name))
101            .map(CollectionIterable<Program>::new);
102    }
103    
104    private ProgramPage _createProgramPage(Program program)
105    {
106        return _factory.getProgramPageFactory().createProgramPage(_root, program, null, null, this);
107    }
108    
109    @Override
110    public String getPathInSitemap() throws AmetysRepositoryException
111    {
112        return _root.getPathInSitemap() + "/" + getParent().getName() + "/" + getName();
113    }
114
115    @SuppressWarnings("unchecked")
116    @Override
117    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
118    {
119        return (A) _factory.getODFPageCache().getChildProgramPage(_root, this, _level1, _name, path);
120    }
121
122    @Override
123    public boolean hasChild(String name) throws AmetysRepositoryException
124    {
125        return _factory.getODFPageCache().getProgramFromPageName(_root, _level1, _name, name).isPresent();
126    }
127    
128    @Override
129    public String getId() throws AmetysRepositoryException
130    {
131        // E.g: odfLevel2://XA/ALL?rootId=...
132        return "odfLevel2://" + _factory.getODFPageHandler().encodeLevelValue(_level1) + "/" + _factory.getODFPageHandler().encodeLevelValue(_name) + "?rootId=" + _root.getId();
133    }
134
135    @Override
136    public String getName() throws AmetysRepositoryException
137    {
138        // E.g: arts-lettres-langues-ALL
139        return NameHelper.filterName(_title) + "-" + _factory.getODFPageHandler().encodeLevelValue(_name);
140    }
141    
142    @SuppressWarnings("unchecked")
143    @Override
144    public Page getParent() throws AmetysRepositoryException
145    {
146        if (_level1Page == null)
147        {
148            _level1Page = _factory.getODFPageHandler().findFirstLevelPage(_root, _level1);
149        }
150        
151        return _level1Page; 
152    }
153
154    @Override
155    public String getParentPath() throws AmetysRepositoryException
156    {
157        return _root.getPath() + "/" + getParent().getName();
158    }
159
160    public ModelLessDataHolder getDataHolder()
161    {
162        RepositoryData repositoryData = new MemoryRepositoryData(getName());
163        return new DefaultModelLessDataHolder(_factory.getPageDataTypeEP(), repositoryData);
164    }
165}